text:
Multiple if else statements for distance-triggered LEDs
I have a sketch that calculates simple distance from the device to the nearest preset GPS coordinate (there are 3 in total) and I would like to have LEDs in the neopixel strip light up according to the proximity of the location.
I managed to make it work with only one 5mm led and a simple if (shortestDist < 10) then digitalWrite(ledPin, HIGH); - else ledpin low. But I want to use a neopixel strip with 7 leds to light up according to various distance criteria.
In my attempt here, I tried to make specific leds light up when 50, 30 and 10m away but it doesn't work properly, and it's a pretty crude approach, as are my coding "skills" :D
I would also like some help on how to make some kind of shorthand for specific led strip setup depending on distance - for example at 50m distance, 2 leds red, 5 leds off, at 30m distance 5 leds red, 2 leds off and so on.
Hope someone can assist the newb :D Currently the leds don't all shut off when the distance is higher than 50.
void loop()
{

while (ss.available() > 0)
    gps.encode(ss.read());
if (gps.location.isUpdated())
{
    Serial.print(F("Lat Lon = "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(", ");
    Serial.println(gps.location.lng(), 6);
}
else if (millis() - last > 1000)
{
    Serial.println();
    if (gps.location.isValid())
    {
        double shortestDist;
        for (int i = 0; i < 3; ++i)
        {
            double distanceToDest =
                TinyGPSPlus::distanceBetween(
                    gps.location.lat(),
                    gps.location.lng(),
                    positions[i].lat,
                    positions[i].lon);
            if (!i || distanceToDest < shortestDist)
                shortestDist = distanceToDest;
        }
        Serial.print(F("Next in range = "));
        Serial.print(shortestDist, 2); // decimal
        Serial.println(" m");

        if (shortestDist < 50)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50);
        }

        else if (shortestDist < 30)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(250, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(250, 250, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50);
        }

        else if (shortestDist < 10)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(250, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(250, 0, 250));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 250, 0));
          pixels.setPixelColor(6, pixels.Color(250, 0, 0));
          pixels.show();
          delay(50);
        }

        else
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 0, 0));
          pixels.show();
          delay(50);
        }

    }
    if (gps.charsProcessed() < 10)
        Serial.println(F("No GPS data."));
    last = millis();
    Serial.println();
}

}

you have a logic error in your code ... else if (shortestDist < 10) will never execute ... think about what you are telling your program to do

I rearranged the "else if shortestDist" by going "if shortestDist biggest value", else if smaller value and it works, as far as I can see it behaves properly

then you did not post your real code... think about this ... which if statement will execute when shortestDist = 5 ?

put serial.print statements inside the if blocks for debugging purpose

@jsotola I don't know how to post full code here other than pastebin - https://pastebin.com/BWVjdr1S - this works and leds turn on and off as they should. Take a look if you have the time, let me know if there's a better way to format it, as you can pretty much tell I'm not very well versed at this :D

the code in the pastebin is different from the code in your question ... you already posted code in your question ... why would you say that you don't know how to post code?

Common inexpensive GPS modules are likely to report positions that appear to jump around by perhaps 5 meters in good conditions.  Many factors affect GPS accuracy and this uncertainty.  Some are listed here.  It might be problematic to implement a 10 meter distance threshold feature unless conditions are favorable.

Consider constraining your "if" tests more.  For example, use "if ((shortestDist <= 50) && (shortestDist > 30))" instead of "if (shortestDist < 50)".  Continue similarly with the other "if" tests.  Otherwise, once shorttestDist is less then 50 only the 1st "if" test is executed as it will become true and stay true and none of the other "it" tests will be considered.

Consider only using mills(). The posted code uses delay() & millis(). Calling delay() is fine but using millis() is almost always better. Mixing the 2, though, should be avoided.

The logic in the code might be incorrect. It appears GPS data is only process and the LEDs updated when GPS information is unavailable (not new).

When writing embedded firmware, always consider hardware problem sources. Many find small batteries problematic during momentary current demands.  Batteries with small Amp-Hour ratings are more prone to dropping their voltage during a high current events.  Such as when a processor operates a relay or activates a sensor.

Thank you for the input - I will use this with 10m increments on a RC boat, it's just a concept test and the RC moves so slow, it should be good. I can maybe try with 15m, I think it should be ok as I did the walking test and GPS coordinates on the street and was pretty satisfactory. One thing that I noticed with my current IF "solution" - the leds I call up on the strip in the specific IF criteria do light up, but they blink, and in rhythm, so it might be something with else if (millis() - last > 1000)

For the LEDs.  I would recommend creating a version of your code that changes the LED at a fixed & expected rate.  You need to separate out any unexpected GPS affects that may be leading you astray. For the GPS. To get an understanding of GPS noise in your setting (trees, buildings, location, weather, ect) log the data of a stationary GPS for a day.  This will give you a good idea of what you might expect and perhaps ideas as to how to mitigate any noise for your given application.

Going on, a few here will write code and post it. I feel that doesn't help as much as the O.P. figuring out the code for them selves. That said, here are a few items I noticed. You are using delay() & millis(). Calling delay() is fine but using millis() is almost always better. Mixing the 2, though, should be avoided. Your logic might be incorrect. It looks like you only process GPS info & update the LEDs when the GPS info is unavailable (not new). When writing embedded firmware, always consider HW problem sources. Many find small batteries problematic during momentary current demands.

I decided to add a few of these comments to the answer since it might help others who happen across this question / answer.


text:
Alternative to GPS location being calculated by radius around a point
Hopefully the thread title isn't confusing - I'm trying to find out how would it be possible to make a different way of proximity warning with GPS.
Default/simplest way is by forming a radius around a goal waypoint, so the proximity criteria will get triggered when you're "inside" the circle. I know about geofencing but that does seem very demanding and complex, so I'd like to ask if something like shown in this pic would be achievable.
So instead of proximity criteria being a radius around a waypoint, forming a circular geofence so to speak, would it be possible to create a half-circle like this, at a specific angle.

