# Question
Title: How to write & read from SPIFFS file as object data on ESP8266
I am trying write four digit number to SPIFFS file, and read that four digit from SPIFFS file and display on seven segment.

The code, I am writing as below, I got "0" on each segment, but if manually make number = 4567; then seven segment show proper number on every segment.

Please help me to learn more about how to read & write and convert to object data.

Here is my code;

```
#include <FS.h>

const char* filename = "/InputInt.txt";
int digit_1 = 0;
int digit_2 = 0;
int digit_3 = 0;
int digit_4 = 0;

int Anode_1 = 16;
int Anode_2 = 14;
int Anode_3 = 5;
int Anode_4 = 4;
int count = 0;
int digits[4] ;
int AnodePins[4] = {4, 5, 14, 16};

int clockPin = 12;
int latchPin = 13;
int dataPin = 15;

int number = 0; //declear the variables

byte numbers[10] {B00000011, B10011111, B00100101, B00001101, B10011001, B01001001, B01000001, B00011111, B00000001, B00001001};

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

  bool success = SPIFFS.begin();

  if (!success) {
    Serial.println("Error mounting the file system");
    return;
  }
  SPIFFS.format();
  File fw = SPIFFS.open(filename, "w");

  if (!fw) {
    Serial.println("Error opening file for writing");
    return;
  }
  char Written = fw.print("1234");

  if (Written == 0) {
    Serial.println("File write failed");
    return;
  }
  fw.close();

  pinMode(Anode_1, OUTPUT);
  pinMode(Anode_2, OUTPUT);
  pinMode(Anode_3, OUTPUT);
  pinMode(Anode_4, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

} //End of setup

void loop() {
  int i;
  File fr = SPIFFS.open(filename, "r");

  if (!fr) {
    Serial.println("Failed to open file for reading");
    return;
  }

  for (i = 0; i < 4; i++) {
    byte number = (Serial.write(fr.read()));
  }
  fr.close();
  break_number(number);
  display_number();
  delay(3000);
} // End of loop

// seperate the input number into 4 single digits
void break_number(int num) {
  Serial.println("");
  digit_1 = num / 1000;
  digits[0] = digit_1;
  Serial.print(" Digit_1: ");
  Serial.println(digit_1);
  int dig_1_remove = num - (digit_1 * 1000);

  digit_2 = dig_1_remove / 100;
  digits[1] = digit_2;
  Serial.print(" Digit_2: ");
  Serial.println(digit_2);
  int dig_2_remove = dig_1_remove - (digit_2 * 100);

  digit_3 = dig_2_remove / 10;
  digits[2] = digit_3;
  Serial.print(" Digit_3: ");
  Serial.println(digit_3);
  digit_4 = dig_2_remove - (digit_3 * 10);

  digits[3] = digit_4;
  Serial.print(" Digit_4: ");
  Serial.println(digit_4);
}

void display_number() {                                             //scanning
  digitalWrite(AnodePins[count], HIGH);                            //turn on the relevent digit
  digitalWrite(latchPin, LOW);                                      //put the shift register to read
  shiftOut(dataPin, clockPin, LSBFIRST, numbers[digits[count]]);    //send the data
  digitalWrite(latchPin, HIGH);                                     //put the shift register to write mode
  delay(0);
  digitalWrite(AnodePins[count], LOW);                            //turn on the relevent digit
  count++;                                                          //count up the digit
  if (count == 4) {                                                 // keep the count between 0-3
    count = 0;
  }
}

```

Here is the result;

```
1234
 Digit_1: 0
 Digit_2: 0
 Digit_3: 0
 Digit_4: 0
1234
 Digit_1: 0
 Digit_2: 0
 Digit_3: 0
 Digit_4: 0
1234
 Digit_1: 0
 Digit_2: 0
 Digit_3: 0
 Digit_4: 0

```

Thanks,

# Answer
> 1 votes
I directly see 3 problems with your code:

1. `Serial.write()` will not return the written data, but the number of send bytes. This means that in your for loop you are only assigning the written number of bytes to the variable, not the data. But I guess you want to display the actual data, which was read from the file. You should assign the return value of `fr.read()` to a variable. Then you can send it via `Serial.write()` and still use that variable for other things later (like displaying).
2. You need to look into variable scope. You have a global variable `number`. But in the for loop you are defining a local variable with the same name via

```
 byte number = ...

```

This variable is only valid in that specific for loop iteration. When the iteration ends, the variable is thrown away and redeclared in the next iteration. It will not be there anymore, when you leave the for loop. So currently you are saving your data in a variable local to the for loop. It does NOT touch the global variable. Thus the other functions only see the value zero, with which the global variable `number` was initialized. You can remove the type `byte` before the variable in the for loop. That makes it an assignment instead of a definition. Thus then you really write the data into the global variable.
3. Data encoding: Clearly you have your number in the file as ASCII encoded text. But you seem to handle it as binary data. That cannot work. For example: When you read the first character of `1234` (which is written in the file), then you get `'1'` (the character, not the number). When looking at an ASCII table you can see, that this character corresponds to a decimal number of 49 (or `0x31` in hex). You can convert an ASCII encoded digit to a real number by subtracting the value of the character `'0'`:

```
 int number = fr.read() - '0';

```

or

```
 int number = fr.read() - 48;

```

(both are equivalent).

Also you are currently just saving the read character into a single variable. That means, that after the for loop only the last character is left. Since this is a composite number, you should do something to compose it. Like this:

```
 number = 0;
 int factor = 1000;
 for(int i = 0; i<4; i++){
     number += (fr.read() - '0') * factor;
     factor /= 10;
 }

```

Note: This is untested, it is not the best way, but the easiest at this point, and it only works for numbers between 1000 and 9999 (4 digit numbers). You can implement this more versatile.

First we are resetting the `number` variable, so that old values are not getting in our way. We are using a variable holding the current factor (starting with 1000, since that is the figure in which the first digit lies). Then we go through the 4 characters, reading them. We subtract the character `'0'` (as described above) and then multiply by the factor. That resulting number is added to the variable `number`. Then we divide the factor by 10 (getting from 1000 to 100, then to 10 and finally to 1). At the end we can use `number` like any other integer variable.

---

Alternative implementation of reading the number, which is suitable for different numbers of digits:

```
number = 0;
// Prepare character buffer to read the number in
char buffer[10] = ""; // space for maximum 9 digits
int pos = 0; // position variable in the buffer
while(fr.available() && pos < 9){ // loop while there is data left to read in the file or we have no pace left in buffer (leaving one character for the terminating null character
    char c = fr.read(); // read character into variable
    if(isDigit(c)){
        buffer[pos] = c; // save digit in buffer
        pos++; // increment position for the next character
    } else {
       break; // break out of loop, if read character is not a digit (we don't want to read further when a non-digit character comes up)
    }
}
buffer[pos] = 0; // terminate buffer with null character
number = atoi(buffer); // use standard function to convert to integer number

```

Note:

* This code is not tested, though it compiles without errors
* You see, that it is not smaller, than the other one, but can handle different number of digits.
* You can still use the first version with smaller numbers, if you always pad them with zeros. So instead `991` you would write `0991` to the file. That will make the first version work.

---
Tags: esp8266, esp32, 7-segment, spiffs
---


title: Stepper Motors Strange Behaviour

text:
# Question
Title: Stepper Motors Strange Behaviour
I am working in a project in which I need to control at the same time three NEMA17 stepper motors. In order to do so, I am using three DRV8825 drivers working at 12V connected to an Arduino MEGA.

This Arduino is generating the pulses in velocity ramps so that we have an accelerated movement to reach the goal.

The schematic I am using for connecting the drivers is the one that the manufacturer recommends:

With a digital analyzer, I can see that my velocity ramp is being generated properly:

In this picture below you can see how steps (ST) are generated once the direction (DR) is set for each of the motors. The time waiting after the direction change is bigger than the necessary established by the manufacturer and also does the duration of the step pulses.

Following this, the motors are supposed to make an accelerated movement until reaching a certain position and then, decelerate and stop.

Although, I am facing the problem that, in some cases, one of the motors (not always the same one) makes a few steps in the opposite direction of the movement and, after that, it executes the expected movement. This leads to, even of making the three motors perform the same movement, one of them finishes differently.

I tried to change the drivers but the same happens. Also, as I said before, I have checked that the pulses are correctly generated.

I would like to know if anyone has faced a similar problem or knows any reason that could lead to this strange behavior.

Thanks.

# Answer
> 1 votes
So, apparently the motors I am using have a optimal work range that doesn't start at 0 but 200PPS. Though, even generating properly the velocity ramps, when using a low acceleration, my motors would be running for some steps outside this optimal range, causing strange movements at the beginning of the movement.

In order to solve it, these non-optimal low velocities are avoided while accelerating so that motors enter directly to the optimal work area.

---
Tags: arduino-mega
---


title: Make an LED Turn

text:
# Question
Title: Make an LED Turn
```
//Make an LED Turn ON after pressing a push button switch for five times. Add a reset switch to turn OFF the LED whenever the reset switch is pressed

**void setup()

{

  pinMode(11, OUTPUT);

  pinMode (4,INPUT);

}

void loop()

{

  int y= digitalRead(6); // push button 2

  static int counter {} ;

  int x= digitalRead(4);// push button 1

  if (x==1&& y==0 )

    counter++;

else if (counter == 5) // If counter is pressed 5 times

{

  digitalWrite(11, HIGH); // Turn on the LED

}

if (counter >= 5) // If counter is greater than 5 led will still on

{

  digitalWrite (11, 1);

}

  else if

   (y==1&& x==0 ) // if pressed push button 2  led of
  {

    digitalWrite(11,0);

}

  counter = 0; // Make counter variable = 0

}

```

# Answer
You can try implementing a counter system in your Arduino program.

For example, if this is your loop() function:

```
void loop(){
int buttonState = digitalRead(1); // Give the variable buttonState the value of pin 1, or whatever your button is connected to
static int counter{}; // Have a counter variable. Static means it doesn't reset to 0 after loop() restarts

if (buttonState == HIGH) // If the button is pressed
{
  ++counter; // Increase the value of counter by 1
}

else if (counter == 5) // If counter is pressed 5 times
{
  digitalWrite(11, HIGH); // Turn on the LED
}
// RESET:
if (counter > 5) // If counter is greater than 5 (you clicked the button again)
{
  digitalWrite (11, LOW);
  counter = 0; // Make counter variable = 0
}
}

```

*Edit* In the comments, Python Schlage made very good suggestions: to change `buttonState` to a boolean and change `int` to `byte` to save space on board the Arduino

Try following this tutorial: https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button and modifying it to work with the counter. Hope this helps! Please let us know if you need help with the setup() function or if anything is unclear.
> 4 votes

---
Tags: programming, code-review
---


# Question
Title: When accessing a variable from an ISR, is a volatile pointer enough?
Let's say I want to modify a global variable from inside an interrupt service routine. I must ensure that any variables I modify are volatile. Does it work to use a volatile pointer to data I want to modify if the data itself is not volatile?