What are you trying to accomplish? I mean, I understand your question, but I'm curious as to why, simply because GPS isn't really all that accurate (however, I don't know how big your semicircle is).

Also, this isn't really an Arduino question, it's a geometry question.

Let

(x, y) be the Cartesian coordinates of the vector going from the
waypoint to your position

radius be the radius of the circle

theta be the orientation of the straight line, in radians.

You can then build a unit vector normal to the straight line:
n = (cos(θ+π/2), sin(θ+π/2)) = (−sin θ, cos θ)
You are on the colored side of the line if the scalar product of n
with (x, y) is positive.
In code:
bool is_inside(float x, float y)
{
    float product = - x * sin(theta) + y * cos(theta);
    float r2 = x * x + y * y;
    return r2 <= radius * radius && product >= 0;
}

Thank you so much for showing the way! But one thing crossed my mind, as I'm moving the "half circle geofence" should remain within the same angle, not relative to me but to some constant, I'm thinking "north"...which means this gets more complex and closer to actual vehicle navigation? Because one thing to make this work correctly as well, is to have the target destination have a reference "north" so that the geofence always faces the proper direction. Which makes me think, is it possible to assign such constant, and make this half geofence face in a destined compass derived direction?

@Varonne: If you want theta to be a constant, just keep it constant. There is no reason it should be more complex than this.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
ESP32 print weird data on Arduino IDE Serial Monitor
I tried to upload a sketch on esp32 devkit v1 (wroom) picture of my board is below :

but this message is always printed on the serial monitor continuously and quickly :
rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
ets Jun  8 2016 00:22:57
I tried multiple sketches and all of them successfully uploaded but always got same data printing in serial monitor as output
In the beginning, the shield on the board heats up a little, but after I made the following settings, it no longer heats up (i powered my board only by connecting it by simple USB cable from my laptop USB port) :
Board : ESP32 Dev Module
Upload Speed :115200
CPU Frequency : "240MHz(wifi/BT)
Flash Frequency : 80MHz
Flash Mode : QIO
Flash Size : 16MB(128Mb)
Partition Scheme : 16M Flash(3MB APP/9MB FATFS)
Core Debug Level : None
PSRAM : Enabled
Arduino IDE version : 1.8.9
ESP Core version : by Espressif Systems version 1.0.6
Is my board burnt due to the setting for maximum performance, and I shouldn't have made these settings for this board?  To adjust these parameters in a way that does not damage the board, how much should I adjust each parameter?
Any suggestions to fix it?
(Nothing connected to GPIO pins and also nothing connected to wifi & Bluetooth)
UPDATE :
If I set the board settings to default, the program will upload to the esp32 board, but I want to use the maximum performance of my board, so how high can I increase each setting?
(settings like cpu freq. Flash freq. and etc. )
How can i be sure of this?
Is there any sketch & instructions to find out how high can i select them?(it seems the board isn't Original and I'm not sure about it's specifications, how can i get this information by any sketch from it and then how high can i set the setting? )

Have you tried an empty sketch with nothing connected to the ESP32?

Is it possible to upload empty sketch on it? ( nothing connected to the board at all - answer deited by mentioning this)

an empty sketch is a sketch with only the functions setup() and loop() without anything in them

I know, i tried now and successfully uploaded but got same result

It seems this error can have many reasons. How are you powering the ESP? Do you use the latest ESP32 core in the Arduino IDE? What are your board settings when programming?

The question updated by the info you want (thanks for your help)

This looks like a very standard ESP32 Dev board, which usually have only 4MB of Flash and no PSRAM. Change the settings for "Flash Size" to 4MB, change the PSRAM setting to "disabled" and try again. You are also working with an old Arduino IDE version and ESP32 Core version.

What is the rest of setting? Are they right? (Frequencies, partition Scheme, ... ). do those settings work for this board?

setting changes done, still same problem

set 40MHz for the flash

"ESP Core version : by Espressif Systems version 1.0.6"  This seems to be latest the 1.x line, but we're up to 2.0.5 now overall. You may want to try with the current core. The IDE is also a little outdated, but if either make any difference at all, it would probably be the core version. May not matter at all, but it's an easy test and odds are anyone trying to help is on the newer core anyway.

I found the an issue . The question updated by new info. Check it out

if your flash memory chip can handle only 40 MHz then you can't set 80 MHz. if is connected as DIO then you can't set QIO. if the module has a 4 MB flash, you can't set 16 MB in Tools menu

The main question is, the board it's not Original and how can i be sure of these? And then what is the detailed instructions to set these board settings?

Simply use the defaults as they are usually fine. If your board runs with the defaults, you can try to change a setting and see if it has any effect. There usually is not much to gain performance wise. You can find out what most settings do by searching for them or looking them up in the ESP32 data sheet. For example here is a discussion about Flash modes which may be interesting.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
EspAsyncWebServer process HTTPS to HTTP
I read this issue. But I didn't understand it.
Like the author I don't have an SSL certificate and I don't want to have one (because if I had one I could live with HTTPS!).
I just want to process any https://<url> request like it was http://<url>. It can be a redirect but the answer states:
server.on("/redirect/internal", HTTP_GET, [](AsyncWebServerRequest *request){
  request->redirect("/hello");
});

server.on("/redirect/external", HTTP_GET, [](AsyncWebServerRequest *request){
  request->redirect("https://techtutorialsx.com/");
});

Ok, but how to detect if the request was HTTP or HTTPS?

the web browser will probably freak out if you redirect to an unsecure webpage

http uses port 80 ... https uses port 443

This isn't something you can do.
What you're asking for is like saying "I have to screw something together but I really only want to use a hammer, so how do I hammer the screw?". The answer is, you don't.
In this case the ESP32 is a server. The web browser is a client. The web browser is speaking HTTPS. When the browser makes an HTTPS request to the server, HTTPS is the only thing the browser will accept. HTTPS include a security layer (that's the "S" part) which is what requires certificates. If the server is not capable of handling that security layer (which it's not if it doesn't have an SSL certificate) then the only thing it can do is reject the connection by either not listening for it or immediately closing it
There is no communication between the client and server if the server isn't configured with certificates and can't speak TLS (the security layer) with the client. Allowing the server to downgrade the security when the client requests it would be a huge general security issue for the web. It's designed to not allow this.
Either support HTTPS properly, get the client to speak HTTP, or just don't do this at all. Those are your options.
As for detecting HTTP vs HTTPS, it depends on the port your server listened on. If you listen on port 80, you get HTTP requests. If you listen on port 443 you get HTTPS. If you're not listening on a port, the request of that type is refused (reset).

Ok got it. I thought it was easier because I saw some IoT devices that do this. Just a clarification: it's not a www application, it's just a configuration page hosted on an MCU device. No security issue here. And TLS is an overkill for this kind of job. Unfortunately, if you don't specify the protocol the browsers assume it's HTTPS and most users wonder why the page is not loaded...


text:
wemos d1 mini keeps resetting while using SIM800L
I am trying to do a small project with SIM800L with Wemos d1 mini. It is a DTMF based project. The problem here is, every time I make a call the d1 mini is getting reset. This is my first project with d1 mini. For the past few days I have googled, trying to find a solution. But I failed. I will be very grateful if you can provide the solution.
I am getting these errors in the serial monitor:
 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x4010f000, len 3460, room 16
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4
tail 4
chksum 0xc9
csum 0xc9
v00043b40
~ld

I am using Arduino IDE. Version: 1.8.8
Here is my project code.
#include <SoftwareSerial.h>

#define rxPin D3
#define txPin D4
SoftwareSerial sim800L(rxPin, txPin);

#define RELAY_1 D7
#define RELAY_2 D8
boolean relay1_state = false;
boolean relay2_state = false;

//stores incomming data from sim800l
String buff;
String dtmf_cmd;
boolean is_call = false;
String ownerNumber = "xxxxxxxxxxxxxxx";

void setup()
{
  pinMode(RELAY_1, OUTPUT);
  pinMode(RELAY_2, OUTPUT);

  //Begin serial communication with (Serial Monitor)
  Serial.begin(115200);

  //Begin serial communication with (SIM800L)
  sim800L.begin(9600);
  Serial.println("Begin serial communication with (SIM800L)");
  delay(500);

  sim800L.println("AT"); //send AT
  delay(500);

  sim800L.println("AT+DDET=1"); //Enable DTMF
  delay(500);

  sim800L.println("AT+CLIP=1"); // Enable CallerID
  delay(500);
}

void loop()
{
  while (sim800L.available()) {
    buff = sim800L.readString();
    Serial.println("Raw: " + buff);

    if (is_call == true) {
      if (int index = buff.indexOf("+DTMF:") > -1 ) {
        index = buff.indexOf(":");
        dtmf_cmd = buff.substring(index + 1, buff.length());
        dtmf_cmd.trim();
        Serial.println("dtmf_cmd: " + dtmf_cmd);
        doAction();
      }
      if (buff.indexOf("NO CARRIER") > -1) {
        sim800L.println("ATH");
        is_call = false;
      }
    }
    if (buff.indexOf("RING") > -1) {

      // Now check the caller number
      if (buff.indexOf("+CLIP:")) {
        unsigned int index, index1;

        index = buff.indexOf("\"");
        index1 = buff.indexOf("\"", index + 1);

        String temp = buff.substring(index + 2, index1);
        temp.trim();

        if (ownerNumber == "+" + temp) {
          Serial.println("Number matched");
          delay(2000);
          sim800L.println("ATA");
          is_call = true;
        } else {
          Serial.println("Number not matched");
        }
      }
    }
  }

  while (Serial.available())  {
    sim800L.println(Serial.readString());
  }
}

void doAction() {
  if (dtmf_cmd == "1") {
    relay1_state = !relay1_state;
    digitalWrite(RELAY_1, relay1_state);
    if (relay1_state == true)
    {
      Serial.println("Relay 1 has been ON");
    }
    else
    {
      Serial.println("Relay 1 has been OFF");
    }
  }
  else if (dtmf_cmd == "2") {
    relay2_state = !relay2_state;
    digitalWrite(RELAY_2, relay2_state);
    if (relay2_state == true)
    {
      Serial.println("Relay 2 has been ON");
    }
    else
    {
      Serial.println("Relay 2 has been OFF");
    }
  }
}

rst cause:4, is a watchdog reset. Add yield() inside your loop() to allow "breathing" at each loop.

I tried, nothing changed.


text:
Best way to "hack" a library without forking it
I'm using Visual Studio Code and PlatformIO.
I added some libraries to my project using platformio.ini:
lib_deps =
    olikraus/U8g2@^2.34.4
    crankyoldgit/IRremoteESP8266@^2.8.4
    plerup/EspSoftwareSerial@^6.16.1
    rlogiacco/CircularBuffer@^1.3.3
    https://github.com/me-no-dev/ESPAsyncWebServer.git
    makuna/NeoPixelBus@^2.7.0
    adafruit/Adafruit BusIO@^1.13.2
    bblanchon/ArduinoJson@^6.19.4
    adafruit/Adafruit PN532@^1.2.2
    khoih-prog/ESPAsync_WiFiManager@^1.15.1
    https://github.com/guestisp/ESP32AsyncDNSServer.git

Now, let's say I have to "hack" few lines of code inside a library to fit my needs.
Since it's a very specific change (not something that can be useful to others) I can easily change directly the source code without forking it on github.
The downside is every time I download again the libraries (or set up another dev machine) I lose all my changes.
I can also move the downloaded library to the lib/ subfolder in the project tree, removing the dependency from lib_deps.
I wonder if there is a more reliable way to do this, i.e. applying a patch after downloading the code (yocto-like).

Use a local source control and repository of your choice. Obtain the latest published rev of the library and make your changes to it (I assume you have already done this, probably a number of times). Check in your changed revision of the library to your local repository. When a new rev becomes available, obtain it and merge it into your local repository.
Update:

One problem of this approach is I will end up with nested
repositories.

I'm coming from old-school source control - file management. rcs, in my case (don't laugh). I'm guessing your local modifications affect only one or a few of the library files. Mightn't something that simple - a file-level merge - solve your issue (regardless of which tool you choose to do it)?

One problem of this approach is I will end up with nested repositories. My project directory is already a git repository. If I clone the library repository inside, say, the lib folder it won't pushed inside mine since it's nested. At least, I was not able to do this.

@Mark: You may clone the library outside of your project's directory, commit your changes there in a dedicated branch, and then include it into your project as a git submodule. Alternatively, you may consider using a git subtree.

@EdgarBonet yep, git subtree did the trick (and for me is the actual solution to my question). I only knew git submodules that are tricky for this kind of scenario.


text:
Multiple unique I2C devices interfere
I'm trying to make a fairly simple program that interfaces with the Adafruit TSL2591 light sensor as well as a MAX30102 pulse oximeter. They both use I2C for communication. I'm using the recommended libraries for both, Adafruit_TSL2591_Library Version 1.4.3 and SparkFun_MAX3010x_Sensor_Library Version 1.1.2 respectively. This is all running on an Arduino UNO, although I will be transferring it to a NANO in the near future. All of the following is using Version 2.0.2 of the Arduino IDE.
The issue I'm running into is that both sensors will work perfectly fine in isolation, but when trying to run at the same time it locks up and outputs nothing.
Example code that works for the Light sensor.
Example code that works for the pulse oximeter.
I know my wiring is good because the sensors work individually with either program even when both sensors are plugged in simultaneously.
The code that almost works:
#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

MAX30105 particleSensor;

const byte LUX_ADDR = 0x29;
const byte OX_ADDR = 0x57;

Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);

#define MAX_BRIGHTNESS 255

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format
//To solve this problem, 16-bit MSB of the sampled data will be truncated. Samples become 16-bit data.
uint16_t irBuffer[100]; //infrared LED sensor data
uint16_t redBuffer[100];  //red LED sensor data
#else
uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100];  //red LED sensor data
#endif