In my case the data is a struct, but does the answer change if the data is a class, array, or just a variable?

```
#include <Arduino.h>

#define PIN_INTERRUPT  2

typedef struct MyStruct
{
    int a_field;
} MyStruct;

MyStruct struct_data;
int array_data[32];

volatile bool _flag_ISR = false;
volatile MyStruct *_struct_ISR = &struct_data;
void myISR()
{
    // just some example stuff
    int read = digitalRead(PIN_INTERRUPT);
    _struct_ISR->a_field = read;
    _arr_data_ISR[4] = read;

    _flag_ISR = true;
}

void setup()
{
    attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPT), myISR, CHANGE);
}

void loop()
{
    if (_flag_ISR)
    {
        // do processing here...
        _flag_ISR = false;
    }
}

```

# Answer
> 1 votes
First, beware that what you have written is not a volatile pointer, it's a pointer to volatile data. If you always access the object through this pointer, you should be fine. If you use the pointer in the ISR, but access the data directly in the main code (bypassing the `volatile` qualifier), then the program could fail.

Consider the following:

```
void loop()
{
    if (_flag_ISR) {
        _flag_ISR = false;
        Serial.println(struct_data.a_field);
    }
}

```

Once the compiler inlines the call to `loop()` from `main()`, the main program looks like

```
int main()
{
    init();  // Arduino core initialization
    setup();
    for (;;) {  // inlined loop()
        if (_flag_ISR) {
            _flag_ISR = false;
            Serial.println(struct_data.a_field);
        }
    }
}

```

And now, since `struct_data` is not volatile, the compiler can legitimately optimize the code by avoiding repeatedly accessing the same RAM location:

```
int main()
{
    init();  // Arduino core initialization
    setup();
    register int data_copy = struct_data.a_field;
    for (;;) {  // inlined loop()
        if (_flag_ISR) {
            _flag_ISR = false;
            Serial.println(data_copy);
        }
    }
}

```

And now the program prints only zeros.

---
Tags: interrupt
---


title: Arduino nano KiCad symbols

text:
# Question
Title: Arduino nano KiCad symbols
Can anyone explain me the difference between the symbols for Arduino nano in KiCad? Is there any important difference at all? All of them seem to have all basic pins.

# Answer
> 3 votes
In short, there aren't any substantial differences. But it makes sense to use the one that actually matches what you have.

My KICAD symbols are out of date, so I downloaded and unpacked the current archive for MCU Module symbols. These things are defined in text files, so doing this allows you to employ the usual diff tools to them, if you break the parts of interest out into separate files, which is what I did to produce the below images.

## Index Entries

Besides the name, they're different in what datasheet they refer to:

## Definitions

In the below, on the left you'll see in dark blue background that both the Nano v2.x and v3.x are actually defined in the same file. So, they are in fact sharing a definition; so, no differences there at all. The original Nano boards varied in that some had ATMega168P and some had ATMega328P. These are practically but not quite the same chip. The significant difference is sizes of the various memories. And they had different bootloaders. Nothing that would make their symbols or footprints significantly different.

On the right is the Nano-Every, which is a fairly different beast from the older Nanos in that it's an ATMega4809, one of the new-series AVR parts, and different significant ways greater than just memory sizes. But, it was designed to have the same layout as the prior Nano boards. They even went so far as to make classes and objects to try to "emulate" the more traditional style GPIO ports of the Nano for Nano Every users.

As you can see there's really no differences besides the names of the pins and a few changes in drawn locations between the v2/v3 symbol on left and the "Every" symbol on the right. Some of the pin names are different, but it's the pin numbers that matter when mating it to a footprint in Kicad, and those are the same between the two.

For whatever reason pin number 29 changed from `W` (in 2/3) to `N` (in "Every"), which according to their documentation is a change from *power input* to *not connected*. I suppose this might make a difference between whether or not you need to add a `PWR_FLAG` symbol somewhere in your design to satisfy electrical rules check (ERC). In the "Every", for whatever reason when they (slightly) rearranged the pins locations in the symbol, they stuck pin number 29 right on top of pin 4. So, if you're having a hard time seeing pin 29, that (and the light gray text) are why.

---
Tags: arduino-uno, arduino-nano, pcb-design
---


# Question
Title: Problems with compiling more then one sketch in the Arduino IDE
I found this ESP8266-MQTT program on Github.

How can I compile this thing with the Arduino IDE?

I only can open one sketch at a time. If I try to compile this then parts of the program are missing for AVRDUDE - but they are in the same folder.

Please can you help me?

# Answer
That sketch is written for the ESP8266, not the ESP32. The two are very different chips, and the libraries used are very different.

You will have to learn how the sketch works, and how the ESP32 libraries work, and port the sketch to the ESP32 once you have learned how.
> 2 votes

---
Tags: esp8266, avrdude, compiler
---


# Question
Title: HC-05 drops connection, then DC Motors won't stop moving 'forward'
This is my first post. I seek you guys' help with my problem. Basically, my project is a Mobile-App Bluetooth Controlled WheelChair. Everything's done except a minor problem comes out during testing. After connecting everything, the wheelchair moves accordingly to the code that I wrote. However, after a few sec/min, the HC-05 drops connection, and the wheelchair drives its own by moving forward. I hope you can understand what I am saying.

When I set the speed = 100. I think I did not face the issue as above (confirmed).

Hardware:

PowerBank

Arduino Uno

HC 05

MDD20A Motor Driver

X2 24V DC Motor

X2 12V Battery

```
//including the libraries
#include <SoftwareSerial.h> // TX RX software library for bluetooth

//Initializing pins for bluetooth Module
int bluetoothTx = 0; // bluetooth tx to 0 pin
int bluetoothRx = 1; // bluetooth rx to 1 pin
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

//Motor 1
int Motor1_Pin = 2;
int Enable1 = 3;

//Motor 2
int Motor2_Pin = 4;
int Enable2 = 5;

char command ; //variable to store the data
int velocity = 0; //Variable to control the speed of motor

void setup()
{
  //Set the baud rate of serial communication and bluetooth module at same rate.
  // Serial Setup
  Serial.begin(9600); // default communication rate of the HC-06 Bluetooth module;
  bluetooth.begin(9600);

  // Motor Setup
  pinMode(Motor1_Pin,OUTPUT);
  pinMode(Enable1,OUTPUT);
  pinMode(Motor2_Pin,OUTPUT);
  pinMode(Enable2,OUTPUT);

  //Setting the enable as HIGH.
  digitalWrite(Enable1, LOW);
  digitalWrite(Enable2, LOW);
}

void loop(){
  if(bluetooth.available() > 0){  //Checking if there is some data available or not
    command = bluetooth.read();   //Storing the data in the 'command' variable
    Serial.println(command);      //Printing it on the serial monitor

    //Change pin mode only if new command is different from previous.
    switch(command){
    case 'F':  //Moving the Car Forward
      analogWrite(Enable1, 175);
      analogWrite(Enable2, 175);
      digitalWrite(Motor1_Pin, HIGH);
      digitalWrite(Motor2_Pin, HIGH);
      break;
    case 'B':  //Moving the Car Backward
      analogWrite(Enable1, 175);
      analogWrite(Enable2, 175);
      digitalWrite(Motor1_Pin, LOW);
      digitalWrite(Motor2_Pin, LOW);
      break;
    case 'L':  //Moving the Car Left
      analogWrite(Enable1, 175);
      analogWrite(Enable2, 100);
      digitalWrite(Motor1_Pin, HIGH);
      digitalWrite(Motor2_Pin, LOW);
      break;
    case 'R':   //Moving the Car Right
      analogWrite(Enable2, 175);
      analogWrite(Enable1, 100);
      digitalWrite(Motor2_Pin, HIGH);
      digitalWrite(Motor1_Pin, LOW);
      break;
    case 'S':   //Stop
      analogWrite(Enable1, 0);
      analogWrite(Enable2, 0);
      digitalWrite(Motor1_Pin, 0);
      digitalWrite(Motor2_Pin, 0);
      break;
//    case 'I':  //Moving the Car Forward right
//      digitalWrite(Motor2_Pin2, LOW);
//      digitalWrite(Motor2_Pin1, LOW);
//      analogWrite(enable1, 0);
//      analogWrite(enable2, 0);
//      break;
//    case 'J':  //Moving the Car backward right
//      digitalWrite(Motor2_Pin2, LOW);
//      digitalWrite(Motor2_Pin1, LOW);
//      analogWrite(enable1, 0);
//      analogWrite(enable2, 0);
//      break;
//    case 'G':  //Moving the Car Forward left
//      digitalWrite(Motor2_Pin2, LOW);
//      digitalWrite(Motor2_Pin1, LOW);
//      analogWrite(enable1, 0);
//      analogWrite(enable2, 0);
//      break;
//    case 'H':  //Moving the Car backward left
//      digitalWrite(Motor2_Pin2, LOW);
//      digitalWrite(Motor2_Pin1, LOW);
//      analogWrite(enable1, 0);
//      analogWrite(enable2, 0);
//      break;
    break;

    //Controlling the Speed of Car
    default:  //Get velocity
      if(command=='q'){
        velocity = 255;  //Full velocity
        analogWrite(Enable2, velocity);
        analogWrite(Enable1, velocity);
      }
      else{
        //Chars '0' - '9' have an integer equivalence of 48 - 57, accordingly.
        if((command >= 48) && (command <= 57)){
          //Subtracting 48 changes the range from 48-57 to 0-9.
          //Multiplying by 25 changes the range from 0-9 to 0-225.
          velocity = (command - 48)*25;
          analogWrite(Enable2, velocity);
          analogWrite(Enable1, velocity);
        }
      }
      }
    }

  }

```

# Answer
> 1 votes
I assume that you want the chair to stop if the connection is lost. Is the 'state' pin on your HC-05 implemented, and does it distinguish between connected and not-connected (or something else)? If it's the former you should be monitoring that state pin. Otherwise, your Arduino and the mobile app need to agree on an "Are you there?" protocol; a handshake that takes place every 0.5 sec or so (off the wall guess!), and if the chair controller hasn't got a response darn near immediately, it stops. If the mobile misses a response, it should send a 'stop' (a backup which might not be heard by the chair controller), and alert the operator. It wouldn't be a half-bad idea to have a watchdog timer (in hardware) on the chair that stops the motors if the chair controller doesn't reset it on short intervals. The chair controller is software; software sometimes fails. You'd like to detect that in hardware in time to cut the drive to the chair before it hits an obstruction or drives into the street.

---
Tags: arduino-uno, hc-05
---


# Question
Title: ESP32 partition table and writing location
In my ESP32 project I have the following platformio.io file:

```
[env:esp32-poe]
platform = espressif32
board = esp32-poe
framework = arduino
lib_deps =
    openslab-osu/SSLClient@^1.6.7
    knolleary/PubSubClient@^2.8
    bblanchon/ArduinoJson@^6.16.1
monitor_speed = 115200

[env:custom_builtin_table]
board_build.partitions = default.csv

```

the default.csv table is this one:

```
# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x140000,
app1,     app,  ota_1,   0x150000,0x140000,
spiffs,   data, spiffs,  0x290000,0x170000,

```

I noticed that when I upload the code to my ESP32 the output is like this:

```
[...]
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 17104 bytes to 11193...
Writing at 0x00001000... (100 %)
Wrote 17104 bytes (11193 compressed) at 0x00001000 in 0.3 seconds (effective 521.5 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 128...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (128 compressed) at 0x00008000 in 0.0 seconds (effective 5621.7 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 27422.0 kbit/s)...
Hash of data verified.
Compressed 1003456 bytes to 585011...
Writing at 0x00010000... (2 %)
[...]

```

Hence, it writes at:

* 0x1000
* 0x8000
* 0xe000 (otadata)
* 0x10000 (app0)

But I cannot understand what are the first two writings.

# Answer
0x1000 is the "second stage" bootloader. This is the code that is responsible for loading the code according to the layout specified in the partition table.

> In ESP-IDF, the binary image which resides at offset 0x1000 in flash is the second stage bootloader. Second stage bootloader source code is available in components/bootloader directory of ESP-IDF. Note that this arrangement is not the only one possible with the ESP32 chip. It is possible to write a fully featured application which would work when flashed to offset 0x1000, but this is out of scope of this document. Second stage bootloader is used in ESP-IDF to add flexibility to flash layout (using partition tables), and allow for various flows associated with flash encryption, secure boot, and over-the-air updates (OTA) to take place.

0x8000 is the partition table itself.

> Second stage bootloader reads the partition table found at offset 0x8000. See partition tables documentation for more information. The bootloader finds factory and OTA partitions, and decides which one to boot based on data found in OTA info partition.

All this is detailed in the ESP-IDF manual.
> 4 votes

---
Tags: esp32, partition, platformio
---


title: MAX30100 not working

text:
# Question
Title: MAX30100 not working
I am unable to get the MAX30100 sensor to work
It keeps throwing the following error:

```
16:06:32.936 -> Initializing...
16:06:32.936 -> MAX30105 was not found. Please check wiring/power.

```

I am using the Sparkfun library Example sketch "Example5\_HeartRate"

As far as I understand the breakout board for the MAX30100 is a bit buggy - By which I mean the internal pullup resistors are connected to 1.8V for some reason instead of 5V

I have used MAX30100 before and had faced the same issue. However, after scouring the internet for hours I found this helpful article: https://reedpaper.wordpress.com/2018/08/22/pulse-oximeter-max30100-max30102-how-to-fix-wrong-board/

I want to use another MAX30100 sensor and have followed the above article again and have done the said changes to my sensor which resulted in the board being detected at address 0x57 when I run the i2c scanner. However, unlike the previous time, the Example sketch did not run as expected.

I even tried this solution: https://github.com/oxullo/Arduino-MAX30100/issues/51#issuecomment-391193292

But kept receiving the same error message.

The pin connections are: ARDUINO -\> MAX30100/MAX300102
3V3 -\> VIN
SDA (A4)-\> SDA\
SCL (A5)-\> SCL
GND -\> GND

I need help asap. Thank you in advance!

I hope the links mentioned are helpful for someone else.

# Answer
This video might help you, in this video, an Indian guy explained the issue in detail with the help of the max30100 sensor schematic diagram, and solved it in two ways. https://youtu.be/ZqdmA4NAqb0
> 2 votes

# Answer
Check out this link. I guess it will work I had the same MAX30100 module what i did was removed those 4.7k resistors mounted through hole resistors on breadboard and pull-uped them using 5V and it was working fine for me
> 1 votes

# Answer
I had similar trouble with a cheap board (RCWL-0531). Used the same “How to fix wrong board” fix you mentioned (pictured). Which worked ... sort of ... Achieved terrible sensing stability (both HR and O2). I read the comments in the sample code about Uno boards (which I had started out on) having insufficient capacity to handle the full sample data, so migrated to ESP32. Still not great. Gave up and bought a Sparkfun MAX30105, still connected to an ESP32 and OLED display. Immediately a different experience, much higher quality but I don't know why. I have some "still to-do" ideas to investigate the MAX30102\_by\_RF library and also to use a more capable processor (e.g., Due) to see if the signal processing capability can be cranked up. Hope this helps - you're not alone.
> 0 votes

---
Tags: sensors, arduino-nano, i2c
---


title: Hardware interrupt calling two ISRs

text:
# Question
Title: Hardware interrupt calling two ISRs
I've spent three days on this, and either I'm blind to something, or something just ain't right.

Doorbell. Front door switch and back door switch. Two interrupt service routines, one attached to each pin. Rudimentary debouncing in the ISR seems to work.

But for some reason, both interrupt routines are firing off when either of the switches is pressed. I've tried RISING, FALLING, LOW, CHANGE, and it all works the same. I tried INPUT\_PULLUP and INPUT\_PULLDOWN and changed the polarity on the switches. No change. I've tried different pins, digital, analog. Nothing seems to keep both ISRs from firing.

Pressing front door button, it should print: `front door high`

Releasing front door button `front door low`

Pressing back door button `back door high`

Releasing back door button `back door low`

But for some reason, both interrupt service routines are called when pushing either button. Here's what I actually get:

Pressing front door button: `back door low` `front door high`

Releasing front door button `front door low`

Pressing back door button `front door WTF?` `back door high`

Releasing back door button `front door WTF?` `back door low`

Here's the code. I hope someone can see something I can't:

```
#include <Arduino.h>

#define FRONT_DOOR_SWITCH A2
#define BACK_DOOR_SWITCH A3

volatile int frontDoorStatus = 0;
volatile int backDoorStatus = 0;

void frontDoorIsr()
{
    static unsigned long last_interrupt_time = 0;
    unsigned long interrupt_time = millis();
    // If interrupts come faster than 200ms, assume it's a bounce and ignore
    if (interrupt_time - last_interrupt_time > 200) {
        if (digitalRead(FRONT_DOOR_SWITCH) == HIGH) {
            frontDoorStatus = 1;
        }
        else if (digitalRead(FRONT_DOOR_SWITCH) == LOW) {
            frontDoorStatus = 2;
        }
        else {
            frontDoorStatus = -1;
        }
    }
    last_interrupt_time = interrupt_time;
}

void backDoorIsr()
{
    static unsigned long last_interrupt_time = 0;
    unsigned long interrupt_time = millis();
    // If interrupts come faster than 200ms, assume it's a bounce and ignore
    if (interrupt_time - last_interrupt_time > 200) {
        if (digitalRead(BACK_DOOR_SWITCH) == HIGH) {
            backDoorStatus = 1;
        }
        else if (digitalRead(BACK_DOOR_SWITCH) == LOW) {
            backDoorStatus = 2;
        }
        else {
            backDoorStatus = -1;
        }
    }
    last_interrupt_time = interrupt_time;
}

void setup() {
    pinMode(FRONT_DOOR_SWITCH, INPUT_PULLDOWN);
    pinMode(BACK_DOOR_SWITCH, INPUT_PULLDOWN);

    attachInterrupt(digitalPinToInterrupt(FRONT_DOOR_SWITCH), frontDoorIsr, CHANGE);
    attachInterrupt(digitalPinToInterrupt(BACK_DOOR_SWITCH), backDoorIsr, CHANGE);
}

void loop()
{
    switch (frontDoorStatus) {
        case 0:
            break;
        case -1:
            Serial.println("front door WTF?");
            frontDoorStatus = 0;
            break;
        case 1:
            Serial.println("front door high");
            frontDoorStatus = 0;
            break;
        case 2:
            Serial.println("front door low");
            frontDoorStatus = 0;
            break;
    }

    switch (backDoorStatus) {
        case 0:
            break;
        case -1:
            Serial.println("back door WTF?");
            backDoorStatus = 0;
            break;
        case 1:
            Serial.println("back door high");
            backDoorStatus = 0;
            break;
        case 2:
            Serial.println("back door low");
            backDoorStatus = 0;
            break;
    }
}

```

Board is Adafruit Feather Express M4 (SAMD51)

# Answer
> 1 votes
Turns out that, in the Cortex Mx processors, interrupts don't work the same way as older 8- and 16-bit Arduino-style chips work.

As far as I can tell, there's only one ISR that's connected to the pins. In that routine, you've gotta check the status of the pins you are monitoring and set a global variable accordingly.

I'm not sure this is the only way to do it (seems kludgy), but it does work and it looks like it can scale to any number of pins. I'm using only two.

Here's my demonstration code if anyone is having the same problem. I put the debouncing code in the ISR. I know that's probably not best practice, but it doesn't take a lot of cycles and it's a lot easier than putting it in the loop.

```
#include <Arduino.h>

#define FRONT_DOOR_SWITCH A2
#define BACK_DOOR_SWITCH A3

volatile bool frontDoor = LOW;
volatile bool backDoor = LOW;

void isr()
{
    static unsigned long last_interrupt_time = 0;
    unsigned long interrupt_time = millis();
    // If interrupts come faster than 200ms, assume it's a bounce and ignore
    if (interrupt_time - last_interrupt_time > 50)
    {
        int fds = digitalRead(FRONT_DOOR_SWITCH);
        int bds = digitalRead(BACK_DOOR_SWITCH);
        if (fds == HIGH) frontDoor = HIGH;
        if (fds == LOW) frontDoor = LOW;
        if (bds == HIGH) backDoor = HIGH;
        if (bds == LOW) backDoor = LOW;
        last_interrupt_time = interrupt_time;
    }
}

void setup()
{
    Serial.begin(115200);
    while (!Serial);
    Serial.println("in setup...");
    pinMode(FRONT_DOOR_SWITCH, INPUT_PULLDOWN);
    pinMode(BACK_DOOR_SWITCH, INPUT_PULLDOWN);

    attachInterrupt(digitalPinToInterrupt(FRONT_DOOR_SWITCH), isr, CHANGE);
    attachInterrupt(digitalPinToInterrupt(BACK_DOOR_SWITCH), isr, CHANGE);
}

bool lastFrontDoor = LOW;
bool lastBackDoor = LOW;

void loop()
{
    if ((frontDoor == HIGH) && (lastFrontDoor == LOW))
    {
        Serial.print("fd+");
        lastFrontDoor = HIGH;
    }
    if ((frontDoor == LOW) && (lastFrontDoor == HIGH))
    {
        Serial.println("fd-");
        lastFrontDoor = LOW;
    }
    if ((backDoor == HIGH) && (lastBackDoor == LOW))
    {
        Serial.print("bd+");
        lastBackDoor = HIGH;
    }
    if ((backDoor == LOW) && (lastBackDoor == HIGH))
    {
        Serial.println("bd-");
        lastBackDoor = LOW;
    }
}

```

---
Tags: interrupt, isr
---


# Question
Title: Arduino Newbie: Solderless Breadboard Alternate
I am completely new to arduino. I have created a circuit using solderless breadboard. But obviously the connections are lose or not as good as a soldered solution. So I was wondering since I am new to circuits too, what is the easiest

# Answer
> 21 votes
Breadboards are for development and testing. When you are OK with your circuit, then you solder it.

Your alternatives:

**Point-to-Point**

Just solder directly component to component. You can arrange your component for minimal space and minimal wiring length. Can be very elegant (depends on your abilities) and doesn't require any board.

**Perforated board**

For personal projects, you can use a perforated board to put all your components. Requires some planning in components placement and wiring (you can paint yourself in a corner). Easy to do.

**Expansion Shield**

It's a perforated board on a shield, so you just plug it over your Arduino Uno. Great if you need easy access to lots of Arduino pins. Cons: little space for components. There are versions with a mini-breadboard instead of a perforated board.

**PCB**

You can make your how PCB, but it's hard and too much work. Use it only for high volume production. It require lots of preparation and dangerous chemicals.

**Useful links (YouTube)**

# Answer
> 10 votes
The next step up from breadboard is either matrix board or strip board.

Matrix board is a PCB with a grid (matrix) of holes in a 0.1" grid with copper annulars around them for soldering.

Strip board (also known as the brand name Veroboard) is like matrix board but the holes are linked together in long strips, a little like a breadboard. These strips run the length of the board and you have to break the strips (there is a special tool you can use, but most people just use a small drill bit) into the pattern you require for your circuit.

Yes, both of these require soldering - so now is the time to get to grips with how to solder. There's plenty of tutorials and videos online to help you get to grips with it (though don't grip the hot end...). Don't be afraid of making a mess of your first attempts, soldering takes practice to get it right - and having the right tools helps.

Get a semi-decent soldering iron - not a plumber's iron, but a proper electronic one. You can get basic ones quite cheap. I started out with one of these cheap Antex ones:

If you can afford it, though, go for a temperature controlled one instead. It makes soldering easier since you are less likely to lift pads from over-temperature.

And last you will want some decent solder. I use 0.7mm solder with a rosin flux core. Don't use solder that doesn't have a flux core, that is for plumbing.

Having a flux pen (electronic flux, not plumbing flux) will help get you out of some sticky situations with your soldering as well. The addition of flux makes the solder behave itself. Without extra flux it can me somewhat unruly. Also some desoldering braid and maybe a desoldering pump can be useful (I tend to use braid more than my pump these days).

# Answer
> 3 votes
To make it easy, you can buy so-called proto shields for Arduino like below.

The advantage is that you can stick it directly on your Arduino (Uno/Mega) and you can soldier the extra components on the proto space.

# Answer
> 3 votes
One alternative that I like is the "breadboard-like" copper boards from Busboard Prototype Systems. Several of their models have layouts just like solderless breadboards, but are soldered, and so more durable and stable, while leveraging your breadboard design pin-for-pin:

I love these because like many folks, I prototype earliest versions on one or more breadboards and these have the same hole layout, even down to the parallel power and ground rails down the sides. Very convenient and available in several sizes and other configurations.

# Answer
> 3 votes
Use wire wrap for quick and easy prototyping.

# Answer
> 1 votes
> what is the easiest

for most people, breadboard is the easiest.

I sometimes do point to point (deadbug, mostly RF or small things), or onto pcb adapters (ghetto-style).

# Answer
> 1 votes
I have not had much luck with breadboards either. I see, on internet, that others seem to make even quite complex circuits. I can only assume it means I need to take more care to insert the components better and perhaps spend a bit more on a better quality product? I see the replies all give alternatives but no suggestions as to why Saad has problems and how to improve I would be interested to know too! At the moment, I also solder components to breadboards but it is a pain if I have to de-solder. I also use one of those childrens kits for experimenting with electronics together with a solderless bread board. It has transistors and capacitors etc and so I can connect it to IC or other particular components fitted to the \[!\[enter image description here\]\[1\]\]\[1\]solderless breadboard. The photo is just to give an idea. I have also tried soldering small female sockets to breadboards and plug the various components into those for testing.

I have been experimenting more and reading some articles on internet. In fact, I found it better to make small jumper wires, rather than use tje ready made ones. The ready made ones tend to move and the contact is not so secure. It is nit so easy to make the small jumpers though and needs patience! I also made a small switch power supply board.. I found on "instructables" https://www.instructables.com/id/Ultimate-DIY-Breadboard-Power-Supply/#CB1TV2QJ70QKF7I It plugs into the bread board and I can select a required voltage

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

# Answer
> 0 votes
## Make a PCB with a plotter

You can create a PCB using copper foil and a cutting plotter. The complexity of the circuits will be limited to the resolution and precision that you cutter can plot at but it's a great for prototypes or full projects.

If you already have a machine, the materials are cheap and circuits can be designed using any vector based editing software. Fritzing supports the export of vector files.

> \[LudwigLabs\] is creating PCBs using copper foil and a cutting plotter (vinyl cutter). In this approach, it’s an additive process where instead of removing copper from a copper-clad board, the traces are cut out of copper foil and transferred to a solid backing surface (cardboard, fiberglass, etc.).

Hackaday: Making PCBs with a cutting plotter

Cricut copper PCB

---
Tags: breadboard
---


title: lcd byte array display

text:
# Question
Title: lcd byte array display
when reading RFID(MIFARE) information using Arduino mega and display in serial monitor it works fine. But, when printing on 2004LCD only one information(Value) displays correctly. The other information Item Name display a decimal number. Could someone help on this?

```
 void Price(){
      block = 4;
      status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid));
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Authentication failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
      status = mfrc522.MIFARE_Read(block, buffer1, &len);  // ***Note down buffer1 within the bracket
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Reading failedl: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
             //Display price information...
      for (uint8_t i = 0; i < 16; i++)
      {
        if (buffer1[i] != 32) // if buffer1[i] not equal to 32
        {
          Serial.write(buffer1[i]);  //Price
         //lcd.write(buffer1[i]);
          Value = buffer1[i];
          }
       }
      Serial.print("/=");
      Serial.println(" ");
      sscanf(buffer1,"%d",&Value);
      lcd.setCursor(0,1);
      lcd.println(Value);

     }
    //==========================================================
    void Item(){ //----- Get & Display Item information
        block = 1;
     status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid));
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Authentication failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
      status = mfrc522.MIFARE_Read(block, buffer2, &len);
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Reading failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
      for (uint8_t i = 0; i < 16; i++) { //
         Serial.write(buffer2[i]);       // Display Item
         lcd.write(buffer2[i]);
         Item_Name=buffer2[i];
        }
        sscanf(buffer2,"%s",&Item_Name);
       //sprintf(buffer2,"%d",&Item_Name);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print(Item_Name);// displays numbers instead of "Fresh Milk 1Lt
     }

```

# Answer
> 0 votes
Consider the following:

```
char buffer2[16];  // array of 16 chars
for (uint8_t i = 0; i < 16; i++) {
    do_something_with(buffer2[i]);  // handle one char at a time
}

```

Here we have an array of 16 cells, each having the `char` type (which I assume is what you have). The loop goes through the array, handling one cell a time. Within the loop, `buffer2[i]` represents the `char` being currently handled.

Keep in mind that a `char` is just an 8-bit integer. It is somehow implied that it is meant to represent a character, where 32 = `' '` (space), 33 = `'!'`, 48 = `'0'`, 65 = `'A'` and so on (see ASCII). The Arduino `print()` methods do assume a `char` (unlike an `int`) is intended to be displayed as a character.

Now your actual loop:

```
int Item_Name;
for (uint8_t i = 0; i < 16; i++) {
    Serial.write(buffer2[i]);  // write the char on the serial port
    lcd.write(buffer2[i]);     // write the char on the LCD
    Item_Name=buffer2[i];      // store the char in a variable
}

```

This will print the contents of the buffer to both the serial port and the LCD. You would have seen the expected message on the LCD if you did not have `lcd.clear()` right after the loop.

```
sscanf(buffer2, "%s", &Item_Name);

```

This means “extract from `buffer2` a sequence of contiguous non-white-space characters, and store it in memory at the address of the variable `ItemName`”. If the buffer contains “Fresh Milk 1Lt”, this will write “Fresh” to that memory location. That is 6 bytes (5 letters and a terminating NUL). Unfortunately, the compiler has only allocated 2 or 4 bytes of RAM for storing `ItemName` (depending on the Arduino model), so this will write past the allocated storage, which is a type of bug known as buffer overflow. Now your Arduino's memory is corrupted and anything can happen.

```
sprintf(buffer2, "%d", &Item_Name);

```

This tries to find within `byffer2` a textual representation of a number, and store it into `Item_Name`. This is safe, but only makes sense if the buffer contains a number, written as text, which is not the case here.

```
lcd.print(Item_Name);

```

This is asking the LCD to print an integer (namely `Item_Name`). It will convert the integer to decimal text and print the corresponding digits on the LCD.

Let's assume for example that `Item_Name` contains the numeric value `32` (which is the ASCII representation of a space). `lcd.print()` will convert that into a sequence of two characters: `'3'` and `'2'` (the decimal representation of 32). It will then send those characters to the LCD (ASCII values 51 and 50), and you will see the text “32”.

If you want to see the text contained within the buffer, the you can either send the characters one by one (like you already did right before `lcd.clear()`), or provide to `lcd.print()` a `char*` pointer with the whole message:

```
lcd.print(buffer2);

```

This assumes that the buffer is terminated with a NUL character. If it is not, then you can either use the char-at-a-time method, or change your code in order to put a NUL terminator in the buffer.

---
Tags: serial, lcd, array, rfid
---


# Question
Title: How to convert an int to const int in Arduino?
For a specific project, I need to convert an int to a const int variable type.

```
int i = 10;
boolean ShiftRegister[i] //Throws error

const int i = 10;
boolean ShiftRegister[i]// Works Fine

```

as i am making my own custom library where the size of boolean can be defined by creating an object by the user

```
myLib Library(20); // user defined boolean size

```

and the size is stored to a struct like this as it can't directly be converted to a const int.

The header file ...

```
#ifndef myLib_h
#define myLib_h
#include "Arduino.h"

class myLib{

public:
myLib(int input);
private:
int input;

};
#endif

```

the C++ code

```
#include "myLib.h"
#include "Arduino.h"

 struct Data {
  int BoolSize;
 }Data[0];

 myLib::myLib(int input){
 Data[0].BoolSize=input
 }

 const int boolSize = Data[0].BoolSize;

 bool DataBoolean[boolSize];

```

Whenever i run this library, it throws an error untill i dont predefine the boolean size in cpp code like this..

```
bool DataBoolean[20];

```

that means there is something error converting the int to const int in this line

```
const int boolSize = Data[0].BoolSize;

```

so what i want is, i dont want to predefine the boolean size in the cpp code. i would rather like to define boolean size by creating an object(where the code crashed), storing the size to a structure then assigning the structure integer to the const int variable. I need an efficiant way to

turn this struct variable

```
Data[0].BoolSize;

```

into a const variable and assign to it like this without any errors

```
const int boolSize = Data[0].BoolSize;

```

so how can i convert an integer to a const int so that i can continue to my project?