int32_t bufferLength; //data length
int32_t spo2; //SPO2 value
int8_t validSPO2; //indicator to show if the SPO2 calculation is valid
int32_t heartRate; //heart rate value
int8_t validHeartRate; //indicator to show if the heart rate calculation is valid

void setup()
{
  Serial.begin(115200); // initialize serial communication at 115200 bits per second:

  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST, OX_ADDR)) //Use default I2C port, 400kHz speed
  {
    Serial.println(F("MAX30105 was not found. Please check wiring/power."));
    while (1);
  }

  byte ledBrightness = 60; //Options: 0=Off to 255=50mA
  byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
  byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
  byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 411; //Options: 69, 118, 215, 411
  int adcRange = 4096; //Options: 2048, 4096, 8192, 16384

  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings

  light_sensor_details();

  light_sensor_configure();

}

void loop()
{
  bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps

  //read the first 100 samples, and determine the signal range
  for (byte i = 0 ; i < bufferLength ; i++)
  {
    while (particleSensor.available() == false) //do we have new data?
      particleSensor.check(); //Check the sensor for new data

    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();
    particleSensor.nextSample(); //We're finished with this sample so move to next sample

    Serial.print(F("red="));
    Serial.print(redBuffer[i], DEC);
    Serial.print(F(", ir="));
    Serial.println(irBuffer[i], DEC);
  }

  //calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)
  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  //Continuously taking samples from MAX30102.  Heart rate and SpO2 are calculated every 1 second
  while (1)
  {
    //dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
    for (byte i = 25; i < 100; i++)
    {
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }

    //take 25 sets of samples before calculating the heart rate.
    for (byte i = 75; i < 100; i++)
    {
      while (particleSensor.available() == false) //do we have new data?
        particleSensor.check(); //Check the sensor for new data

      redBuffer[i] = particleSensor.getRed();
      irBuffer[i] = particleSensor.getIR();
      particleSensor.nextSample(); //We're finished with this sample so move to next sample

      //send samples and calculation result to terminal program through UART
      Serial.print(F("red="));
      Serial.print(redBuffer[i], DEC);
      Serial.print(F(", ir="));
      Serial.print(irBuffer[i], DEC);

      Serial.print(F(", HR="));
      Serial.print(heartRate, DEC);

      Serial.print(F(", HRvalid="));
      Serial.print(validHeartRate, DEC);

      Serial.print(F(", SPO2="));
      Serial.print(spo2, DEC);

      Serial.print(F(", SPO2Valid="));
      Serial.println(validSPO2, DEC);
    }

    //After gathering 25 new samples recalculate HR and SP02
    maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

    light_sensor_read();

  }
}

void light_sensor_details () {

  sensor_t sensor;
  tsl.getSensor(&sensor);

  delay(500);

}

void light_sensor_configure () {

  delay(200);
  tsl.setGain(TSL2591_GAIN_MED);
  delay(200);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
  delay(200);
  tsl2591Gain_t gain = tsl.getGain();

}

void light_sensor_read() {

  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;

  Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 6);
}

The pulse oximeter part will function correctly with the last two lines of setup() and the last line of loop() commented. light_sensor_details();,light_sensor_configure(); and light_sensor_read(); respectively. The output with these two lines commented is as follows:
red=4229, ir=3967
red=4530, ir=3790
red=3629, ir=4104
red=3563, ir=5211
red=4555, ir=9076
red=7091, ir=16753
red=13068, ir=23695
red=10753, ir=11273
...
red=31031, ir=48271, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31044, ir=48283, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31017, ir=48289, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31027, ir=48306, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31022, ir=48291, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=31016, ir=48271, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30997, ir=48294, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30981, ir=48268, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30966, ir=48289, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
red=30981, ir=48293, HR=-999, HRvalid=0, SPO2=-999, SPO2Valid=0
...

(An expected output given my finger wasn't on the sensor for this.)
If I uncomment the 2nd last line of setup() then it still manages to show the red and ir values but never starts to show the calculated values. Instead it will occasionally (unpredictably) show chunks of invalid characters, like so:

Going further and uncommenting the other two lines simply locks up and prints nothing to the serial monitor.
Also to clarify the three light sensor related functions do work in their own file, I'll include it here for the sake of completeness:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);

void setup()
{
  Serial.begin(115200); // initialize serial communication at 115200 bits per second:

  light_sensor_details();
  light_sensor_configure();
}

void loop()
{
  light_sensor_read();
}

void light_sensor_details () {

  sensor_t sensor;
  tsl.getSensor(&sensor);

  delay(500);

}

void light_sensor_configure () {

  tsl.setGain(TSL2591_GAIN_MED);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);

  tsl2591Gain_t gain = tsl.getGain();

}

void light_sensor_read() {

  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;

  Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 6);
}

Running this outputs:
...
Lux: 41.283641
Lux: 36.879783
Lux: 10.549278
Lux: 2.826355
Lux: 11.158865
Lux: 1.489472
Lux: 1.713600
Lux: 31.461915
Lux: 48.357471
Lux: 50.827312
...

I think the issue is something to do with the I2C bus, but because both sensors use their own libraries for communication I can't use the online examples for manually starting and stopping communication with the Wire library. I can't find anyone else online with this issue or any examples of multiple I2C devices that I'm able to make use of (to my understanding).
Am I on the right track with it being an I2C problem? Is there a simple fix that I'm simply unaware of? Or is there a separate issue with my code?
Many thanks for any help!
Edit: Changed Title

It turns out the issue was with limited dynamic memory. The MAX30105 requires a lot of space for its calculations and adding anything else, whether that be another sensor or even a software serial connection, would crash it. Even using Serial.println() put it over the edge. It became unstable beyond around 89% full, or about 250 bytes of empty dynamic memory.
I ended up using a 32u4 equipped board to solve the memory issue and it worked perfectly after that.
It had nothing to do with I2C.


text:
Driving APA102C strips from Mega 2560
I have written (cobbled together from code snippets) an Arduino program that pushes various patterns down 160 APA102C LED strips (5). I originally was using a 5V 40A power supply and everything worked peachy. That was when the length from the clock and data pins was maybe 6-8 inches. Now I am try to get ready for a XMAS parade and attaching 100 LED strips. I have the power but the data and clock pins aren't getting to the strips. Is there some quick and dirty (not a real electronics guy here, just a code pusher) method to get signals out to the strips, maybe 6 feet? I would greatly appreciate any help I could get and I'm sure the kiddies would have Santa throw some extra goodies your way if I could get this figured out. I've got like 10 days.....YIKES!!!!
Thanks so much!!!!
And Happy Holidays
Joe B

For a quick and dirty way you could cut a few LEDs from your strip, so that you have a number of single LEDs. Then you can place one LED after X feet of cable. Each LED receives its own data and outputs the signal for the next LED. So the signal after an LED is of the same quality as of the first signal. At least that is what can be done with other similar RGB LED strips. I would bet, that this is also the case for this type.
Before wiring everything up you should probably experiment a bit with the cable length. Test how long you can make the cable until you see problems. Then make the cables inbetween the LEDs shorter than that.
If you don't want these intermediate LEDs to light up, you can set them to off in your program.
Another - not so quick and dirty - way would be to put one microcontroller near the start of each cluster of strips (where one or multiple or all strips start) and let them communicate with a master microcontroller using an interface for longer distances (like RS485).
Depending on your situation the quick and dirty method might be enough.

Well then again  there is always having a FAULTY strip!!!. I was working on the base code and hardware configuration and never thought to try one of the other strips (I do after all have 5 of them). I just happened to grab one of the other strips and BOOM, all was well. At least to a point. It looks like I can run 3 or 4 strips at the same time from one Arduino (Mega 2560) if I crank the brightness factor down and limit the strips to 120 LEDs. Since this is a nighttime parade. I'll still be bright enough. I just HATE cutting the extra 40 LEDS off the strip.

At one point I was looking at using multiple Arduino Unos. Problem is they're the cheapo chinese ones with the 240 chips and I have a hell of a time communicating with them. Was going to use fiber optic (which I also play around with) and use them to communicate with each other. THANKS SO MUCH FOR THE RESPONSE!!!!! Of the 5 boards I posted to yours was the only answer I got. On top of all this silliness I also got a granddaughter on Monday afternoon. Now all I need are my new soldering tips.... THANKS AGAIN, Best of the Holidays to you and your family, STAY SAFE

@joebataz Why do you need to crank the brightness down? Are you providing the strips with power through the Arduino? If yes, then DON'T! You can easily burn the voltage regulator or the protection diode. Instead connect the strips power lines directly to the power supply (not through the Arduino). The Arduino can be connected in parallel.