any helps please? thanks for your kind support.

# Answer
> 2 votes
At the time the constructor of your class is called, its size must be already defined, because the memory allocation takes place before. But you try to give it as a parameter to the constructor. This cannot work.

You have at least these alternatives. *(Note: This is an invitation to edit this answer and add more, if you know some serious solution.)*

### 1. Use a template for the size

Please be aware that each different size will generate another implementation in machine code.

```
template<size_t size>
class myLib {
public:
    inline myLib<size>() {}
private:
    bool data[size];
};

```

### 2. Allocate the requested memory dynamically

```
class myLib {
public:
    inline explicit myLib(size_t size) : data(new bool[size]) {}
    inline ~myLib() {
        delete[] data;
    }
private:
    bool* data;
};

```

*Note: Depending on the version of C++ you're using, you need to consider the Rule of Three (before C++11) or the Rule of Five (beginning with C++11). Since the implementation of the missing methods depends on specific details, it is left as an exercise to the reader.*

# Answer
> 0 votes
If you want variable length of an array, then you can use malloc. With same conext, if you want to initiate an array with specific length of value you have to use malloc.

---
Tags: library, cpp
---


# Question
Title: Compiling for Wemos D1 mini with Visual Studio Code
I'm giving Visual Studio Code (VSC) a try and am getting unexpected results. I have a program (sketch) that compiles fine in the Arduino IDE. I create a workspace in VSC, initialize the project, and after some more mucking about I get a compile there appears to succeed:

```
[Done] Finished verify sketch - RanchMonitor2.ino

```

But the console pane shows four "problems":

How can the compilation have succeeded if there are problems?

The same sort of thing is happening with one of the samples - HelloServer.ino In this case the problems are an incomplete type and memcpy\_P not defined.

I wouldn't think it should make a difference, but I'm working without a board physically attached to the USB port.

UPDATE: I think "Problems" are issues identified by Intellisense. They appear even before a compilation is attempted. All I have to do is open the workspace and wait a few seconds, then the "problems" appear. Hence my conjecture they are Intellisense warnings, not compilation errors. Adding "ESP8266" to the Defines section of c\_cpp\_properties.json got rid of the error "WiFiManager" is undefined.

# Answer
Intellisense reports "Problems" - these are distinct from compile time errors. Just because Intellisense can't resolve a literal or something doesn't mean it won't be resolved in the compiler; thus it's possible to have the IDE report a problem but still be able to have a successful compile. In the case described above, two changes to the c\_cpp\_properties.json file provided Intellisense with the information it needed. A header file was added to the forcedInclude section to provide pin definitions. A literal "ESP8266" was added to the defines section to indicate the processor type. This define is used in lots of header files so it must be know to Intellisense when reading the headers. Here are the relevant sections of that .json file:

```
        "forcedInclude": [
            "C:\\Users\\David\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\2.7.1\\variants\\d1_mini\\pins_arduino.h"
        ],
        "defines": [
            "USBCON",
            "ESP8266"
        ],

```
> 1 votes

---
Tags: esp8266, vscode
---


# Question
Title: How can I control 2 servos without an external power supply?
I've been trying to implement a project that's been in my head for a while, I want to wirelessly control my light and fan switches using an ESP32 and 2 servos (one for each switch) through an HTML page, and then later integrate it with Alexa

I have seen how **one** servo can be controlled by connecting the servo's power cable to the ESP32's Vin pin, but how can I control **two**? I want to avoid using an external power supply like a battery pack because I want it to be a completely automated process, and I don't want to have to keep switching out batteries often for the thing to work. I'll be using a 5V wall outlet to power the ESP32 using a USB.

Also, if anyone can provide a few more tips on how I can make my project more efficient or point out where I might be making a mistake, I'd be glad. I'm still new to the microcontroller world.

Thanks

**EDIT** : I've attached a picture of the circuit diagram, just have a look and let me know if it is workable

# Answer
The power wire is just needed, well, to power the servo. The control is done via the third wire (the other wire being Ground).

You can connect the second servo's power in parallel, only the control wire must be separated from the first servo's control wire.

*Note: You need to make sure that the current consumption of both servos does not exceed the provided power.*
> 1 votes

---
Tags: esp32
---


# Question
Title: SEN0114 moisture sensor low max reading?
I am using the following SEN0114 moisture sensor with an ESP32: https://datasheetspdf.com/datasheet/SEN0114.html

How come when submerged in water I only get a reading of ~2500? Should this not read ~4095 as the ESP32 analog pins are 12-bit?

# Answer
> 1 votes
This is a resistive sensor and "plain" water is not infinitely conductive. In fact, pure or distilled water is a very poor conductor. Also, "plain" water - tap water, I assume - will vary in its dissolved solids, not only from source to source, but likely over time, too, for some sources and it is these solutes that are responsible for increased conductivity. That goes double for plant-moisture sensing because it is really measuring the resistance of damp dirt, which again, varies in composition.

So the sensor can give you a range from dry to very moist, *per plant*, but the absolute measurements won't be very meaningful.

---
Tags: sensors, esp32, analogread
---


title: Arduino Nano Every I2C PORTMUX

text:
# Question
Title: Arduino Nano Every I2C PORTMUX
Arduino Nano Every schematic informs us that we can use ATMega4809's pins PF03 and PF02 to communicate via I2C.

ATMega4809 manual says in page 19 that in order to use those pins as I2C we need to use PORTMUX.

I'm not really an expert and I don't understand how to do that. Any help would be approciated.

# Answer
In the Nano Every schematic, PF2 and PF3 are connected over to PA2 and PA3 respectively. That is, Arduino pin A5 and ATMega4809 pins PF03 and PA03 are connected together by PCB traces such that there's no distinction between them, PF03 doesn't have its own header pin anywhere distinct from PA03. They're both A5. Likewise for Arduino pin A4 and ATMega4809 pins PF02 and PA02.

The Nano Every was designed to be compatible with the original Nano boards that used the ATMega328P. On these boards the A5, `analogRead`-capable pin, is *also* the I2C/Wire clock signal. Likewise, A4, `analogRead`-capable pin, is *also* the I2C/Wire data signal.

On the ATMega4809 the I2C/Wire Master/Slave signals on PORTA routed to the A5 and A4 pins are not *also* `analogRead`-capable. That is, they are not connected to the analog-to-digital converter in the chip as they were in the Atmega328P on the old Arduino Nano boards.

To mirror the workings of the original Nano, where A4 and A5 were *both* `analogRead` pins and I2C/Wire Master/Slave pins, they connected A4 and A5 to *pairs* of ATMega4809 pins. One of these pins on PORT**F** is connected to make the Arduino pin `analogRead`-capable and the other pins on PORT**A** are connected to make the Arduino pin Wire/I2C Master/Slave capable. In other words, they used two AVR pins to synthesize a single Arduino pin capable of both functions that were available on that pin on the older Nano boards.

When it comes to using PORTMUX to switch choice of I2C pins, practically speaking, you won't be able to if you're looking to get alternate pins for TWI Master. PORTMUX lets you switch the I2C Master/Slave or just Master peripheral onto pins PC2 and PC3 instead of PA2 and PA3. But, in the Nano Every schematic, you can see these are not connected to anything. So if you wanted to do that, it would mean something like soldering wiring-wrap wire directly to the MCU pin, which would be difficult. And PC2 and PC3 are the only two other ATMega4809 pins that PORTMUX will route the hardware I2C Master/Slave peripheral to. So, practically speaking, if you want I2C any pins other than A4 and A5 on a Nano Every, it means using a software (bit-banged) implementation of I2C.

You asked (in comments) about the TWI support indicated on PF2 and PF3 in the ATMega4809 datasheet. I think I'd either been looking at an older datasheet or maybe disregarded those pins because of how they're hardwired over to PORTA on the Nano Every. The ATMega4809 has a "Dual TWI" mode apparently, where you can have just master mode on the pins that are normally both, and just slave mode on an alternate set of pins. In two configurations of PORTMUX under Dual TWI, the PF2 and PF3 are where the slave-only capability of the peripheral are broken out. With PORTC's TWI pins unconnected and PORTA's TWI pins hardwired to PORTF's TWI pins, it's unclear to me what advantage you could get out changing PORTMUX on an Arduino Nano Every.
> 2 votes

---
Tags: i2c, atmega
---


# Question
Title: WDT ISR not called when SPI ST7789 module initiated
Using the `.init` function for the ST7789 TFT screen prevents my WDT ISR from firing. What explains this behaviour, and is there something I can do? Any other timer ISR I could use instead?

```
#include <Adafruit_ST7789.h>    // Includes Adafruit_GFX.h

#define TFT_CS 10 // define chip select pin
#define TFT_DC 9  // define data/command pin
#define TFT_RST 8 // define reset pin, or set to -1 and connect to Arduino RESET pin

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

void setup()
{
    //Serial.begin(9600);
    pinMode(13, OUTPUT);

    WDTCSR = (24); // Change enable and WDE - also resets
    //prescalers only - get rid of the WDE and WDCE bit.
    WDTCSR = (6); // 1 sec
    WDTCSR |= (1 << 6); //enable interrupt mode - WDT as an interrupt is useful to wake up from sleep
    sei();

    tft.init(240, 240, SPI_MODE2); // comment this out and WDT works fine
    tft.setRotation(0);
    tft.setTextWrap(true);
}

void loop()
{

}

ISR(WDT_vect)
{
  digitalWrite(13, (digitalRead(13) ^ 1));   // toggle LED pin
}

```

Thanks!

# Answer
You can't use the LED on pin 13 on Uno, Nano or Nano Every, if you use SPI . It is the clock pin of the SPI.

The init function of the display initializes SPI which dedicates the pin to SPI peripheral and disconnects it from pin IO peripheral.
> 2 votes

---
Tags: spi, tft, watchdog
---


# Question
Title: How would one send radio signals from Arduino at a non-standard frequency
**TL;DR:** How would one send a fixed radio signal at 447,54MHz with Arduino?

**Background:** I recently purchased a (receive only) SDR and recorded my garage door fob. I found it sends a fixed signal at the frequency 447,54MHz, which I was able to decode. Now I want to try activating the garage door via Arduino. The standard 433MHz senders obviously don't work, since they have a totally different frequency.

I tried searching for senders of my frequency (447MHz) and also for senders with different or variable frequencies. I didn't really find much. Also I read in some post (that I don't remember currently), that building an own sender circuit is not easy (since the exact PCB design plays a big role in the behavior in the ciruit). It didn't seem, that this would be a valid way for me.

Has someone here experience with such frequencies? While I know, that this site doesn't do product recommendations, maybe I just searched for the wrong term and you can help me with that. Or maybe there are no (or very very few) "maker-ready" products for this out there currently. Maybe the creator of the garage door system wanted a non-standard frequency for security-through-obscurity (since that doesn't protect against attackers with a sending SDR).

Also I researched about frequency bands. Normally I would think of a garage door fob as a Short Range Device (SRD), but instead my frequency is right above (and outside) of the band PMR. Maybe this is because the system is really old (can easily be between 15 and 30 years).

I'm kinda lost on how to proceed here, or if proceeding is even viable here.

# Answer
> The standard 433MHz senders obviously don't work, since they have a totally different frequency.

I think "433 MHz" is used as a band name, with 433 MHz actually being at the lower limit of a band that covers approximately 40 MHz. Your garage door opener will likely be referred to as a "433 MHz garage door opener", even though it operates at 447.54 MHz.

For your experiments, you might try the HC-12 module. It's billed as a 433 MHz radio, but in fact it covers 433 MHz to 473 MHz in 100 bands with 400 kHz spacing, so it will cover your desired 447.54 MHz. The link above has some Arduino code examples that might help get you started. And of course there is much more information on this topic if you're interested.
> 1 votes

---
Tags: rf
---


title: Using functions in header files

text:
# Question
Title: Using functions in header files
I want to include a function in my sketch I moved to a .h file.

I did it as follows:

My code:

```
#include "header.h"

void setup() {
  fct();
}

void loop() {

}

```

My header:

```
#include "Arduino.h"
#ifndef MYHELPERS_H
#define MYHELPERS_H

void fct() {
// stuff
}

#endif

```

The same process seems to work for variables but the IDE says this function in not declared in this scope...

I don't understand what I'm doing wrong...

Thanks guys!

# Answer
I found a solution somewhere else on internet...

This portion:

```
#ifndef MYHELPERS_H
#define MYHELPERS_H

```

Was not written correctly... "MYHELPERS\_H" should've been replaced by the name of my file. Now it works just fine.
> -1 votes

---
Tags: arduino-ide, error, functions, header
---


title: Make an LED less bright

text:
# Question
Title: Make an LED less bright
As an exercise to learn rather then the most efficient way to accomplish a goal.... (i'm a hands on hardware guy, but I need to get my Sh!T together and learn some coding)

I would like to make an LED less bright within a project. I have a nano set up to control a relay to control a dc load when a momentary switch is pressed (this is kinda needlessly complicated solely to allow me to use a particular momentary switch I wanted to use for a bunch of not that great reasons ;-)

Anyway... the code i'm using is this:

```
int pbuttonPin = 2;// connect output to push button
int relayPin = 10;// Connected to relay (LED)

int val = 0; // push value from pin 2
int lightON = 0;//light status
int pushed = 0;//push status

void setup() {
  // Robojax.com code and video tutorial for push button ON and OFF
  Serial.begin(9600);
  pinMode(pbuttonPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
 digitalWrite(relayPin, HIGH);// keep the load OFF at the begining. If you wanted to be ON, change the HIGH to LOW
}

void loop() {
// Robojax.com code and video tutorial for push button ON and OFF
  val = digitalRead(pbuttonPin);// read the push button value

  if(val == HIGH && lightON == LOW){

    pushed = 1-pushed;
    delay(100);
  }

  lightON = val;

      if(pushed == HIGH){
        Serial.println("Light ON");
        digitalWrite(relayPin, LOW);

      }else{
        Serial.println("Light OFF");
        digitalWrite(relayPin, HIGH);

      }

// Robojax.com code and video tutorial for push button ON and OFF

  delay(100);

```

The above code is straight up cut and paste... i'm clueless

I have a LED cathode on pin 10, (so i know the relay is on more easily from a distance). however the application is on a boat, and at night it is too bright and distracting. So i want to make the LED dimmer... I know I could add a larger value resistor, but i want to expand my understanding and would like suggestions on other ways PWM maybe....

cheers:

# Answer
There are two methods of dimming a LED : by PWM or by a limiting current resistor.

1. PWM code

```
 `//Initializing LED Pin
 int led_pin = 10;
 void setup() {
 //Declaring LED pin as output
         pinMode(led_pin, OUTPUT);
 }
 void loop() {
         analogWrite(led_pin, 127); // half intensity
         delay(5);
 }`

```
2. Hardware. Use following schematic
> 2 votes

# Answer
If you want to decrease the brightness in general, the easiest solution would in deed be to use a high value resistor.

If you want to use PWM - for example to change brightness programmatically - you just need to replace the calls to `digitalWrite(HIGH|LOW)` with calls to `analogWrite(x)` (ref), where `x` represents the duty cycle/brightness. The range of `x` depends on your microcontroller.

Note, that PWM (which is used by `analogWrite()`) only works on dedicated pins. On the other side, there are microcontrollers wich have analog pin with a "true" analog output. On such an analog pin - though it is possible to use `analogWrite()` \- the brightness will not be linear and have an offset, which makes it pretty much useless for dimming an LED.
> 1 votes

# Answer
Follow this tutorial. It doesn't get any better than this. https://www.arduino.cc/en/Tutorial/BuiltInExamples/Fade
> 0 votes

---
Tags: led
---


# Question
Title: ATTiny85 USB Troubleshooting. Device is not recognized when programmer asks to plug in device
I have bought this cheap AVR Programmer Board and I thougth that I would be OK just plugging it into my USB port. Then after I did that nothing happened so I passed last 4 hours trying to understand what was going wrong. I learned that ATTiny85 microchips often come with no bootloader.  So first I tested it with Arduino as ISP and simple blink code. It worked. Then I downloaded micronucleus and i flashed it via Arduino as ISP. I think this process worked pretty well as the output show

```
> avrdude -C ../etc/avrdude.conf -c arduino -p t85 -P COM3 -b 19200 -U flash:w:/micronucleus/firmware/releases/t85_default.hex

 avrdude: AVR device initialized and ready to accept instructions

 Reading | ################################################## | 100%
 0.01s

 avrdude: Device signature = 0x1e930b (probably t85) avrdude: NOTE:
 "flash" memory has been specified, an erase cycle will be performed
          To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file
 "/micronucleus/firmware/releases/t85_default.hex" avrdude: input file
 /micronucleus/firmware/releases/t85_default.hex auto detected as Intel
 Hex avrdude: writing flash (8166 bytes):

 Writing | ################################################## | 100%
 0.09s

 avrdude: 8166 bytes of flash written avrdude: verifying flash memory
 against /micronucleus/firmware/releases/t85_default.hex: avrdude: load
 data flash data from input file
 /micronucleus/firmware/releases/t85_default.hex: avrdude: input file
 /micronucleus/firmware/releases/t85_default.hex auto detected as Intel
 Hex avrdude: input file
 /micronucleus/firmware/releases/t85_default.hex contains 8166 bytes
 avrdude: reading on-chip flash data:

 Reading | ################################################## | 100%
 0.09s

 avrdude: verifying ... avrdude: 8166 bytes of flash verified

 avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)

 avrdude done.  Thank you.

```

Problem that I'm now facing is that when I try to upload a code using ATTiny Development Board via arduino IDE (selecting Attiny85 digispark default 16.5mhz) and it asks me to plug in the device, device is not recognized.

I already installed drivers downloaded from github release section of DevicestumpArduino repository, tried installing micronucleus configuration driver via zadiag like i read in this question but nothing worked. What am I missing?

# Answer
From your AVRDude output:

> avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)

It does not appear that you have programmed the AVR configuration fuses.

One for thing, `E:FF`, is extended fuse value 0xFF, which is missing the `SELFPRGEN` (self-programming) fuse that would allow Micronucleus to load your code onto the AVR, that is allow the AVR to execute instructions to program itself. So, assuming it managed to show up on USB, you wouldn't actually be able to use it to put code on your chip.

You can see what they should be where the makefile `fuse` target defers to your `t85_default` configuration:

```
FUSEOPT = -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m -U efuse:w:0xfe:m

```

The fuses that are actually preventing it from showing up on USB are more likely the clock related fuse bits in the low fuse byte. In particular `CKDIV8` (factory default) is set to divide-by-8 where it is not in the makefile. The `CKSEL` bits are set to 0x2 (factory default) for the 8Mhz internal RC oscillator whereas the makefile wants them to be set to 0x1, for internal PLL (phase locked loop) that generates higher clock rates from the RC oscillator. In short, your chip is running at 1MHz rather than 16Mhz. The Micronucleus code may also be written such that it needs PLL for bit-banging USB, though I haven't looked into that to be certain.
> 3 votes

---
Tags: attiny, attiny85
---


# Question
Title: Arduino recieve sensor data from other arduino SPI
I have Arduino Uno (sender) and Arduino Uno Wifi rev 2 (receiver). I want to send the ping value to the other one via serial - jumper wires. Arduino Uno is using the newping example, and I want the Uno Wifi to receive the sensor value and print it to serial. I am using SoftwareSerial.h jumper wires go TX\<-\>RX , RX \<-\>TX, GRD-GRD according to the pins in the sketch below.

The problem is the sketch code for the Uno WiFi (receiver), it keeps printing garbage and seems like no carriage return sometimes.

```
13
⸮10
⸮52
⸮5LC⸮1⸮H⸮10
5⸮H⸮51
13C⸮10
⸮5⸮H⸮5LC⸮13
10
⸮52
51C⸮13
10
⸮52
5LC⸮13
⸮10C⸮52
⸮51
13
10
⸮52
50

```

Code on Uno (sender):

```
// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------
#include <SoftwareSerial.h>
#include <NewPing.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
SoftwareSerial mySerial(9, 10); // RX, TX

void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

 Serial.println("Hello World Serial");
 mySerial.begin(4800);
 mySerial.println("Hello World, mySerial");
}
void loop() {
  delay(500);                     // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  Serial.print("Ping: ");
  Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range)
  Serial.println("cm");
  mySerial.print(sonar.ping_cm());
  mySerial.println();
  }

```

code on uno wifi (reciever):

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // set the data rate for the SoftwareSerial port
  mySerial.begin(4800);

}

void loop() { // run over and over

    Serial.println(mySerial.read());
    delay(1000);

}

```

I can see the Uno (sender) with NewPing is printing the correct data to it's serial but I can't get the Uno wifi (listener) to get the same value. Its just garbage. I am new to this, what am I doing wrong?

# Answer
Well had a bit of luck after spending all day on this.

Arduino UNO (sender): Like mentioned by chrisl, use `Serial.write` and not `Serial.print`

```
mySerial.write(sonar.ping_cm());

```

UNO Wifi (receiver):

```
Serial.println(mySerial.readString());