Hey Chris,
I have MASSIVE power supplies 40A at 5V unfortunately my vehicle which has a 110V outlet only puts out about 2.5A so I am running the strips thru a 5V 5A supply. I got 3 strips (160 LEDs) running at acceptable brightness. The Arduino itself barely will power 1 strip, found that out years ago when I was developing the system. Here is what the strips look like at 200 LEDs per strip. I was a DJ/VJ until I got hurt.
https://www.youtube.com/watch?v=g7qDTtEqrSI
Video was shot in my very small office. Much more impressive in a club environment. Thanks again, Joe B

Ah ok, just wanted to be sure. You can also use the big power supply. The important measure here is power in Watts. 40A at 5V are 200W (current multiplied by voltage). 2.5A at 110V is 275W, so enough for your big power supply with some headroom for losses


text:
Arduino code works when connected to laptop, not when connected to battery or wall socket
So I have an Arduino nano, and I am using two SG90 servos, and 1 BMP280, and 1 MPU6050. My code works fine when I plug my nano into my computer, but when I connect the battery to my nano, it doesn't run. The servo moves to 90 degrees, but it seems that it is not detecting the sensor data and not moving the servo. I commented out all calls to Serial.
Here is my code:
/***************************************************************************
  This is a library for the BMP280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BMP280 Breakout
  ----> http://www.adafruit.com/products/2651

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>

// MPU
#include <MPU6050.h>

// Servo
#include <Servo.h>

Servo servoY;
Servo servoX;

MPU6050 mpu;

// Timers
unsigned long timer = 0;
float timeStep = 0.01;

// Pitch, Roll and Yaw values
float pitch = 0;
float roll = 0;
float yaw = 0;

#define BMP_SCK  (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS   (10)

Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);

void pitch_roll_yaw(){
  // Serial.print("Pitch: ");
  // Serial.println(pitch);

  // Serial.print("Roll: ");
  // Serial.println(roll);

  // Serial.print("Yaw: ");
  // Serial.println(yaw);
  int thsjsojf = 1;
}

void setup() {
  // Servo
  servoY.attach(8);
  servoY.write(90);

  servoX.attach(9);
  servoX.write(90);

  // Serial.begin(115200);
  // while ( !Serial ) delay(100);   // wait for native usb
  // Serial.println(F("BMP280 test"));
  unsigned status;
  //status = bmp.begin(BMP280_ADDRESS_ALT, BMP280_CHIPID);
  status = bmp.begin();
  if (!status) {
    // Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "
    //                   "try a different address!"));
    // Serial.print("SensorID was: 0x"); Serial.println(bmp.sensorID(),16);
    // Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
    // Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
    // Serial.print("        ID of 0x60 represents a BME 280.\n");
    // Serial.print("        ID of 0x61 represents a BME 680.\n");
    while (1) delay(10);
  }

  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

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

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

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

}

int incrementPitch = 0;
int curAngle = 90;
int incrementPitchDown = 0;

void loop() {
    timer = millis();
    // Read normalized values
    Vector norm = mpu.readNormalizeGyro();

    // Calculate Pitch, Roll and Yaw
    pitch = pitch + norm.YAxis * timeStep;
    roll = roll + norm.XAxis * timeStep;
    yaw = yaw + norm.ZAxis * timeStep;

    float normalY = norm.YAxis;

    // Serial.print(F("Temperature = "));
    // Serial.print(bmp.readTemperature());
    // Serial.println(" *C");

    // Serial.print(F("Pressure = "));
    // Serial.print(bmp.readPressure());
    // Serial.println(" Pa");

    // Serial.print(F("Approx altitude = "));
    // Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */
    // Serial.println(" m");

    // pitch_roll_yaw();

    //TODO: This works, but if pitch > 1 and the servo arm is already at max, it doesn't move. Fix.
    // TODO: If pitch < 1. move the servo in the opposite way by 5 degrees. Need to track current angle.
    if(pitch>1){
      // Serial.println("PITCH IS GREATER++++++THAN 1, MOVING Y SERVO");
      servoY.write(curAngle+incrementPitch);
      curAngle = curAngle+incrementPitch;
      // Serial.print("Pitch: ");Serial.println(pitch);
      if(curAngle>180){
        // This is just so we don't print the current angle if curAngle > 180. This can be antything.
        int something = 1;
      } else {
        // Serial.print("Current Angle of Y servo: ");Serial.println(curAngle);
      }
      incrementPitch+=6;
    } else if(pitch<-1){
      // TODO: If pitch is < -1, then we move the servo in 5 degree increments starting at the current angle. Right now it jumps some degrees, check the if(pitch>1) for errors? MUST FIX.
      // Serial.println("Pitch is LESS---------THAN 1, MOVING Y SERVO");
      servoY.write(curAngle-incrementPitchDown);
      curAngle = curAngle-incrementPitchDown;
      incrementPitchDown+=6;
    }

    // Serial.println();
    delay(200);
}

ALso, none of the other threads solve my problems.

what battery are you using?

@jsotola a 9v battery

do you mean a standard 9 V block battery like these? ... https://duckduckgo.com/?q=9v+battery&iax=images&ia=images

@jsotola yes precisely

those are for powering low current devices like smoke alarms ... it is surprising that there is enough current to move the servo even once

So, what should I use to power it? I am using my Arduino in a model rocket so it can't be too heavy.

the 9 V battery contains six AAAA cells in series ... try six AA cells for testing ... you may have to choose another battery chemistry for higher power density

How long should the circuit work? It's not the capacity, but the current that's limiting you. -- You could look for a rechargeable battery like NiMH or LiIon. Make sure you read the data sheet and check that it can deliver enough current. Of course you need to find the required current, by measuring or reading the data sheets of your Arduino and the other parts like the servo.

If are you powering the servo's via your Nano (and thus the USB port), this will cause problems. The Servo's need need 500/700 mA each (>1 Amp total). My laptop USB is 500mA, so rotating two servo's will cause a power drop (voltage goes down due the draw of current).
in my experience using servo's when connected to a computer/laptop is not reliable. This will happen: the servo rotates, the power drops causing the Microcontroller to restart or cause problems (voltage) for the  sensor.

So how will I power them?