```

So, instead of `mySerial.read` I used `mySerial.readString`. This is most likely a obvious mistake to almost everybody here; took me two days. Sigh.
> 1 votes

---
Tags: arduino-uno, serial, spi, softwareserial, arduino-uno-wifi
---


# Question
Title: what voltage level is a digital low for the interrupt mode LOW?
I am learning about interrupts and one of the interrupt modes is LOW which triggers anytime the pin is a digital low.

Can someone tell me what voltage that is for an Arduino nano? I did a google search and it said a LOW can be anywhere from 0 to 2V.

I am making a project using a nano and I am powering it with batteries. It would be great if I could set up an interrupt to turn on an LED when the batteries were getting weak so I would know when to change them.

# Answer
> It would be great if I could set up an interrupt to turn on an LED when the batteries were getting weak

That won't work. The thresholds for the pin registering LOW or HIGH depend on the supply voltage. Very roughly:

* a pin in guaranteed to register LOW if its voltage is below ⅓ Vcc
* it is guaranteed to register HIGH if it's above ⅔ Vcc
* nothing is guaranteed between ⅓ and ⅔ of Vcc.

For the exact voltage levels, you should check the datasheet.

Note also that those are *guaranteed* levels. The actual thresholds are closer to ½ Vcc, with an hysteresis of roughly Vcc/10.

For detecting a low battery condition, you should use the ADC, combined with either a voltage divider on Vcc or the internal bandgap reference.
> 2 votes

---
Tags: arduino-nano, voltage-level
---


# Question
Title: How can I remove the delays in this code for sweeping the servo?
I know this is probably a very asked question, but I am building a fairly basic radar type thing which sweeps left and right and uses an ultrasonic sensor to determine the distance to an object and a buzzer is set off if something is detected.

The device itself works but I've noticed that because I have used delay() to allow the servo to complete its full movements, it is holding up the rest of the code, and as a result the buzzer and returning of the distance is extremely unresponsive and sluggish.

So far I have looked at simply returning a value whenever the motor reaches a certain step but it doesn't achieve exactly what I'm looking for, and I have looked into using millis() for timing asynchronously, but I'm struggling to wrap my head around it a bit in terms of how it will work for a servo.

My current working but sluggish code:

```
//Servo Stuff
#include <Servo.h>
int servoPin = 12; // Pin for interacting with servo defined
int servoStart = 0; //Starting position of servo motor
int servoEnd = 90; //End position of servo means it rotates 90 degrees
int waitTime = 1000; // Allows servo to fully rotate before moving again
int servoPos = 20; // For incrementing the position of the servo
int servoStep = 20; //amount to increment servo position by
Servo myServo; // Creates an instance of a servo object

//Ultrasonic stuff
int trigPin = 9;
int echoPin = 10;
long duration;
int distance;
int maxDistance = 329; // The max range of the ultrasonic sensor

//Buzzer stuff
int buzzerPin = 11;
int buzzerWait = 200;

void setup(){

//Attach the servo object to the pin and begin serial monitor with
// polling rate of 9600
Serial.begin(9600);
  myServo.attach(servoPin);
  pinMode(buzzerPin, OUTPUT);

    pinMode(trigPin, OUTPUT); // Trig pin set as output
    pinMode(echoPin, INPUT); // echo pin set as i
      }

    void loop()
    {

      // Moving servo
      myServo.write(servoStart); //Moves servo to the starting pos
      //delay (waitTime); //allows servo to fully move before next move
      //myServo.write(servoEnd); //Moves to end position
      //delay (waitTime); // waits before reverting back to start pos

    //myServo.write(servoStart);
    //delay(waitTime);
    //myServo.write(20);
    //delay(waitTime);
    //myServo.write(40);
    //delay(waitTime);
    //myServo.write(60);
    //delay(waitTime);

     // Using ultrasonic sensor

      // Clears the trig pin
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);

    // Sets the trigPin on HIGH state for 10 microseconds
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

    // reads echoPin and returns the travel time of the wave in microseconds
      duration = pulseIn(echoPin, HIGH);

    // Calculating distance
      distance = duration*0.0343/2;

    //Prints the distance to the Serial Monitor
      Serial.print("Distance: ");
      Serial.println(distance);
      Serial.println(distance);

      if (distance < maxDistance) {
      digitalWrite(buzzerPin, HIGH);
      //delay(buzzerWait);
      //digitalWrite(buzzerPin,LOW);
      //delay(buzzerWait);

      }else digitalWrite(buzzerPin, LOW);

    }

```

Any pointers to some good resources for this would be very appreciated, thanks.

# Answer
> 2 votes
From your code it seems like you are doing all the servo movement before you read the distance and report back. A lot of code is commented out, so it's a bit difficult to follow. What I would do is something along the line of:

```
[...]
int servoStart=0;
int servoEnd=90;
int servoPos=0;

[...]
void setup() {
    [usual setup stuff like you do it now]
    myServo.write(servoPos);  //start at pos 0
    // Maybe a delay here to make sure we are at pos. 0
}

void loop() {
    //Switch direction if we reach end
    if (servoPos+servoStep < servoStart || servoPos+servoStep > servoEnd)
        servoStep = -servoStep;
    servoPos += servoStep;
    myServo.write(servoPos);
    //Small delay?
    //Read distance
    //Send distance to seraial
    //Buzz buzzer if needed
}

```

---
Tags: servo, millis
---


# Question
Title: How to use LCD Screen and IR Remote to broadcast a countdown
I am trying to use an IR Remote to input date's and time's for a countdown, so then the LCD will display a countdown, like this:

```
LCD: Enter Year
Remote-Input: 2021
LCD: Enter Month
Remote-Input: 08
LCD: Enter Day
Remote-Input: 20
LCD: Enter Hour
Remote-Input: 08
LCD: Enter Minute
Remote-Input: 00
LCD: Enter Second:
Remote-Input: 00
LCD: You have __ Years, __ Months, __ Days, __ Hours, __ Minutes, __ Seconds.

```

How do I do this?

# Answer
> How do I do this?

I have no clue how you do that but I do know I would do that.

> I know how to ask a question.

Apparently not, your question is far from perfect (and my answer above is technically the only correct answer to that specific question). It doesn't tell us what you've tried, it doesn't tell us what you haven't tried. It not specific nor practical. Doesn't state your experience with Arduino, doesn't state which hardware you (would) be using. (Though I must say your example output thing is quite nice)

> I was just in a rush.

Isn't everyone nowadays? And why would we invest time in an answer on a question which has no effort put into it?

---

You're basically asking "How to do an Arduino project" (or any project), there's many ways but let's dive into it.

**0. Split up your project into smaller projects.**

Since it sounds as if you have no clue on how to get started or if you feel this project is daunting, it may help to make the 'problem' easier to get started. You can always add more complexity.

Make one Arduino program, which shows "Hello World" on the LCD.

Make one Arduino program, which receives IR codes and depending on which button pressed, shows "Hello" or "World" in your terminal.

**1. Research**

Search the internet, maybe there's projects like this. Try to google for "Arduino Countdown Timer". Check what design choices they made, what hardware they use and how they work in general.

**2. Design**

Make a design, not only about the aesthetic part, but also functionally. What happens if the timer depletes? Should it also have a buzzer? Does it need an enclosure?

And technically, how will it be powered?

**3. Acquire hardware**

As a starter; it can help to buy hardware from stores that also include example code. Use the example code to test and verify your hardware and connections.

**4. Software**

If you're asking "How to write software", you're better off starting out with some example projects/tutorials which include the code and explain it.

But basically you should use the example code to drive the hardware, use examples on the internet combined with your own experience to create a program that matches your required behavior.

---

**If, along this path, you have a practical question. We will be much more able to, and happy to, help.**
> 0 votes

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


# Question
Title: Reproduce simulated temperature data with Arduino
I'm starting a test using Arduino to reproduce a set of temperature values in water each three hours and need some help with it.

I will use two ds18b20 sensors to control two thermostats connected to relays. The idea is that Arduino could access the data from a file in which there are simulated data for each day in the future. Something like this:

```
Date,Time,Temperature
01/01/2070,00:00:00,27.229211807251
30/12/2070,21:00:00,24.6133060455322
01/01/2070,06:00:00,22.1697025299072
01/01/2070,09:00:00,20.3209171295166
01/01/2070,12:00:00,27.7610721588135
01/01/2070,15:00:00,33.6277084350586
01/01/2070,18:00:00,34.5402450561523
01/01/2070,21:00:00,31.9973392486572
02/01/2070,00:00:00,26.2283573150635
02/01/2070,03:00:00,21.5823612213135
02/01/2070,06:00:00,18.6461429595947
02/01/2070,09:00:00,17.2126712799072
02/01/2070,12:00:00,24.8096561431885
02/01/2070,15:00:00,30.6440677642822
02/01/2070,18:00:00,33.8463973999023
02/01/2070,21:00:00,31.3529300689697
03/01/2070,00:00:00,25.2961673736572
03/01/2070,03:00:00,20.8135623931885

```

Based on this info the sensor will control the thermostat to decrease or increase the temperature within three hours (8 different temperatures by day). I'm going to start with 1 week (7 day x 8 temperatures = 56 simulations), but want to increment it till 3 months (720 simulations).

Considering the use of if/else if, it seems that would be a massive amount of conditionals.

Does anybody have a good solution to run this temperature simulation based on predefined data?

Thanks in upfront.

# Answer
> 2 votes
You can use an array to go through the times.

Create a struct with the fields `time` and `temperature` (you should think about saving time as unix epoch, meaning seconds since 1970, so that you save memory).

```
struct SetPoint {
    unsigned long time;
    float temperature;
};

```

Then you can declare an array of type `SetPoint` to hold the tubles of time and temperature:

```
#define DATA_SIZE  720
SetPoint data[DATA_SIZE] = {
    {<time1>, <temp1>},
    {<time2>, <temp2>},
    ...
    };

```

In the above, you need to replace `<timeX>` and `<tempX>` by your data. Then declare a position variable, which the element index, which will be invoked next:

```
unsigned int pos = 0;

```

We are starting with the first element (index 0) and compare its time to the current time. If it is equal (or current time is after the elements time), we will set the thermostat to the elements temperature and increment the position variable. Something like this:

```
if(pos < DATA_SIZE && current_time >= data[pos].time){
    set_thermostat(data[pos].temperature);
    pos++;
}

```

Note: I used the variable `current_time` here as standin for your way of getting the current time, and the `set_thermostat()` function as a standin for your way of setting the thermostat. Also I inserted a check into the if statement, to prevent the code going further, when it reached the data array end.

---

That said, depending on the used board you can easily get into memory trouble here. An Arduino Uno does not have enough memory to save 720 of the data points above. `float` and `unsigned long` both take 4 bytes each, so 8 bytes per element, which makes `8*720 = 5760` bytes. The Uno only has 2048 bytes total in RAM. There are enough boards, which have more RAM. The ESP32 for example would have way enough (though there are many others; the ESP32 is just the first to get into my mind here).

Or you can add an SD card module to your build and save the data points in a file. That would also make it way easier to get the data in your project or change the data. It would just involving writing the corresponding file on your SD card.

Then the workflow would be a bit different. Lets assume you save one data point per line as text:

* Open file and read one line. Close file.
* Parse read text into 2 variables (time and temperature)
* Use these variables for the if statement from above
* if the time of the loaded data point was reached, open the file again, read the next line and parse it into the variables
* The if statement now uses the next datapoint

and so on. If there is no line left to read, you could go into an infinite loop, stopping the code from running further than your data.

There are ready to use SD card modules to buy out there, and you can find many tutorials about how to use them online.

---

As Edgar Bonet correct stated in the comments, you can greatly reduce the needed RAM, when assuming regular intervals (3h in your case). Then you don't need to save the time for each data point. You only need the one start time for the series. Also above I used `float` for the temperature (as I assumed, that at this point it would be the easiest for you). But since temperature settings for thermostats are mostly working only down to the 1 digit after the decimal point, you can save memory space by using a different representation. For example you could save the temperature as a single byte signed integer with the unit of 0.1°C and a reasonable offset (for example 25°C being zero). So some example values would be:

```
Temp | value
------------
18°C | -70
20°C | -50
22°C | -30
25°C | 0
27°C | 20
35°C | 100

```

That would give you the precision of one digit after the decimal point and a range from 12.3°C to 37.8°C. When changing the factor of `0.1°C`, you can also change the range (and precision with it) as you really need it.

So with the above you would only need 720 byte for the actual data, which is good for the Uno.

BUT: I would still suggest looking into the SD card reader. You will have more work building the project, but you won't have the same hassle with including or updating the data. That can come in especially handy, if you want to use to further use the device after the 3 months. Just loading new data on it (maybe even way more data, like for a full year) is easier with an SD card.

---
Tags: arduino-uno, relay, temperature-sensor, datalogging, automatization
---


# Question
Title: Set up a motion sensor to turn on lights and record how long the lights are on
I'm doing a school project and I want to measure the difference in time that the lights are on in a classroom with and without a motion sensor controlling them. I haven't really found anything about recording how long sensors act or the time between activations. How could I possibly do this?

# Answer
> 3 votes
I would consider placing a light sensor close to one of the lights to signal when the lights are on. Placement is critical as you do not want a signal when the lamp is off. I am assuming they are permanent light fixtures and you are not allowed to tamper with the wiring. Record the elapsed time when they are on. Note the start time and then subtract that from the current time based on your watch. For elapsed time and subtract the ontime from that. With the sensor you can also record each time the light is turned on etc. That would all be in your software.

---
Tags: sensors
---


title: Convert from hexadecimal to binary

text:
# Question
Title: Convert from hexadecimal to binary
I need to simulate a pulse train. Everything is in order with this code, it solves its problem. The question is: I need to change the keys, but it is too difficult to manually type in so many zeros and ones each time. On the other hand, I know that my hexadecimal key looks much shorter: "B8C4F9". Is it possible to create a string in such a way that the system itself translates to the binary system?

And the second question: How can you automatically measure the length of an array so as not to manually calculate KEY\_LEN?

```
const int KEY_LEN = 24;
const char key[KEY_LEN] = {"101110001100010011111001"};

int T = 200; // Pulse repetition period in microseconds
int Zero = 80; //0.4*T; // Duration of zero in microseconds
int One = 120; //0.6*T;// Duration of a unit in microseconds

const int LED_PIN = 13; // Used digital pin 13 of the arduino to connect the transmitter

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  for (int n = 0; n < KEY_LEN; n++)
  {
    if (key1[n] == '1') //If the bit read == 1
    {
      sendSignal(One);
    }

    else if (key1[n] == '0')//If the bit being read == 0
    {
      sendSignal(Zero);
    }
  }
}

void sendSignal(int duration)
{
  digitalWrite(LED_PIN, LOW);
  delayMicroseconds(duration);
  digitalWrite(LED_PIN, HIGH);
  delayMicroseconds(T - duration);
}

```

# Answer
There is really no reason to save the key as a string, as you are doing. You can just save it as a normal number. Then you can also use the hexadecimal representation on your code:

```
unsigned long key = 0xB8C4F9;

```

Then you need to send out each bit of that number:

```
for (int n = 0; n < KEY_LEN; n++)
{
    if (key & (1 << n)) { //If the bit read == 1
        sendSignal(One);
    } else {//If the bit being read == 0
        sendSignal(Zero);
    }
}

```

The following is happening in the if statement: `(1 << n)` will take the value 1 (binary `0b00000001`) and will shift the bits to the left by n digits. For example: If n is 2, we get `(0b00000001 << 2) = 0b00000100`. With this we can select a bit in our number. Then we take that and do a bitwise AND `&` with the key. That will set all bits to zero, which are not currently selected. The resulting number is zero, if the corresponding bit in `key` is zero. If the corresponding bit is 1, this will return a number different from zero (which is interpreted as `true`. Thus we check, if the n-th bit of `key` is one or zero.

> How can you automatically measure the length of an array so as not to manually calculate KEY\_LEN?

Generally you can calculate the size of an array with the `sizeof()` function:

```
unsigned int size_of_array = sizeof(array)/sizeof(array[0]);

```

`sizeof()` returns the number of bytes. So to get the number of elements, we need to divide by the number of bytes in each element;

For the way shown above this is not that easy. Normally it is not really needed, since such keys normally don't change length very often. If you find a variable type, which exactly fits your key size, you could use `sizeof(key)*8` to get the number of bits in it. But your current value `0xB8C4F9` only needs 3 bytes. I don't know a type with 3 bytes, but maybe somewhere you can get something like `uint24_t`. Honestly here I would just use a hardcoded size, just like you are using a hardcoded key value.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: WiFiManager - Combine NonBlocking portal AND addParameter
I wish to config `WiFiManager` and `addParameter` of MQTT topic and local server on its ConfigPortal.

Additionally in a case of a power outage or any, in case of losing WiFi, to continue in a `NonBlocking` way.

The problem is when combining both features in one sketch, I get some errors.

Entire code is ( please notice comments marked `Marker[i]` ):

```
#include <WiFiManager.h>
#define MQTT_SERVER "192.168.3.200"
WiFiManager wm;

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

  WiFiManagerParameter custom_mqtt_server("mqtt_server", "mqtt server", MQTT_SERVER, 40);
  WiFiManagerParameter custom_mqtt_user("mqtt_user", "mqtt user", "", 10);
  WiFiManagerParameter custom_mqtt_pwd("mqtt_pwd", "mqtt password", "", 10);
  WiFiManagerParameter custom_mqtt_topic("mqtt_topic", "mqtt topic", "", 10);
  WiFiManagerParameter custom_mqtt_group("mqtt_group", "mqtt group", "", 10);
  WiFiManagerParameter custom_mqtt_root("mqtt_root", "mqtt rootTopic", "", 10);
  wm.addParameter(&custom_mqtt_server);
  wm.addParameter(&custom_mqtt_user);
  wm.addParameter(&custom_mqtt_pwd);
  wm.addParameter(&custom_mqtt_topic);
  wm.addParameter(&custom_mqtt_group);
  wm.addParameter(&custom_mqtt_root);

  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
  //  wm.resetSettings();

  //  wm.setConfigPortalTimeout(180);
  // wm.setConfigPortalBlocking(false);  // <--- Marker [#1]

  //  if (!wm.autoConnect("AutoConnectAP")) {
  //    Serial.println("failed to connect and hit timeout");
  //    delay(3000);
  //    //reset and try again, or maybe put it to deep sleep
  //    ESP.restart();
  //    delay(5000);
  //  }

  bool res;
  res = wm.autoConnect("test123", "password"); // password protected ap
}

void loop() {
  // put your main code here, to run repeatedly:
  //  wm.process(); //<--- Marker [2]
  Serial.println("hi");
  delay(100);

}

```
1. When `Marker[1]` & `Marker[2]` are commented out ConfigPortal works as expected, and in `Blocked` state - meaning there is no `hi`'s on Serial monitor.
2. When only `Marker[2]` is commented out, ConfigPortal is reached, lacking all `addParameter` fields.
3. When `Marker[1]` & `Marker[2]` are not commented out, ConfigPortal is now reachable, but not having Non-Blocking feature...
4. What is the purpose of `wm.process()` ?

Guy

# Answer
> 2 votes
The WiFiManger's `autoConnect` function starts the configuration web server (and AP) only if connection to configured WiFi network is not established.

If you want to run the WiFiManger's web server to reconfigure WiFi or to set other parameters, you can start the WM web server with the `startConfigPortal` function.

`autoConnect` and `startConfigPortal` are blocking by default. The library has a loop inside this functions which runs until the web server is stopped calling \[Exit\] action on the configuration web page or the timeout set with `setConfigPortalTimeout` is reached after last contact from browser.

To run the WM web server 'parallel' to your sketch you can configure it as not blocking with `setConfigPortalBlocking(false)`. Then to allow WM handling of the web server the sketch must periodically call `wm.process()`.

In not blocking mode the \[Exit\] action on the configuration wen page doesn't stop the web server. The server must be stopped in code.

The parameter definitions must by global in sketch, if you want to run WiFiManager with parameters outside of setup(). Parameters local in setup() don't exist after setup() finishes. WiFiManager detects this and doesn't use the parameters.

The `OnDemandWebPortal` example and `OnDemandNonBlocking` example demonstrate `startConfigPortal` in blocking and not blocking use.

---
Tags: wifi
---


# Question
Title: Minimal example of Task Scheduler Blink?
Scheduler\_example00\_Blink is ~300 lines. For just an Arduino Uno, what is a minimal example?

It's hard to know what belongs and what doesn't. This example has six different approaches, and I'm just trying to extract one of them.

# Answer
```
#include <TaskScheduler.h>

// Scheduler
Scheduler ts;

/*
   Approach 1: LED is driven by the boolean variable; false = OFF, true = ON
*/
#define PERIOD1 500
#define DURATION 10000
void blink1CB(); // <-------------------------------------------|
Task tBlink1 ( PERIOD1 * TASK_MILLISECOND, DURATION / PERIOD1, &blink1CB, &ts        , true );
//           (     500 * 1UL (ms)        , 100000 ms/ 500    , function , just put it,  ?   )

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  ts.execute();
}

inline void LEDOn() {
  digitalWrite( LED_BUILTIN, HIGH );
}

inline void LEDOff() {
  digitalWrite( LED_BUILTIN, LOW );
}

// === 1 =======================================
bool LED_state = false;
void blink1CB()
{
  if ( LED_state )
  {
    LEDOff();
    LED_state = false;
  }
  else
  {
    LEDOn();
    LED_state = true;
  }
}

```
> 1 votes

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


# Question
Title: TimedAction.h: No such file or directory
I am new to Arduino and I am trying one of the library TimedAction.h for sudo multithreading on Arduino. However the library is not present in the Arduino. How do I install external library(if it is)?

# Answer
You can use three ways to install libraries in the Arduino IDE:

The probably easiest way is to go to **Sketch \> Include Library \> Manage Libraries**, (you can use *Ctrl+Shift+I* too) search for the library you want to install and click the install button. After that you need to include the library in your sketch with a `#include <LibraryName.h>`, or if you don't know the name, head again to **Sketch \> Include Library** and click on the library you want to include.

If a library is not in the Library Manager from step one, you have to download the `.zip` file, go to **Sketch \> Include Library \> Add .ZIP Library** and search for the file. You just have to do that once, and it will be moved to your library folder. Again, make sure to include the library into the sketch.

If you just have a single file, you can move it to the sketch folder and include it by using `#include "LibraryName.h"`, but you have to do it all over again for a new sketch, so I would recommend the other solutions if you can and want to use it permanently.
> 2 votes

---
Tags: arduino-uno, library
---