connect an external 5v supply tot the servo's (PowerBank/USB charger/5V LED driver/anything 5V). Connect this power supply to the GND of Servo's AND the board (important!).
Connect the board to the laptop via USB (now the board is powered by your laptop and the servo's via an external supply).
Upload code and test


text:
How do I put a LiquidCrystal_I2C class in a Lcd class?
I want to make my main code cleaner so I was thinking of making a Lcd class which I can use every time I need to print on lcd. So my main code every time I try to print text I need to call :
lcd.clear();
lcd.setCursor(1,0);
lcd.print("Text 1st line");
lcd.setCursor(1,0);
lcd.print("Text 2nd line");

The problem is I need to create a class called Lcd which initialises the LCD display through LiquidCrystal_I2C.h and calls it's functions in order to print as I want.
Below I will post some code which is totally wrong but I guess it can give you the idea of what I am trying to do:
LcdControl.hpp
class LcdControl{
    public:
        LcdControl();
        void printOnLcd(int data,int column,int line);
        void printOnLcd(char data,int column,int line);
};

LcdControl.cpp
#include <LiquidCrystal_I2C.h>
#include <Arduino.h>
#include "LcdControl.hpp"

LcdControl::LcdControl(){
    LiquidCrystal_I2C lcd(0x27,20,4);
    lcd.init();
    lcd.init();
    lcd.backlight();
}

void LcdControl::printOnLcd(int data,int column,int line){
    lcd.clear();
    lcd.setCursor(column,line);
    lcd.print(data);
}

void LcdControl::printOnLcd(char data,int column,int line){
    lcd.clear();
    lcd.setCursor(column,line);
    lcd.print(data);
}

You could also use an inheritance model where the the base class is the original library LiquidCrystal_I2C and you simply create a new derived class, in this case LcdControl. In LcdControl, you simply pack in your additional methods. The only slight complexity is that you have to invoke the constructor of the base class LiquidCrystal_I2C when the constructor of the derived class LcdControl is called.
Here it is in a simulation:  https://wokwi.com/projects/349238619253244498
Code:
#include <LiquidCrystal_I2C.h>

class LcdControl : public LiquidCrystal_I2C {
  public:

    LcdControl( uint8_t lcd_Addr, uint8_t lcd_cols, uint8_t lcd_rows) :
      // base class constructor
      LiquidCrystal_I2C ( lcd_Addr, lcd_cols, lcd_rows ) {
    }

    void printOnLcd(const char * data, int column, int line) {
      LcdControl::clear();
      LcdControl::setCursor(column, line);
      LcdControl::print(data);
    }

} ;

LcdControl lcd(0x27, 20, 4);

void setup() {

  Wire.begin() ;
  lcd.init() ;
  lcd.backlight();

  lcd.printOnLcd( "hello world2", 0 , 0 ) ;
  delay(1000) ;

  lcd.printOnLcd( "hello world3", 1 , 2 ) ;

}

void loop() {

}

Potentially, your lcd local of the constructor becomes member instead:
class LcdControl{
    public:
        LcdControl();
    // ...
    private:
        LiquidCrystal_I2C lcd;

There it is accessible from all of your member functions and (without splitting hairs) exists for the lifetime of LcdControl variable. The way you have it currently the lcd instance is local to the constructor, so inaccessible elsewhere (e.g. inside printOnLcd()) and dies when the constructor returns.
The construction of the lcd member happens in the LcdControl() member initializer list:
LcdControl::LcdControl()
    : lcd(0x27,20,4)
{

Newer standards of C++ allow some forms of initialization to be done where it's declared as member. I'm not going to recheck the standards now. But the above way should work regardless of which Arduino core and version you have.
The call to the lcd's init() may need to be done in an counterpart init()/begin() in your own class. When you do something that can fail in the constructor you have little opportunity to detect/handle this when done in the constructor on an embedded device like an Arduino where your class may be to make a global and where exceptions aren't supported; some Arduino's support exceptions and some don't. For an Arduino fallible part of initialization/contruction of often separated out so you can control how and where/when that failure happen, often in setup() and without reliance on exceptions.
There are a lot of ways to achieve something similar. The above seems closest to what you're attempting in the question. It may not necessarily make the most sense in your particular usage. You can want to have the class have a member pointer or member reference instead of a member instance, but you need to be more careful about their respective lifetimes. It is often a mistake to do initialization in inner layers of your code without providing the user of it any control. E.g. not allowing the user of your LcdControl class to initialize it's own LiquidCrystal_I2C instance and pass that in or to allow passing in the parameters for the LcdControl class to use.


text:
3.5mm jack frequency response at low frequency (20Hz)
I'm trying to drive a bass shaker at low frequencies, down to 20Hz, with an Arduino. Has anyone ever done something like this?
I found an audio amp that takes in 3.5mm aux, and I was hoping to get a 3.5mm jack to drive the amp from an Arduino. However, I can't find any technical specs on audio jacks so I am not sure if they support low frequencies. Are there any audio jacks with frequency response data available?
If not, are there other ways to achieve this?

why the doubt? how did you get the idea that it would be a problem?

I have read that using aux to feed subwoofers is not recommended since many audio devices filter out low frequencies on aux outputs

but that is not a property of the jack, but a property of the amplifier. so the answer doesn't help you at all

You can send DC (i.e. 0 Hz) through an audio jack, so I would not worry about its low-frequency response.

OP meant a jack input of the amplifier, not the connector itself


text:
Atmega32u4: Reduce power consumption while keeping USB active
I have a USB powered board, that should consume as little power when idle as possible, while keeping the USB connection alive.
The device only sends data to the host, doesn't receive any, so the connection itself doesn't necessarily have to be working while idle, but the host needs to be able to see the device as connected. So the device should never disconnect.
I can set the Atmega32u4 to idle mode while keeping the USB connection up, but the power consumption is really high (hardly lower than when active). I disabled all the peripherals I can disable in idle mode, but it didn't change much.
As soon as I enter any other sleep mode (power down, stand-by or ADC noise reduction) the connection is lost and the host can't see the device any more, even though the documentation says, that in ADC noise reduction mode, the USB clock stays active, and in power down/stand by, asynchronous USB interrupts should keep working.
Is there anything else I can do to reduce power consumption?
Is there anything I need to do to use power down, stand-by or ADC noise reduction modes while keeping the USB connection alive?

How do you put the MCU into sleep mode? Isn't it waked after a millisecond or so by the timer interrupt?

I am currently using this library: https://github.com/LowPowerLab/LowPower . I figured out, that I made a mistake, and now I can use ADC noise reduction mode. But the change isn't very high. If I drop it down using power-down/standby, the power consumption is reduced to next-to-nothing, but the USB connection is lost. It is woken by the WDT, afaik, and I let it wake up after 256ms. It is than awake for <1ms before sleeping again.

Is there a way to put it into power-down/standby without loosing the USB connection? That would be perfect.

Are you calling idle() with ADC_OFF, TIMER4_OFF... and everything else OFF? Try measuring the current draw with both USB_OFF and USB_ON: this will tell you whether it's the USB peripheral itself that is drawing too much current. You can also check the datasheet to see if there are other peripherals not taken care of by the library, which you could disable with the power_*_disable() function from the avr-libc.

@EdgarBonet Very interesting: USB_OFF reduces the power consumption significantly (even lower than ADC noise reduction mode), while keeping USB alive. I am still well above the current usage that I get in powerdown mode, but that's a significant improvement already. This leads me to think that powerdown should be possible, but that I need to somehow need to add interrupts or something for USB to correctly react to SUSPI/WAKEUPI while in powerdown mode.

Thanks a lot for the list of peripherals, I will cross-check than!


text:
Fubarino (microchip pic32mx), Second timer interrupt is not firing
volatile uint32_t counter_timer = 0;
void __USER_ISR myISR() {
  counter_timer++;
  clearIntFlag(_TIMER_3_IRQ);
}

void __USER_ISR myISR_timer_four() {
  clearIntFlag(_TIMER_4_IRQ);
  TMR4 = 0x16E3600;
  Serial.print("hi\n");
    if(PORTAbits.RA10 != 1){
      LATAbits.LATA10 = 1;
    }
    else{
      LATAbits.LATA10 = 0;
    }
}

void setup{

  T3CONbits.TCS = 0b0; // Timer Clock Source Select bit
  T3CONbits.TCKPS = 0b000; //0b111; // Timer Input Clock Prescale Select bits
  T3CONbits.ON = 0b1; //0;//0b1;
  asm("nop \n");

  T4CONbits.TCS = 0b0;
  T4CONbits.TCKPS = 0b000;
  T4CONbits.T32 = 0b1;
  TMR4 = 0x16E3600; // half of 48mHz.
  T4CONbits.ON = 0b1;

  setIntVector(_TIMER_3_VECTOR, myISR);
  setIntPriority(_TIMER_3_VECTOR, 4, 0);
  clearIntFlag(_TIMER_3_IRQ);
  setIntEnable(_TIMER_3_IRQ);

  setIntVector(_TIMER_4_VECTOR, myISR_timer_four);
  setIntPriority(_TIMER_4_VECTOR, 1, 0);
  clearIntFlag(_TIMER_4_IRQ);
  setIntEnable(_TIMER_4_IRQ);

 TRISAbits.TRISA10 = 0;  // Fubarino onboard yellow led
}

void loop() {
delay(500);
Serial.println(counter_timer);
Serial.println(TMR4, DEC);
}

Hi,
i wanna use multiple interrupts, i got the information from a document i got from: Majenko Technologies.
the interrupt bound to Timer3 works, this was the example code in the pdf.
now i "assembled" a second interrupt bound to timer4, copy, paste and adapt, but that isn't working.
i can print the "content" of the timer4 register and it's running.
have i done something wrong?
search engine didn't yield a answer.

The problem was that you need to combine the even and the next odd timer (see datasheet of the microchip pic you're using) to form a 32 bit timer.


text:
Simple FastLED sketch that crashes when led strip is long but not when its shorter
I have a pretty simple sketch that crashes, and crashes hard (Platform.io console says "Disconnected (read failed: [Errno 6] Device not configured)" and I need to power off/on the Arduino to continue.
The sketch does not crash and seems to work fine when I use a smaller number of LEDS but crashes after a few seconds when I use a longer number of LEDS.  Seems like a strange hardware issue because the sketch looks simple! I have added a lot of Serial.print(ln)'s to verify it is doing what I think it is, and it does... until the crash!
This will run forever, but if I change cNumLeds from 60 to 160 it crashes (and my actual LED strip has 300 LEDs and I use all of them in other sketches).
#include <Arduino.h>
#include <FastLED.h>

const uint16_t cDataPin = 15;
const uint16_t cNumLeds = 60;

CRGB leds[cNumLeds];

void setup() {
   Serial.begin(9600);
   FastLED.addLeds<WS2812B, cDataPin, GRB>(leds, cNumLeds).setCorrection(TypicalLEDStrip).setDither(true);
   FastLED.setBrightness(127);
   FastLED.clear();
   FastLED.show();
   FastLED.delay(100);
}

uint16_t offset = 0;
CRGB colors[] = {CRGB::White, CRGB::Red, CRGB::White, CRGB::Green, CRGB::White, CRGB::Black};
byte numColors = sizeof(colors)/sizeof(colors[0]);
uint32_t cycle = 75;

void loop() {
  EVERY_N_MILLISECONDS(cycle) {
    for (uint16_t i = 0; i < cNumLeds; i++) {
        leds[i] = colors[(i + offset) % numColors];
    }
    offset = (1 + offset) % cNumLeds;
  }
  FastLED.show();
}

Any tips for debugging greatly appreciated ! (And apologies in advance for my C++ style, I am a confirmed C programmer trying not to do any damage in C++)

How are you powering the LED strip? Sounds like either your power supply is not strong enough or you are providing power through the Arduino

Yes @chrisl, guilty as charged, powering from the 5V Arduino pin. I guess that's what the extra red and black wire on the strip are for : ) TIme to learn soldering, I guess.

But i have run other sketches, much more complex, on the whole of the 300 led strip, so not sure I get why this sketch is having a power issue.

powering from the 5V Arduino pin.

You should not do this. You can fry the voltage regulator or the protection diode doing this (depending on how you supply the power).
When you draw more current from a power source than it can supply, first the voltage will drop. If the voltage drops enough the Arduino will brown out and reset as soon as the voltage is up again. If you keep drawing that much power, you can fry parts of the power source (in this case your Arduino). Sometimes this is reversible, when the power source has some kind of emergency shutdown (like the voltage regulator of a genuine Arduino Uno). Otherwise it will get destroyed.
When controlling power hungry devices like LED strips you should connect their power lines directly to your power supply (given it has the correct voltage). That way the current doesn't have to flow through the Arduino. Also you need a power supply, that can handle your peak current. The RGB strips with WS2812 drivers can draw up to 60mA per LED (on white in full brightness). So for a strip with 160 of them it would be a current of 60mA * 160 = 9.6A. Add a little headroom and you would need a power supply, that can at least provide 10A of current.

But i have run other sketches, much more complex, on the whole of the 300 led strip, so not sure I get why this sketch is having a power issue.

We haven't seen your previous sketches. But most likely you had a lower current, because you didn't light up all LEDs at once and/or only at lower brightness. The drawn current depends on how bright you set each LED (to be specific each color of each LED, since one RGB LED is actually 3 LEDs with the colors red, green and blue in one casing). So your current was low enough to not brown out the power from the Arduino.

Appreciate it @chrisl.... not that I had any reason to doubt you but I re-ran my sketch at a ridiculously low brightness and it ran forever.

@PaulM Your observation confirms the answer.


text:
Arduino Nano Doesn't Upload Any Code After Connecting It In Reverse (Rotated 180°)!
I've Made A PCB Which Includes An Arduino Nano. I Soldered Some Female Pin Headers Instead Of Soldering The Arduino Itself, So That I Can Easily Plug/Unplug The Arduino Board.
It Was All Good, Until I Accidentally Plugged The Arduino Nano Rotated 180°, Which Made Arduino Pin(12) Connected To The Vin(11.1v) At The PCB, And Arduino (Tx) Pin Plugged Into Pin(13)'s Place At PCB, And So On ...
The PCB's Power Was On (11.1v @ VIN Place At The PCB).
Now,

When I Power The Arduino Board It Looks Normal, 5v Pin And Vin Pin Works Good, No Power Issues, But The  Arduino IDE doesn't Upload Any Sketches To It, It Gives Me This Error:

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

I Tried Burning Bootloader With The IDE It Gave Me This:

avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

Error while burning bootloader.

I Tried To Upload Code With The IDE But Used USBsp Programmer, It Gave Me This:

avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

the selected serial port
 does not exist or your board is not connected

I Tried To Program The Board Using USBasp Programmer -with ICSP pins- and avrdude, It Gave Me This:

avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

I Also Tried To Upload Code, Or Burn Bootloader Using Another Arduino, But Didn't Work!

But When I Connect It To The Computer Using The Usb Cable, The IDE Detects It, And It Allows Me To Open The Serial Monitor!

So, What's The Problem? Is It Completely Broken, Or It Can Be Repaired??
I Suppose That The Atmega Is Burnt, As 11.1v Was On Pin(12), And Pin(11) Was Connected To Ground!!

Did you check with another Arduino that your circuit works in principle? Most probably you bricked your Nano.

ya, The Circuit Works Fine, I Tested It With Another Arduino ..

So your Nano is dead.

Fine  ...

Apparently your Nano is dead.
Depending on the specific device and your skills, you can try to replace the AVR on it. Please be aware that you need to flash the bootloader on it.

Buying A New One Is Easier Than Replacing Replacing The Atmega328p! ..

Well, then go ahead. ;-) Time is money under certain circumstances, but not necessarily at hobbyists. -- BTW, please reconsider your style to write any word capitalized.

I Will  ...

As a new user of SE/Arduino your might want to take the [tour] to learn how this site works. It is not a forum. -- For example, if you think an answer solves your issue, you mark it. This way your question will be shown prominently as "solved", you saw this probably already on the list, where the answers marker is colored and check-marked. Never edit the title to add something manually.


text:
How to allow cross-domain requests with ESP8266WebServer.h ? - CORS policy: Access-Control-Allow-Origin
With an nodeMCUv2 I want:

to start a wifi server with ESP8266WebServer.h
serve a root html page which will interact with the ESP and fetch external data

Issue:
CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.'
Tried to make CORS happy, by either one of the followings, but didn't help:
.sendHeader("Access-Control-Allow-Origin", "*");
.enableCORS(true);
#include <ESP8266WebServer.h>
ESP8266WebServer srvAmb(80);
void handleRoot(){
// srvAmb.sendHeader("Access-Control-Allow-Origin", "*");
   srvAmb.enableCORS(true);
   srvAmb.send(200,"text/html; charset=utf-8", myRootWebPagWithJSExternalFetch);
}
void setup(){
...
    srvAmb.on("/", handleRoot);
...

Part of the served root html page:
try{
  const Qresponse = await fetch( "https://zenquotes.io/api/random" );
  const Qdata = await Qresponse.json();
  console.log(Qdata);
  ...
} catch (error) {
  console.error(error);
}

Console log in Chromium:

Access to fetch at 'https://zenquotes.io/api/random' from origin '192....' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

So, how does one fetch external data from the browser running on PC, smartphone, etc?
Thanks
P.S. One could ask the server to fetch the data, prior to supplying the html page, but that's not esp server's job.
P.P.S. I hadn't the credit to create tag keywords such as:
fetch, CORS, Allow-Origin, policy
REM: under How to allow cross-domain requests on ESP8266WebServer
it is suggested that .sendHeader("Access-Control-Allow-Origin", "*") could be deprecated, very well but ArduinoIDE does not raise any warning; anyway suggested solution fails.
Looking at the source code https://github.com/esp8266/ESPWebServer/blob/master/src/ESP8266WebServer.cpp,
the method sendHeader() on line 238, has a 3rd parameter(a boolean) that if set to true, puts before the passed name & value before the already passed header, otherwise puts it after, aka the declarative order is important.
Viz, what's the valid header the esp server needs to send??
Especially, has Chromium details, states:

Request URL: zenquotes.io/api/random

Request Method: GET

Status Code: 200

Referrer Policy: strict-origin-when-cross-origin

See also: https://javascript.info/fetch-crossorigin

One thing, because I struggled with CORS in a different context lately: Are you sure, that your browsers cache doesn't interfere here? I had the issue that setting allow origin to * wouldn't help, but as soon as I used a different browser (or in my case a fresh profile of firefox), it was working.

@chrisl. NO. But I wonder if it has nothething to do with the fact that the fetch is https while the connection with ESP is http.
GET https://zenquotes.io/api/random net::ERR_FAILED 200
https://stackoverflow.com/questions/22665232/what-can-cause-chrome-to-give-an-neterr-failed-on-cached-content-against-a-ser

Details in Chromium: states that the header is missing:
A cross-origin resource sharing (CORS) request was blocked because of invalid or missing response headers of the request or the associated preflight request .
...
Request Status Preflight Request (if problematic) Header Problem Invalid Value (if available)
random blocked  Access-Control-Allow-Origin Missing Header
So it does not do job as Chromium 107 expects.
https://web.dev/cross-origin-resource-sharing/?utm_source=devtools  and
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

The issue is URL specific.
Indeed, if I change API, namely
const Qresponse = await fetch( "https://zenquotes.io/api/random" );

by for example:
const Qresponse = await fetch( "https://api.open-meteo.com/v1/meteofrance?latitude=49.71&longitude=4.16&daily=sunset&timezone=Europe%2FBerlin" );

then it works.
I presume that I comes from network developper tools info in Chromium:

Referrer Policy: strict-origin-when-cross-origin

claiming a strict origin for zenquotes.io's API.
My esp server code being:
void handleRoot(){
    srvAmb.sendHeader("Access-Control-Allow-Origin", "*", 1);
    srvAmb.send(200,"text/html; charset=utf-8", myRootWebPagWithJSExternalFetch);
}

Remark, with or without the additional 3rd param of sendHeader() it works.


text:
Fading out a led with reed switch loop
I was hoping to get some help on the fading led which I am working on.
For my project I need to have a led, which when it is placed next to a magnet, continuously shines, but as soon as it is taken away it has to fade out in a certain amount of time. So far I managed to write the code which detects when the light is taken away from the magnet and fades out, but when the magnet is nearby again, the led lights up and keeps shining, no matter  if I take it away from the magnet or not. So how I could solve this? I tried to exit the loop function, but then this process happens only once, which is not what I want. I am also using reed switch to detect the magnet, but if you have other sensor suggestions, let me know. I'm including the code down here.
Thank you for your help in advance:)
int ledPin = 9;
int brightness = 255;
int fadeAmount = 5;
const int reedPin = 2;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(reedPin, INPUT_PULLUP);
}

void loop() {
  int proximity = digitalRead(reedPin);
  if (proximity == HIGH) {
    Serial.println("Switch opened");
    while (brightness >= 0) {
      analogWrite(ledPin, brightness);
      brightness = brightness - fadeAmount;
      delay(30);
      Serial.println(brightness);
    }
  }
  else {
    Serial.println("Switch closed");
    analogWrite(ledPin, brightness);
    Serial.println(brightness);
  }
}

First, please don't provide code as an image. Instead copy and paste the code as text into the question and format it correctly by selecting the code and clicking the {} button in the question editor

Your current problem probably comes from the fact, that you execute the fading loop, even if brightness is already zero, and that you don't reset it to zero after fading.
while(brightness >= 0){
   ...
   brightness = brightness - fadeAmount;
   ...
}

Imagine we are at the point, where brightness is 5. The while condition is true, since 5 > 0. Then we execute the code in the loop, setting brightness to 0. We again check the while condition. It is still true, since 0>=0. So after executing the code in the loop again, brightness is now -5. But analogWrite() only takes a 1 byte unsigned (!) integer, aka uint8_t, while int is a 2 byte signed (!) integer. So only the lower byte of that integer will be used and interpreted as unsigned. So -5 gets interpreted as 251, which you see as lighting up in full brightness.
Easy fix would be to set brightness to zero after the while loop:
brightness = 0;

That said, I would suggest a completely different route, which will make your code way more responsive, by using the non-blocking coding principle from the BlinkWithoutDelay example, that comes with the Arduino IDE.
As you did, I would use a global brightness and fadeAmount variable, but also one to hold a timestamp:
unsigned long timestamp=0;

Then in loop() we can first do the fading to zero by using the millis() function as a clock:
if(millis()-timestamp > 30){
    brightness = brightness - fadeAmount;
    if(brightness < 0) brightness = 0;
    timestamp = millis();
}

That will decrement the brightness variable to zero without blocking with a delay(). The speed can be changed by changing the number 30 to something different. This number has the unit milliseconds.
Then we can check for the reed switch and set brightness to 255, if it is activated:
if(!digitalRead(reedPin)){
    // reedPin is LOW
    brightness = 255;
}

So as long as the magnet is at the reed switch, this code will set brightness to 255.
And finally we need to write the value of brightness to the output pin:
analogWrite(ledPin, brightness);

So as a full code:
int ledPin = 9;
int reedPin = 2;

int brightness = 0;
int fadeAmount = 5;
unsigned long timestamp = 0;

void setup(){
    pinMode(ledPin, OUTPUT);
    pinMode(reedPin, INPUT_PULLUP);
}

void loop(){
    if(millis()-timestamp > 30){
        brightness = brightness - fadeAmount;
        if(brightness < 0) brightness = 0;
        timestamp = millis();
    }

    if(!digitalRead(reedPin)){
        // reedPin is LOW
        brightness = 255;
    }

    analogWrite(ledPin, brightness);
}

I've tested this with a normal button (currently no reed switch here). It should work as expected.

I tested it, it works. Thank you so much!


text:
ESP Sim800l Firebase
So, I'm trying to send data from ESP boards- 32 and 8266 using sim800l module to firebase.
But I'm getting HTTP not connected error. I tried to search web but it seems that firebase changed something recently and the ways previously used cant be used. So anyone who has recently done that please help. P.S I'm considerably new to this.
Project - So to give you idea I'm trying to make a Vehicle GPS tracking system which would send data first to firebase using Sim800l.
My Code -
#define TINY_GSM_MODEM_SIM800

#define TINY_GSM_RX_BUFFER 256

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
#include <TinyGPS++.h> //https://github.com/mikalhart/TinyGPSPlus
#include <TinyGsmClient.h> //https://github.com/vshymanskyy/TinyGSM
#include <SoftwareSerial.h>
#include <ArduinoHttpClient.h> //https://github.com/arduino-libraries/ArduinoHttpClient
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
const char FIREBASE_HOST[]  = "vehicle-tracking-4a76d-default-rtdb.firebaseio.com";
const String FIREBASE_AUTH  = "6NGxNkNWf2inWa1LrdktCtq4************";
const String FIREBASE_PATH  = "/";
const int SSL_PORT          = 443;
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
// Your GPRS credentials
// Leave empty, if missing user or pass
char apn[]  = "airtelgprs.com";
char user[] = "";
char pass[] = "";
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
//GSM Module TX pin to NodeMCU D3
//GSM Module RX pin to NodeMCU D4
#define rxGSM 0 //D3
#define txGSM 4 //D4
SoftwareSerial sim800(rxGSM, txGSM);
TinyGsm modem(sim800);
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
//GPS Module TX pin to NodeMCU D1
//GPS Module RX pin to NodeMCU D2
#define rxGPS 5 //D1
#define txGPS 4 //D2
SoftwareSerial neogps(rxGPS, txGPS);
TinyGPSPlus gps;
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
TinyGsmClientSecure client1(modem);
HttpClient http_client = HttpClient(client1, FIREBASE_HOST, SSL_PORT);
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

unsigned long previousMillis = 0;
long interval = 10000;

//**************************************************************************************************
void setup() {
  Serial.begin(115200);
  Serial.println("NodeMCU serial initialize");

  sim800.begin(9600);
  Serial.println("SIM800L serial initialize");

  neogps.begin(9600);
  Serial.println("neogps serial initialize");
  delay(3000);

  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  //Restart takes quite some time
  //To skip it, call init() instead of restart()
  Serial.println("Initializing modem...");
  modem.restart();
  String modemInfo = modem.getModemInfo();
  Serial.print("Modem: ");
  Serial.println(modemInfo);
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

  // Unlock your SIM card with a PIN
  //modem.simUnlock("1234");

  http_client.setHttpResponseTimeout(90 * 1000); //^0 secs timeout
}
//**************************************************************************************************

//**************************************************************************************************
void loop() {
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  //Restart takes quite some time
  //To skip it, call init() instead of restart()
  //Serial.println("Initializing modem...");
  //modem.init();
  //String modemInfo = modem.getModemInfo();
  //Serial.print("Modem: ");
  //Serial.println(modemInfo);
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  //  Serial.print(F("Waiting for network..."));
  //  if (!modem.waitForNetwork()) {
  //    Serial.println(" fail");
  //    delay(1000);
  //    return;
  //  }
  Serial.println(" OK");
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

  //  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  //  Serial.print(F("Connecting to "));
  //  Serial.print(apn);
  //  if (!modem.gprsConnect(apn, user, pass)) {
  //    Serial.println(" fail");
  //    delay(1000);
  //    return;
  //  }
  //  Serial.println(" OK");
  sim800.listen();
  sim800.println('AT+SAPBR=3,1,"Contype","GPRS"');
  sim800.println('AT+CSTT="airtelgprs.com","",""');
  sim800.println("AT+SAPBR=1,1");
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

  http_client.connect(FIREBASE_HOST, SSL_PORT);

  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  while (true) {
    if (!http_client.connected()) {
      Serial.println();
      http_client.stop();// Shutdown
      Serial.println("HTTP  not connect");
      break;
    }
    else {
      gps_loop();
    }
  }
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
}
//**************************************************************************************************

//**************************************************************************************************
void PostToFirebase(const char* method, const String & path , const String & data, HttpClient* http) {
  String response;
  int statusCode = 0;
  http->connectionKeepAlive(); // Currently, this is needed for HTTPS

  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  String url;
  if (path[0] != '/') {
    url = "/";
  }
  url += path + ".json";
  url += "?auth=" + FIREBASE_AUTH;
  Serial.print("POST:");
  Serial.println(url);
  Serial.print("Data:");
  Serial.println(data);
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

  String contentType = "application/json";
  http->put(url, contentType, data);

  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  // read the status code and body of the response
  //statusCode-200 (OK) | statusCode -3 (TimeOut)
  statusCode = http->responseStatusCode();
  Serial.print("Status code: ");
  Serial.println(statusCode);
  response = http->responseBody();
  Serial.print("Response: ");
  Serial.println(response);
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  if (!http->connected()) {
    Serial.println();
    http->stop();// Shutdown
    Serial.println("HTTP POST disconnected");
  }
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
}
//**************************************************************************************************

//**************************************************************************************************
void gps_loop()
{
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  //Can take up to 60 seconds
  boolean newData = false;
  for (unsigned long start = millis(); millis() - start < 2000;) {
    while (neogps.available()) {
      if (gps.encode(neogps.read())) {
        newData = true;
        break;
      }
    }
  }
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  //If newData is true
  if (true) {
    newData = false;

    String latitude, longitude;
    //float altitude;
    //unsigned long date, time, speed, satellites;

    latitude = String(gps.location.lat(), 6); // Latitude in degrees (double)
    longitude = String(gps.location.lng(), 6); // Longitude in degrees (double)

    //altitude = gps.altitude.meters(); // Altitude in meters (double)
    //date = gps.date.value(); // Raw date in DDMMYY format (u32)
    //time = gps.time.value(); // Raw time in HHMMSSCC format (u32)
    //speed = gps.speed.kmph();

    Serial.print("Latitude= ");
    Serial.print(latitude);
    Serial.print(" Longitude= ");
    Serial.println(longitude);

    String gpsData = "{";
    gpsData += "\"lat\":" + latitude + ",";
    gpsData += "\"lng\":" + longitude + "";
    gpsData += "}";

    //PUT   Write or replace data to a defined path, like messages/users/user1/<data>
    //PATCH   Update some of the keys for a defined path without replacing all of the data.
    //POST  Add to a list of data in our Firebase database. Every time we send a POST request, the Firebase client generates a unique key, like messages/users/<unique-id>/<data>
    //https://firebase.google.com/docs/database/rest/save-data

    PostToFirebase("PATCH", FIREBASE_PATH, gpsData, &http_client);

  }
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
}
//**************************************************************************************************


text:
Is there a FreeRTOS library for an Arduino Nano 33 BLE?
I can't seem to find any library online so I can start developing FreeRTOS tasks for the Arduino Nano 33 BLE in the Arduino IDE. Is FreeRTOS incompatible with this Arduino?

the Arduino mbed platform for the Nano BLE is based on mbed RTOS. why do you want to use FreeRTOS?

I have a college assignment where I need to install and characterize FreeRTOS on 3 different systems, the ones I chose with the help of the professor were the Arduino Uno, the ESP-32 and the Arduino Nano 33. Since I never used ESP-32 and Arduino Nano 33 I just assumed the professor knew it would work, but it really seems like it doesn't support FreeRTOS. I don't know how to use mbed RTOS and I don't have a lot of time to work on this project, so it wouldn't make sense to use anything besides FreeRTOS, which is the only RTOS I can use.

esp32 arduino platform is RTOS too

Forget about the Arduino Uno. It's CPU is much to weak to run any OS.

The Arduino Uno actually runs FreeRTOS pretty well and is easily programmable because there is a library for it inside the Arduino IDE.


text:
PWM with a TRANSISTOR on flexible LED filament
I would like to create a custom lighting, with PWM capability, powered from battery. I would like to use flexible led filaments, and since those consumes more than 40mA, I can't use them directly on a board. I found a link explaining to use a MOSFET transistor, to dim my leds. So the transistor that I need would be one with a 5v power supply, and a 5v Voltage input.
The problem is that I can't find any transistor matching those specs. I also noticed that they have a heatsink, which mean that they need to dissipate heat, and are therefore not power efficient (which i do not like). Am I missing something ?
Any help will be apreciated, thanks !

look for DC motor drive circuits or relay drive circuits ... there are many examples

You cannot find a MOSFET with that exact rating, because transistors can be used with all voltages inside of their specific limits. Most MOSFETs can be used with way higher voltages than 5V.
What you need is a logic level MOSFET, which means, that it will be in saturation (aka being fully ON) at the typical logic level of 5V on its gate. In the datasheet of a MOSFET you will find a diagram which shows the drain current depending on the gate-source voltage. At your logic level (5V in this case) you want the curve approaching a plateau.
Another important value is R_DS(on). That is the resistance of the MOSFET when its on. The lower the resistance, the lower will the power lost to heat.

I also noticed that they have a heatsink, which mean that they need to dissipate heat, and are therefore not power efficient (which i do not like).

Every MOSFET dissipates some energy as heat, since no MOSFET can have R_DS(on) of zero. The typical heat sink flap is meant to dissipate the heat for keeping the MOSFETs temperature in the specified range, even when drawing the maximum specified current. The datasheet of a MOSFET has a section with maximum ratings. There you should see the maximum drain current I_D with its corresponding needed temperatures. For example have a look at this datasheet of a random logic level MOSFET from mouser. There is no specification of how hot the case gets with a specific current, since this depends on the suroundings, but the datasheet states, that it will support up to 80A, when you keep the case to a temperature of 25°C.
It also states what electrical power it can dissipate with its package: P_D. You should look at how much current you need for your LED filament. You can calculate the dissipating power with P = R * I² (P being power, R the resistance R_DS(on) and I the current through the MOSFET).

Thanks for the clarification ! So if I need to check for power dissipation, there will be in the datasheet a graph with temperatures at specific currents drains (I_D) ? In the link you gave, I found a graph named "FIGURE 10. Maximum drain current vs. Case temperature". Is it the right graph ? Because It seem inverted, is that normal ? And how can I get those MOSFETs ? I tried search engines but i can't find much of them on internet

Thats the point, that I wanted to make clear. There is no diagram for how hot the MOSFET gets with a given current, because that also depends on how fast the suroundings can move the heat away. Its affected by things like airflow, air temperature, air humidity, ... . So instead they give you information on the current, that the MOSFET will sustain at a given temperature. To find out how hot it will get in your application, you need to test it. The actual power loss is only determined by current and R_DS(on)

And you can find such MOSFETs at any good supplier for electronic components in your region. Mouser would be one, that at least is available in europe. I don't know, where you are and what the relevant suppliers are in that region.

Ok thanks, it is a lot more clearer now. I'm a student, I live near paris, but it is a bit complicated to find such electronics stores. They're usually not opened the weekend or so. I'll try Mouser !

Welcome! You are missing some information. A transistor will work but you will lose about 0.7 Volts when it is on. That voltage times the current will tell you how many watts it needs to dissipate. The data sheet will give you all this information.  The transistor is a current controlled device so there will not be a Base voltage rating. You can determine the current for the base by dividing the load current by the HFE then adding a bit.
By connecting more than 20 mA to the port pins especially more than 1 may destroy the Arduino. Surprise the LED is also a current device so you need to limit the current into it. This can easily be done with a resistor.
The MOSFET would be the easiest solution. Put a resistor maybe 10K from the port pin to ground. The reason is the port pins are floating from power on until your software defines and sets there level. Then connect the port of the Arduino to the gate of the MOSFET which has its source grounded. Connect the LED(s) to the drain and place a resistor in series with the LED and + voltage. It can be 12 Volts or whatever you like. You will need to size the current limiting resistor to the LED(S) appropriately and be sure the voltage rating of the MOSFET is at least 10% higher then the voltage.
There is a great book available called the Arduino Cookbook, getting that and reading it will be a big help to you.

Though MOSFETs are voltage controlled, while Bipolar transistors are current controlled.

Hi, thank you for your answer ! I was indeed a bit confused about transistors. As i'm searching a MOSFET with specific specs, I went on that website ROHM tool, and filled the specs, and it says "voltage power supply". Is that the right way to search for a MOSFET ?


text:
Ability to calculate bearing related distance with Arduino GPS
Pardon if there's a more precise/technical way of formulating this question :)
What I'm currently working on is a proximity warning with Arduino. There's a preset GPS location in the sketch and if I'm moving closer to it, once I cross a set distace threshold, action is triggered.
I think picture will do better explaining on what challenge I wish to overcome here. Calculating simple "straight line" distance between my current geolocation and the preset destination is easy, but as you can see in the illustration I made, it works from all directions.
100 meter from the target is valid here from any point, or any bearing that the subject might be approaching, which is tedious and not what I want to achieve.
Lower illustration shows what I'd wish to achieve - achieve the trigger criteria only if approaching the destination from certain "bearings"...if that's the right way to phrase it. Hope someone understands what I'm trying to do, if you have some pointers where to start looking and if this can even be achieved on Arduino - do let me know :) Thanks a lot

it's just geometry ... not really about arduino

Perhaps I phrased the question wrong - so it is possible that arduino could detect proximity to a set destination without making a "redundant" circle due to distance radius? Would this be something on the geometry side, or on GPS library side, for example - if location is 100m from the target with the appropriate bearing - then trigger.

so, you want the proximity alert to be valid only if you are walking on a road, for example

Maby reading this (my similar question) will be useful for you : https://arduino.stackexchange.com/questions/91196/how-to-find-the-correct-navigation-course-by-gps-navigation-with-arduino/91197#91197   and also this one for proximity trigger https://arduino.stackexchange.com/questions/91247/how-to-write-a-program-to-do-2-different-loop-task/91253#91253

Note, that you actually don't need specific bearings, but little cones around these bearings, since the position will have some noise in it

@jsotola yes that could be the idea, if I'm approaching the destination from one direction, it triggers, but if I approach the same destination but from another bearing, it doesn't do anything. Curious guy that's an interesting topic you made, I'll look into it!

@chrisl not sure what you mean with cones around bearings? I believe my GPS module parses the bearing data as well, I thought this idea of mine could work by looking at the destination address and preset bearing if that would be possible? For example only trigger action if the distance toward specific LAT LON is less than "value" and if bearing is in the range of "value".

"in the range of value", thats exactly what I meant. It's not just one value, but range range around that value, because the bearing might not be stable and have some noise in it.

Before suggesting a possible solution consider these aspects of the problem:

The question assumes a "flat earth".  For small distances this assumption likely contributes an error that can be ignored.  For larger distances consider calculating the great circle distance.
Consider not every GPS module populates all NMEA fields.  If bearing is supplied consider it is not valid unless the GPS module has moved more than the current accuracy of that GPS module.

While the criteria is simple (only alarm when approaching a given latitude and longitude (or MGRS coordinate) while traveling on a certain bearing), the implementation can be troublesome and / or tedious.  Consider noise.  The position of the GPS module might vary 10 meters while stationary.  Resulting in a false bearing.  The person carrying the GPS may not walk a straight line.  This additional noise may result in never raising an alarm.  If the GPS is carried in a car, roads may not exist for direct travel to the given latitude and longitude. Again, the alarm may never be given.
As it turns out, the assumptions made here indicate bearing is not a good criteria when determining direction of approach to a given latitude and longitude.  Rather, it may be simply the relation between the current latitude and longitude and the given latitude and longitude that offers the best solution.


text:
How "fast" could GPS data be refreshed while moving and does it depend on the mcu?
I'm using Nano Every and SIM33EAU GPS module for my project and today I went riding shotgun to test how it works when moving on the road. I am using u8g2 library and one of the things that I have printed on the screen is gps.course.deg - which is as the name suggest, course of the GPS module's movement in degrees.
Next to my Arduino device I had a phone with some compass app, and the course was somewhat correct while we were moving at normal traffic speed, but the update rate was vastly different and I don't know why. The only "delay" in the sketch I have is this;
  if (gps.location.isUpdated())
  {
    Serial.print(F("Lat Lon = "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(", ");
    Serial.println(gps.location.lng(), 6);
  }

  else if (millis() - last > 500)
  ...

I wasn't able to check the Serial Monitor as I didn't have a laptop, so only reading from GPS module was what was being printed on the small OLED screen. So is the lagging update something on the GPS module side and how it works, or is it perhaps OLED not being able to refresh?

why are you asking for people to guess about your problem? ... this site is for providing answers, not guesses, so please ask a clear  answerable question and include all information that you have

GPS modules deliver position updates in very different frequencies, depending on model and configuration (where changeable). Cheaper modules only provide an update every 1 second, while better ones have 5 or 10 Hz position update. Check the documentation for your module to get that information.
Additionally, it is of course possible to "cheat", by calculating an extrapolation, using the last position, direction and speed. Since speed and direction don't typically change very quickly, that works quite well and can give position updates at arbitrary rates.

thanks @PMF I figured there had to be some internal limit, for some reason I thought all the consumer level GPS modules like the one I have are "50Hz" ... obviously completely wrong. So the mobile phone cheats, or do they put top class gps modules in there?

@Varonne I believe they cheat, but I can't tell you for sure. A "real" frequency of 5 or 10Hz is realistic even for decently priced modules. Downside probably is that they would use more power, which is also always a problem in cell phones. A top class GPS module that is used in professional navigation equipment is $15000 or so.