text:
How do I put timers by using millis on 3 PIR sensors?
I want to make the PIRs to stay on for about 1 minute. I've found the code that can do so for 1 PIR, but I dont know how to apply the code for 3 PIRs.
Here is the code for 1 PIR with timer using millis:
int ledPin = 8;
int pirPin = 3;

unsigned long piron;
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 10;

int off;
int on;
const int LDR = A0;
int ldrStatus;

unsigned long currentMillis =( millis()/1000 ) / 60;

/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

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

{
ldrStatus = analogRead (LDR);
if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                          // the higher reading(ldrStatus), the dimmer light
                          // the lower the reading(ldrStatus), the brighter light

{
analogRead (pirPin) == off;

Serial.println ("Its SUNNY DAY !!!");
digitalWrite(ledPin, LOW);

}

if (ldrStatus >= 700)
{
Serial.println ("Its DARK already");

    if(digitalRead(pirPin) == HIGH){
       digitalWrite (ledPin, HIGH);
     piron = ( millis()/1000 ) / 60;
  }

  if ((currentMillis - piron) > 1) {
    digitalWrite(ledPin, LOW);

  }

    }
}
`

and here is the code for 3 PIRs without the timer

    int calibrationTime = 10;

int pirPin = 3;
int ledPin = 8;

int pirPin1 = 4;
int ledPin1 = 9;

int pirPin2 = 5;
int ledPin2 = 10;

int ledPin3 = 11;

int off;
int on;
const int LDR = A0;
int ldrStatus;

/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

   pinMode(pirPin1, INPUT);
  pinMode(ledPin1, OUTPUT);
  digitalWrite(pirPin1, LOW);

   pinMode(pirPin2, INPUT);
  pinMode(ledPin2, OUTPUT);
  digitalWrite(pirPin2, LOW);

 pinMode (ledPin3, OUTPUT);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop()
{
ldrStatus = analogRead (LDR);
if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                          // the higher reading(ldrStatus), the dimmer light
                          // the lower the reading(ldrStatus), the brighter light

{
analogRead (pirPin) == off;
analogRead (pirPin1) == off;
analogRead (pirPin2) == off;
Serial.println ("Its SUNNY DAY !!!");
digitalWrite(ledPin, LOW);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
}

if (ldrStatus >= 700)
{
Serial.println ("Its DARK already");
digitalWrite(ledPin3, HIGH);

    if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
      digitalWrite (ledPin, HIGH);
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2,LOW);
    }

    if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
      digitalWrite (ledPin1, HIGH);
      digitalWrite (ledPin, LOW);
      digitalWrite(ledPin2,LOW);

}
   if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
      digitalWrite (ledPin2, HIGH);
      digitalWrite (ledPin1, LOW);
      digitalWrite (ledPin, LOW);

   }

     if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
    digitalWrite (ledPin1, HIGH);
    digitalWrite (ledPin, HIGH);
    digitalWrite (ledPin2, LOW);

}

     if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
      digitalWrite (ledPin, HIGH);
      digitalWrite (ledPin2, HIGH);
      digitalWrite (ledPin1, LOW);
     }

     if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
     digitalWrite (ledPin2, HIGH);
     digitalWrite (ledPin1, HIGH);
     digitalWrite (ledPin, LOW);
     }

    if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
      digitalWrite (ledPin2, HIGH);
      digitalWrite (ledPin1, HIGH);
      digitalWrite (ledPin, HIGH);

    }

     if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
      digitalWrite (ledPin2, LOW);
      digitalWrite (ledPin1, LOW);
      digitalWrite (ledPin, LOW);
     }

}

}

@jsotola ive try rewriting the first code from `if(digitalRead(pirPin) == HIGH){
digitalWrite (ledPin, HIGH);
piron = ( millis()/1000 ) / 60;
}
if ((currentMillis - piron) > 1) {
digitalWrite(ledPin, LOW);
}   to   digitalWrite (ledPin, digitalRead(pirPin));
piron = ( millis()/1000 ) / 60;
if ((currentMillis - piron) > 1) {
digitalWrite(ledPin, LOW);
}`    but it seems to ignore the timer or am i writing the code wrong

and thanks! now i know i dont need to use if :)

okay, ive tried changing to 50seconds in this code   digitalWrite(ledPin, digitalRead(pirPin));        piron = millis();    currentMillis = millis();   if ((currentMillis - piron) > 50000) {     digitalWrite(ledPin, !digitalRead(pirPin)); startMillis = currentMillis;  but the timer still doesnt work. The led turns off in like 3  seconds....

can you give me an example? sorry for asking too many question...im still new to this.

it means pir on = led on, i want to make the led on by using the pir, and after 1 minute  the led is automatically off

your question still says make the PIRs to stay on for about 1 minute .... please edit the question and delete the comment

This is not a complete answer, but an idea of how to accomplish the task.
I just typed it in without testing the code.
Use arrays to hold variables. That way a loop can be used to service the three sensors and the three LEDs..
for (i = 0; i<3; i++) {
   currentTime = millis();                             // save current millis() value

   if (digitalRead(pirPin[i]) == HIGH) {               // check if PIR is detecting motion
      trigTime[i] = millis();                          // save trigger time
      trig[i]     = true;                              // set a state variable that indicates
   }                                                   //   that a trigger happened

   if (trig[i]) {                                      // if trigger happened
      if (currentTime - trigTime[i] < 50000) {         // is it less than 50 sec since last motion?
         digitalWrite (ledPin[i], HIGH);
      }
      else {
         trig[i] = false;                              // 50 second timer ran out
         digitalWrite (ledPin[i], LOW);
      }
   }
}

thanks a lot!! though i did some changes in that code and put the pirs and leds in different loops. i finally got it. thanks again, i really appreciate it. :D


text:
Formatting variables from a variadic function
I have a function that concatenates a print line, however I am having trouble getting some of the strings to format correctly.
Using Serial.print formats the output from keypad.getKey() correctly, however when I try to output the same format using printConcatLine() it does not give me the same output. I've tried casting it as both a char and an int...

void printConcatLine(const char* mask, ...) {
    va_list params;
    va_start(params, mask);

    while(*mask != '\0') {
      if (*mask == 'i') {
          Serial.print(va_arg(params, int));
      } else if(*mask == 'c') {
          Serial.print(va_arg(params, const char *));
      } else if (*mask == 'f' || *mask == 'd') {
          Serial.print(va_arg(params, double));
      }
      ++mask;
    }

    va_end(params);
    Serial.println();
}

char btnPressed = keypad.getKey();
  if (btnPressed) {
    Serial.print("BtnPressed: ");
    Serial.println(btnPressed);
    // Output: "BtnPressed: 1"

    printConcatLine("ci", "BtnPressed: ", btnPressed);
    // Output: "BtnPressed: 49"

    printConcatLine("cc", "BtnPressed: ", btnPressed);
    // Output: "BtnPressed: "
  }

I also tried changing:

va_arg(params, const char *)

to

va_arg(params, char)

which also did nothing.
How can I modify the call to va_arg() to properly output the same output as Serial.print()?

Incidentally, on chipKIT we provide the handy Serial.printf("...", ..., ..., ...) function which is ideal for this. The formatting is handled by this code, which itself was lifted directly from RetroBSD.

Since you’re using serial to print the string, why the need to concatenate it?  Just print it out in chunks.

Edgar beat me to it by a few seconds, but my answer is pretty much the same as his, so read that first.
I will however add a few extra notes and pointers:

It's better to assign the va_args to an actual variable. That makes it both easier to read and understand what's going on, and more certain for the overloading of the print function to know what is supposed to happen (at least from the reader's perspective) that mere casting.
Bytes and chars are promoted to integer when being passed to a variadic function, so you have to treat them as such
float and double happen to be the same on the AVR based Arduinos, so your code will be OK there, but the same can't be said for other chips. If you want your code to be portable then you should split float and double into separate handlers since they use different sizes.
It can be good to "pass through" unknown characters in the format string so that you can add extra formatting in there. See my example below.

Here's my variant of the same code. Note the colon and space in the format that is used to add more formatting to the output (this could be enhanced by adding a % before any format characters as printf does). I also like to use a separate pointer to iterate over the format string instead so that the original start pointer is still available if I should ever want it.
Also note the difference between c and i: use c to print a letter from a char, and i to print the number in a char instead.
void printConcatLine(const char *mask, ...) {
    va_list params;
    va_start(params, mask);

    char *ptr = (char *)mask;
    while (*ptr != '\0') {
        if (*ptr == 'c') {
            int c = va_arg(params, int);
            Serial.write(c);
        } else if (*ptr == 'i') {
            int i = va_arg(params, int);
            Serial.print(i);
        } else if (*ptr == 's') {
            const char *s = va_arg(params, const char *);
            Serial.print(s);
        } else if (*ptr == 'f' || *ptr == 'd') {
            // Be careful with this. It's not portable. On AVR float
            // and double are the same, but that's not the case on other
            // microcontrollers. It would be better to split them.
            double d = va_arg(params, double);
            Serial.print(d);
        } else {
            Serial.write(*ptr);
        }
        ptr++;
    }

    va_end(params);
    Serial.println();
}

void setup() {
    Serial.begin(115200);
    char btnPressed = 1;
    float flt = 3.141592653;

    if (btnPressed) {
        printConcatLine("c: sisd", 'Q', "BtnPressed: ", btnPressed, " done ", flt);
    }
}

void loop() {
}

how much flash space does this save compared to printf? in my test none.

@Juraj A lot. Take a look at the link in my comment above for a "light weight" printf formatter and you'll see how much is involved in it.

sorry. no. printf produces a little smaller code. I use my StreamLib for printf wrapper for Serial https://github.com/jandrassy/StreamLib/blob/3b2393284315de939105a0c11df50be1471f6cfe/src/FormattedPrint.cpp#L28

@Juraj Maybe on the Arduino, but then the Arduno printf lacks float support, which is included in the code here. If you take out the float support you will most likely find this code considerably smaller. Float support is massive.

I compiled both versions for the Uno with float support and, to my surprise, Juraj's is smaller (text: 4814, data: 68, bss: 166) than yours (text: 6226, data: 62, bss: 166).

@EdgarBonet That is a surprise it has to be said.

the printf float support with -Wl,-u,vfprintf -lprintf_flt is somehow unconditional. it makes even Blink large

I recommend to use printf if you don't need float support in printf. This code produces a little smaller compiled code then the one in Majenko's answer and has the full power of the printf except of float.
#include <StreamLib.h>

void setup() {
    Serial.begin(115200);
    char btnPressed = 1;
    float flt = 3.141592653;

    byte b;
    BufferedPrint bp(Serial, &b, 1);

    if (btnPressed) {
        bp.printf("%c: %s %i %s", 'Q', "BtnPressed: ", btnPressed, " done ");
        bp.println(flt, 4);
    }
}

void loop() {
}

With StreamLib you can of course print float with normal single print function for floats, the same as for Serial or network Client, with second parameter for the number of decimal places.
If you want to create a formatted C-string you can use the CStringBuilder of the StreamLib. It too builds the string with print functions and has 'printf' too.

Re “smaller program”: smaller compiled code?

@EdgarBonet, yes, smaller compiled code

With the format "ci", the argument is interpreted as an integer, and
the output is correct: 49 is the ASCII code of '1'.
With the format "cc", the argument is interpreted as a string (pointer to an
array of chars), which is incorrect.
One (bad) solution is to use the "cc" format and pass &btnPressed as
an argument. The problem with this approach is that the byte in memory
right after btnPressed may not be a zero, and the format expects a
NUL-terminated string.
A better approach would be to have one format for a char and a
different one for a string. I suggest "c" and "s" respectively. But
then you should be aware that there are special promotion rules
associated with variadic functions. When playing with your code, the
compiler reminded me of this one:

warning: ‘char’ is promoted to ‘int’ when passed
  through ‘...’

So the function should expect an int, and cast it to char in order
to call the correct overload of Serial.print():
void printConcatLine(const char* mask, ...) {
    va_list params;
    va_start(params, mask);

    while(*mask != '\0') {
      if (*mask == 'i') {
          Serial.print(va_arg(params, int));
      } else if(*mask == 's') {
          Serial.print(va_arg(params, const char *));
      } else if(*mask == 'c') {
          Serial.print((char) va_arg(params, int));
      } else if (*mask == 'f' || *mask == 'd') {
          Serial.print(va_arg(params, double));
      }
      ++mask;
    }

    va_end(params);
    Serial.println();
}

Used like this:
printConcatLine("sc", "BtnPressed: ", btnPressed);
// Output: "BtnPressed: 1"

source: Stack Exchange

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

sort: votes


text:
Get GPS position from a Heltec Wireless Tracker arduino
I've bought a Heltec Wireless Tracker Arduino.
I want to get the GPS position. I've taken the original example "GPSDisplayOnTFT" from the IDE (I've made a few changes because the original code wasn't working for me).

My screen always shows:
peek: 0
LAT: 0.00
valid: 0

I've put a comment on the code to show the line.
This is my code:
#include "Arduino.h"
#include "HT_st7735.h"
#include "HT_TinyGPS++.h"

TinyGPSPlus GPS;
HT_st7735 st7735;

#define VGNSS_CTRL 3

void GPS_test(void)
{
  Serial.println("GPS 1");
    Serial1.begin(9600,SERIAL_8N1,33,34);
    Serial.println("GPS_test");
  delay(1000);
    while(1)
    {
    st7735.st7735_fill_screen(ST7735_BLACK);
        if(Serial1.available()>0)
        {
            if(Serial1.peek()!='\n')
            {
                GPS.encode(Serial1.read());
        String peek = "peek: " + (String)GPS.encode(Serial1.read());
        Serial.println(peek);
         st7735.st7735_write_str(0, 0, peek);

            }
            else
            {
                Serial1.read();
                if(GPS.time.second()==0)
                {
          Serial.println("second==0");
                    continue;
                }
                st7735.st7735_fill_screen(ST7735_BLACK);
                st7735.st7735_write_str(0, 0, (String)"GPS_test");
                String time_str = (String)GPS.time.hour() + ":" + (String)GPS.time.minute() + ":" + (String)GPS.time.second()+ ":"+(String)GPS.time.centisecond();
                st7735.st7735_write_str(0, 20, time_str);
        Serial.println(time_str);
                String latitude = "LAT: " + (String)GPS.location.lat();
                st7735.st7735_write_str(0, 40, latitude);
        Serial.println(latitude);

                String longitude  = "LON: "+  (String)GPS.location.lng();
                st7735.st7735_write_str(0, 60, longitude);
        Serial.println(longitude);

                delay(5000);
                while(Serial1.read()>0);
            }

      Serial.println("***************************");
      Serial.println(Serial1.peek());
      Serial.println(Serial1.read());
      Serial.println(GPS.location.lat());
      st7735.st7735_write_str(0, 20, "LAT: " + (String)GPS.location.lat());

      //NOTE: it always shows '0'
      st7735.st7735_write_str(0, 40, "valid: " + (String)GPS.satellites.isValid());
      Serial.println("*********** fin ***********");

        }
    else{
     Serial.println("Serial 1 no available");
     st7735.st7735_fill_screen(ST7735_BLACK);
      st7735.st7735_write_str(10, 50, (String)"Unavailable");
     delay(5000);
    }
    Serial.println("while 1");

    delay(5000);
    }
}

void setup(){
  delay(100);
  Serial.begin(115200);
  Serial.println("setup 1");
  pinMode(VGNSS_CTRL,OUTPUT);
    digitalWrite(VGNSS_CTRL,LOW);

  st7735.st7735_init();
  st7735.st7735_fill_screen(ST7735_BLACK);
  st7735.st7735_write_str(20, 10, (String)"Loading ...");
  st7735.st7735_write_str(20, 50, (String)"GPS_test");

  Serial.println("setup 2");
  GPS_test();
  Serial.println("setup 3");

}

void loop(){
  Serial.println("loop 1");
  delay(3000);
  Serial.println("loop 2");
}

I'm not sure if I have to connect the antenna to the GNSS module.
Is there something I can print in thelogs to bring more info?
========= EDITED =========
This is the serial monitor output:
01:13:43.526 -> GPS_test started
01:18:12.693 -> setup 1
01:18:12.871 -> setup 2
01:18:12.871 -> GPS 1
01:18:12.904 -> GPS_test
01:18:14.201 -> peek: 0
01:18:14.232 -> ***************************
01:18:14.232 -> 106
01:18:14.232 -> 106
01:18:14.232 -> 0.00
01:18:14.329 -> *********** fin ***********
01:18:14.329 -> while 1
01:18:19.610 -> peek: 0
01:18:19.685 -> ***************************
01:18:19.685 -> 79
01:18:19.685 -> 79
01:18:19.685 -> 0.00
01:18:19.738 -> *********** fin ***********
01:18:19.738 -> while 1
01:18:25.036 -> peek: 0

what does this mean? ... original code wasn't working for me

@jsotola, it means that serial monitor and screen were showing nothing.

"I'm not sure if I have to connect the antenna to the GNSS module." Without an antenna, how is the module supposed to receive signals from space?

Many COTS GNSS modules, when not in lock, send NMEA message with just commas where latitude and longitude are expected.
The UC6580, used on the Heltec Wireless Tracker, appears to use the NMEA 0183 data format.
As the NMEA messages do not appear in the posted code, it is assumed some or all are in the TinyGPSPlus library used in the above code.
If we go to the TinyGPSPlus github.com account we see there are example Arduino INO file. This example tracks multiple satellites and reports "Satellite numbers, elevation, azimuth, and signal-to-noise ratio". This data is usually available even before the GNSS module is in lock (producing latitude and longitude values). So it's useful during problem investigation.
Modify the question when more information is available. For now it sounds like a bad GNSS module, bad GNSS antenna, bad antenna connection or you are indoors where you can not see GNSS satellites.

#define VGNSS_CTRL 3

Based on the example code from Heltec Github page. The pin for VGNSS_Ctrl is pin 37 instead of pin 3 as shown in your code.
Further checking the schematic diagram for Heltec Wireless Tracker V1.0, it confirmed that VGNSS_Ctrl is indeed on pin 37 which is used to activate the VDD_GNSS (i.e. to enable the power supply for GPS module).

Hcheung solution is nearly correct, but the pin according schematic is not 37 but 36.

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


text:
How can I provide a custom TLS CACert bundle with Arduino on ESP32?
With an ESP8266 it's pretty easy to pass a custom bundle; eg:
BearSSL::WiFiClientSecure client;
BearSSL::CertStore certStore;

int numCerts = certStore.initCertStore(FSTYPE, "/certs.idx", "/certs.ar");
client.setCertStore(&certStore);

Of course ESP32 doesn't use BearSSL. So I'm trying to work out the equivalent.
It appears I have to use setCACertBundle(), but I can't find an example of how to do this. There's a lot of Platform.io stuff but I'm not using that.
I also see hints that the libraries may already contain a built-in bundle, which may be sufficient, but, again, I can't see how to use this.
What is the ESP32 equivalent of the ESP8266 code?
It doesn't necessarily have to load from a filesystem; I can programatically generate constants to include in my code (indeed that'd be easier in some respects).

To use a cert collection with the ESP32 we need to provide the CAs in a specific format called a "bundle".  This is a binary data structure with certs sorted in order and an "offset" header to allow for quick access to each cert.
Generating this object gets a litle complicated.
The Arduino ESP32 library v3.0.7 (latest version) is based on ESP-IDF 5.1.4
The format for a bundle in this is
  uint16_t num_certs
  uint16_t offset * num_certs
  <cert_data>

Note the offsets are 16bit so the complete bundle can't be more than 64k.  Using https://curl.se/ca/cacert.pem it's too large (it generates a 69k bundle) so it's possible some CAs at the end of the list (in alphabetical order by CN) would not work.  When providing a custom bundle ensure the generated file is under 64k.
So in esp-idf v5.4 the format has changed.  It's now
  uint32_t offset * num_certs

The number of certs is determined by offset[0]/sizeof(uint32_t)
This means the gen_crt_bundle.py script in the master branch will not work with Arduino ESP32 library and you must use the one from the v5.1 branch.
Also it may mean that as the Arduino library updates to v5.4 or above then code will need changing.
To use a custom CA bundle we need to use the generator from v5.1; ie from
https://github.com/espressif/esp-idf/tree/release/v5.1/components/mbedtls/esp_crt_bundle
We can generate a bundle file with
python3 gen_crt_bundle.py -q -i *.pem

That will create  x509_crt_bundle
This needs to be got into your program.  This could be placed in SPIFFS
or LittleFS and loaded into a variable at runtime, or we can embed it
directly into our program as a const PROGMEM variable.
To embed it we can use a script similar to this:
eg
#!/bin/sh

F=x509_crt_bundle

echo 'static const uint8_t certs_bundle[] PROGMEM = {'
xxd -p $F | sed 's/\(..\)/0x\1,/g' | sed '$s/,$//'
echo '};'

s=`wc -c < $F`

echo "#define SIZE_OF_CERTS $s"

This will create output that looks like
static const uint8_t certs_bundle[] PROGMEM = {
0x00,0x8a,0x00,0x36,0x01,0x26,0x30,0x34,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x52,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0a,

....

0x4f,0x17,0x02,0x03,0x01,0x00,0x01

};
#define SIZE_OF_CERTS 64057

(Oh good; 64057 is below 65535 so all the offsets will be OK).
I called this output certs.h.
This can now be used
#include <WiFi.h>
#include <time.h>
#include <WiFiClientSecure.h>
#include "certs.h"

...
  WiFiClientSecure client;
  client.setCACertBundle(certs_bundle,SIZE_OF_CERTS);

Note this changed in 3.0.4 where you need to pass the size of the array;
in 3.0.3 this would simply be client.setCACertBundle(certs_bundle)
and would likely fail due to a bug.
Now esp-idf v5.1 has a cacrt_all.pem that is from Tue Jan 10 04:12:06
2023 GMT along with the DST ROOT CA X3 (cacrt_local.pem) which may no
longer be needed but is for older letsencrypt cross-signing.
To use this built-in bundle that is embedded into libmbedtls.a requires a little bit of a kludge as well.  As far as I can work it out,

extern const uint8_t x509_crt_imported_bundle_bin_start[] asm("_binary_x509_crt_bundle_start");
extern const uint8_t x509_crt_imported_bundle_bin_end[]   asm("_binary_x509_crt_bundle_end");

...
  client.setCACertBundle(x509_crt_imported_bundle_bin_start,x509_crt_imported_bundle_bin_end-x509_crt_imported_bundle_bin_start);

This allowed me to connect to servers with certs from common CAs (eg Amazon, Google, LetsEncrypt).

Glad that you solved this.

@hcheung Thanks for your answer; it helped lead me to the solution!

How to use CA Cert Bundle in Arduino ESP32?
The process for using the ESP32 setCACertBundle() was described in Arduino Library README.md of WiFiClientSecure Library for Arduino ESP32 framework release 2.x. For some reason it has been reduced to a simple vague paragraph in release 3.x README.md when the WiFiCleintSecure library is re-factored to NetworkClientSecure library. Espressif lately like to do that and sometime break the backward compatibility or remove something useful from its Github without explanation.
Create a CA Cert Bundle
In order to use a cert bundle, first you would need to generate a cert bundle. You could generate it yourself, or get CA certificates extracted from Mozilla from here. The download Mozilla CA certificate store cacert.pem is in PEM format and is around 200KB uncompressed.
Esp-idf has a python utility for generating a binary version of CA bundle which is only around 64kB. Download the gen_crt_bundle.py (you might need to install python package cryptography with pip3 install cryptography before you can run the python script).
Run the python script with the following command line to generate the binary file:
python3 gen_crt_bundle.py -i cacert.pem

This should generated a file called x509_crt_bundle, make a directory in your project directory and move the created bundle into the directory.
mkdir data data/cert
mv x509_crt_bundle data/cert/

Setup PlatformIO

The code that I'm going to shown work for PlatformIO, but does not work for Arduino IDE (I don't know why and in fact I don't really use Arduino IDE these days so I never spent the time to find out why).

Assuming you had PlatfromIO installed and have created an Arduino project. Add build flag in platformio.ini:
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
board_build.embed_files = data/cert/x509_crt_bundle
monitor_speed = 115200

Call setCACertBundle() before making an secure connection
The code for using the setCACertBundle() is actually quite simple and similar to the usage of WiFiClientSecure example, with only two differences:

add extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_bundle_bin_start"); to your sketch;
call client.setCACertBundle(rootca_crt_bundle_start); before making a client connection.

Here is the complete example sketch that I used for testing, it access the httpbin.org test site (you could try other sites) and httpbin server would return a response in json format.
#include <WiFiClientSecure.h>

const char* ssid     = "wifi ssid";
const char* password = "wifi password";

const char*  server = "httpbin.org";

extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_bundle_bin_start");

WiFiClientSecure client;

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

  Serial.print("Connecting to SSID: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

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

  // client.setCACert(ISRG_Root_X1_CA);
  client.setCACertBundle(rootca_crt_bundle_start);
  // client.setCertificate(test_client_cert); // for client verification
  // client.setPrivateKey(test_client_key);  // for client verification

  Serial.println("\nStarting connection to server...");
  if (!client.connect(server, 443))
    Serial.println("Connection failed!");
  else {
    Serial.println("Connected to server!");
    // Make a HTTP request:
    client.printf("GET https://%s/get HTTP/1.1\n", server);
    client.printf("Host: %s\n", server);
    client.println("Connection: close");
    client.println();

    while (client.connected()) {
      String line = client.readStringUntil('\n');
      if (line == "\r") {
        Serial.println("headers received");
        break;
      }
    }
    // read the response body
    while (client.available()) {
      char c = client.read();
      Serial.write(c);
    }

    client.stop();
  }
}

void loop() {
  // do nothing
}

The screen capture shown the overall directory structure of platformIO setup as well as the response received from the test server (httpbin.org).

For reference, here is the system setting of my PlatformIO show during the compilation.
PLATFORM: Espressif 32 (6.9.0) > Espressif ESP32 Dev Module
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
 - framework-arduinoespressif32 @ 3.20017.0 (2.0.17)
 - tool-esptoolpy @ 1.40501.0 (4.5.1)
 - tool-mkfatfs @ 2.0.1
 - tool-mklittlefs @ 1.203.210628 (2.3)
 - tool-mkspiffs @ 2.230.0 (2.30)
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5

This is all great, except the question says "There's a lot of Platform.io stuff but I'm not using that".  I'm looking for something I can build with arduino-cli or (worst case) the Arduino IDE.   In your solution what is rootca_crt_bundle_start?  Is it the cert bundle itself or some sort of pointer into the flash filesystem?

It is a pointer to the binary CA cert bundle in data/cert

Let me know if you find something work for Arduino IDE. The second option described in the README that I linked should work for Arduino IDE, but It requires you to load the pen file from SPIFFS, but it will take up 200KB+ RAM space...

Unless I'm missing something, Store the bundle as a SPIFFS file, but then you have to load it into RAM in runtime and waste 64k of precious memory but neither the v2 nor v3 READMEs tell me what I then need to do with the bundle; do I just pass it directly to setCACertBundle() ?  It seems everyone is using PlatformIO now, so I can't find any examples not using it!!

I think I worked it out.  It didn't help that the data structures changed format in esp-idf and arduino-esp32 is using an older version!  But it seems to work :-)


text:
Multichannel communication with Arduino and HC-12 transmitter
The HC-12 module has 100 possible channels starting at 433 MHz. Can someone tell me how to program the Arduino to use multiple channels at the same time? My goal is to build an RC transmitter with Arduino and an HC-12 module for a quadcopter. Therefore I need 6 channels, like a normal transmitter does. Thanks in advance!

I believe you are misunderstanding what it means by channels. The HC-12 can transmit on up to 100 channels, which means different frequencies under the 433 MHz band. For example 433.05 MHz or 433.15 MHz. This is so multiple HC-12 modules can be used next to each other and only the module receiving on the channel of the transmitter will receive the data broadcast.
What you need to do for your quadcopter is send an array of bytes that begins with a constant, followed by the data you need (a packet). Example:
byte packet[] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}

// in your loop
packet[1] = ; HOW MUCH THE ENGINE IS THROTTLED
packet[2] = ; HOW FAR THE CONTROL TO GO FORWARD IS DEPRESSED
// etc

Iterate through this array writing the data through the serial port to the HC-12. Whenever your receiver detects the constant (in this case 0x00) read the values that follow as the controls for the quadcopter.

I'm starting on HC-12 myself and as I understand, you can only access 1 module at a time by selecting each modules individual channel, assuming you have set the modules to separate channels, you cannot receive data from multiple modules even if set to the same channel at the same time, it would just be a jumble of unsortable data. But you may be able to select one channel after another and collect each set of data separately 1 thru 6 and then extract the information you need by using AT+C001,002,etc. Or you could use 1 RX and program the on board arduino to cycle thru the 6 motors sequentially and collect the 6 sets of data that way. this question would be easier to answer with a diagram of you proposed circuit.

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

authors: Стоян Димитров


text:
HTTP post request in JSON Format using SIM900 module
I tried to send HTTP post requests to a server in JSON Format using a SIM900 module. But the code is not posting the data. While posting the data I'm getting the error response while initializing the server using the command:
{("AT+HTTPPARA=\"URL\",\"http://test.server/insert-path")}

I don't know what the error is and how to fix it. Please help me to fix this.
#include<SoftwareSerial.h>

SoftwareSerial client(2,3);

String testReading="{  \"testID\" : 1,  \"testLevel\" : 1, }";

void setup() {
  Serial.begin(9600);
  client.begin(9600);
  delay(1000);
  if(client.available()) {
    Serial.print("Connected");
  } else {
    Serial.print("Not Connected");
  }
  checkSignal();
  connectGPRS();
  postData();
  delay(1000);
}

void loop() {
  if(client.available()) {
    checkSignal();
    connectGPRS();
    postData();
    delay(1000);
  }
}

void connectGPRS() {
  client.println("AT+CGATT?");
  delay(1000);
  ShowSerialData();
  client.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
  delay(1000);
  ShowSerialData();
  client.println("AT+SAPBR=3,1,\"APN\",\"www\"");
  //Using Indian Standard Vodafone Sim and so APN is www
  delay(1000);
  ShowSerialData();

  client.println("AT+SAPBR=1,1");
  delay(1000);
  ShowSerialData();

  client.println("AT+SAPBR=2,1");
  delay(1000);
  ShowSerialData();
}

void checkSignal() {
  client.println("AT+CSQ");
  delay(1000);
  ShowSerialData();
}

void ShowSerialData() {
  while(client.available()!=0)
    Serial.write(client.read());
}

void postData() {
  client.println("AT+HTTPINIT");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPPARA=\"CID\",1");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPPARA=\"URL\",\"http://test.server/insert-path");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPPARA=\"CONTENT\",\"application/json");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPDATA=99,10000");
  delay(1000);
  ShowSerialData;

  client.println(testReading);
  delay(1000);
  ShowSerialData;

  client.println("AT+HTTPACTION=1");
  delay(10000);
  while(!client.available());
  ShowSerialData();
}

Give us a clue - how far does it get? What does it do?

This code will post the manually given data in the Arduino to the server.It's just a sample code.I'm using SIM 900 to establish GPRS connection.

The connections are been establishing between the SIM and Arduino sometimes GPRS is been connected but the data is not been send to the server..

Can you post to the server using a PC (not on the server's local network)? Are you sure the server is working and accessible? Do the server's logs show the failing connections? Are we looking for a connectivity problem or a problem with the data it's sending?

It's worth mentioning that if you're relying on your ShowSerialData() function to know what's going on, it may not be reliable. Serial data does not all appear in one go.  Your code relies on a race - the data arriving fast enough for there always to be some in the buffer.  You can hack it by adding a delay(1000) right at the start of ShowSerialData().

Thanks.. I have delayed that.. The error is while initializing the URL.. When I send the command {("AT+HTTPPARA="URL","http://test.server/insert-path")}.. I'm receiving ERROR response.. I even delayed the time at posting the data and at initializing the HTTP.. But still I'm getting ERROR response..

Could you edit your question to include this information, please? I suspect I won't be able to solve it for you, but the clearer you make the question, the more likely someone else will.

Thanks Mark for your help.. If you got any idea of solving this please ping me..

Hi all use this code below for establishing HTTP connection with the server. And to neglect the 601 or 504 error use proper posting format. Here I'm using JSON format. I just gave manual data. Ignore those errors in HTTPINIT, AT+SAPBR=2,1. The data will be posted to the server
 #include<SoftwareSerial.h>

SoftwareSerial client(2,3);

String reading="{  \" : 1,  \"latitude\" : 12.983027,  \"longitude\" : 80.2594,  \"timestamp\" : 100,  }";

void setup()
{
  Serial.begin(9600);
  client.begin(9600);
  delay(500);

  if(client.available())
  {
    Serial.print("Connected");
  }
  else
  {
    Serial.print("NotConnected");
  }

  //initSIM();
  connectGPRS();
  connectHTTP();
}

void loop()
{

}

void connectGPRS()
{
  client.println("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
  delay(1000);
  ShowSerialData();

  client.println("AT+SAPBR=3,1,\"APN\",\"www\"");//APN
  delay(1000);
  ShowSerialData();

  client.println("AT+SAPBR=1,1");
  delay(1000);
  ShowSerialData();

  client.println("AT+SAPBR=2,1");
  delay(1000);
  ShowSerialData();
}

void connectHTTP()
{
  client.println("AT+HTTPINIT");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPPARA=\"CID\",1");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPPARA=\"URL\",\"http://xxx.xxx.xx/Listener/\"");//Public server IP address
  client.println("AT+HTTPPARA=\"URL\",\"http://testServer/Listener/\"");//Public server address
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPPARA=\"CONTENT\",\"application/json\"");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPDATA=" + String(reading.length()) + ",100000");
  delay(1000);
  ShowSerialData();

  client.println(reading);
  delay(1000);
  ShowSerialData;

  client.println("AT+HTTPACTION=1");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPREAD");
  delay(1000);
  ShowSerialData();

  client.println("AT+HTTPTERM");
  delay(1000);
  ShowSerialData;
}

void ShowSerialData()
{
  while(client.available()!=0)
  {
  Serial.write(client.read());
  delay(100);
  }
}

client.println(reading);
delay(1000);
ShowSerialData;

The above line of code would result in an error.

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


text:
Trying to pass a char to software serial with a button press
Good day everyone,
I'm returning to the Arduino world after my a 3 year hiatus following the birth of my son.
I'm trying to push a button connected to pin 2 and have that send a 'd' to SoftwareSerial on pins 10,11. This should trigger an output back from the device connected to the SoftwareSerial.
I'm encountering an issue:
When I press the button it sends about 15 d's. I would like to limit this to just one char per button press, I attempted to build an if statement but it seems to ignore the conditions.
#include <SoftwareSerial.h>
// software serial #1: TX = digital pin 10, RX = digital pin 11
SoftwareSerial portOne(10, 11);
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int button1State = 0;

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // Start each software serial port
  portOne.begin(4800);
  while (!portOne) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

// the loop function runs over and over again forever
void loop() {
  int Once = 0;
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH ) {
    if (Once == 0) {
      Once = 1;
      // turn LED on:
      digitalWrite(ledPin, HIGH);
      // send D to Radio
      portOne.write("d");
      Serial.write("d");
      Serial.print(Once);
      Serial.println();
      delay(1);
    }
  }
  else (buttonState == LOW) {
    // turn LED off:
    Once = 0;

    digitalWrite(ledPin, LOW);

  }
  portOne.listen();
  // while there is data coming in, read it
  // and send to the hardware serial port:
  while (portOne.available() > 0) {
    char inByte = portOne.read();
    Serial.print(inByte);
  }
}

There's built in code formatting in the post editor, use it to format your code correctly. It looks like {}.

You should debounce your button. 2) You should qualify Once as static, otherwise it's reset to zero (actually, recreated) every time you enter loop().

Thank you Edgar, qualifying Once as static fixed it! I didn't realize it was getting cleared everytime, driving me crazy!

Now comes the second part. When I first boot up the device connected to portOne I see the boot-up message, however after I press the switch and see d1 on the serial monitor I get nothing back from the other device.

When I connect the device directly to my computer and press d I see a five line status output from the device. Based on my Sketch that should be echo'd back to the serial monitor however I see nothing but the d1, any ideas?

As Edgar stated my issue was I didn't make the Once variable static
"1) You should debounce your button. 2) You should qualify Once as static, otherwise it's reset to zero (actually, recreated) every time you enter loop()."

As pointed out by Edgar you should debounce the button. Perhaps increasing the delay() should do the trick.
Try with 100-200 milliseconds.
With this edit you can delete Once unless you are planning on using it somewhere else.

If he deletes Once, it will repeatedly send characters when the button is held down.


text:
Digital Band pass filter arduino 1100-1300 Hz
For a project I need to design an digital band pass filter. I started of with this in Matlab:
wch=1100*2*pi;
wcl=1300*2*pi;

sys=tf([1/wch 0],[1/(wch*wcl) 1/wch+1/wcl 1])
sysd=c2d(sys,9615,'tustin')

so I got this values:

3.01e-08 z^2 - 3.01e-08/(z^2 + 2 z + 1)

Then I rewrote it to:
y[k] = 3.01*10^-8*u[k]-3.01*10^-8*u[k-2] -y[k-2]-2y[k-1]

and so I put hoped that this arduino script should do the Job:
#include <TimerOne.h>

float out;

float second_filt(float x0) {
  static float y1=0;  // y[n-1]
  static float y2=0;  // y[n-2]
  static float x1=0;  // x[n-1]
  static float x2=0;  // x[n-2]
  float y0 = 3.01*10^(-8)*x0-3.01*10^(-8)*x2-2*y1-1*y2 ;

  // Shift values
  y2 = y1;  // Shift y[n-1] to y[n-2]
  y1 = y0;  // Shift y[n] to y[n-1]
  x2 = x1;  // Shift x[n-1] to x[n-2]
  x1 = x0;  // Shift x[n] to x[n-1]
  return y0;
}

void setup() {
  Timer1.initialize(32); //Initialize timer with a period of 32 us
  Timer1.pwm(9,0); // Use pin 9 for PWM
}

void loop() {
  if (isTime()) {
    out=second_filt(analogRead(0));
    Timer1.setPwmDuty(9,out); //Sets the duty cycle to the analog value on pin 0
  }
}

bool isTime(){ //Checks if 300 us elapsed since the last call
  static unsigned long t0=0;
  static unsigned long t1=0;

  t1 = micros();

  bool res = (t1-t0)>300;

  if (res) {
    t0 = t1;
  }
  return res;
}

Now I don't know what the error: 'invalid operands of types 'double' and 'double' to binary 'operator^' means and I am not sure if this is actually gonna work. Pleas help me out I have been busy with this for days.

You may have trouble getting this to work on an ATmega-based Arduino, especially if floating point which must be emulated in software.  If you encounter difficulty you might consider one of the more recent Teensy series boards which have a more capable processor and a faster ADC as well.

You cannot use ^ as mathematical power symbol in C. Ini C it means the exclusive-or bit operation (hence the error showing it is a bit operation).
For the mathematical power function, you should use the math C library. See library explanation. To include it, use:
#include <math.h>

The power function has the following prototype:
double pow(double x, double y)
Returns x raised to the power of y.

However if you only need to write a float/double in exponential format, you can use
3.01e-8

You have more than one problem here...

3.01e-08 z^2 - 3.01e-08/(z^2 + 2 z + 1)

I don't quite understand your Mathlab code, but there is something wrong
with this transfer function. The denominator can be rewritten as
(z + 1)2. Thus there is a double pole at
z = −1, i.e. at the Nyquist frequency. An infinite gain at
Nyquist is not what you expect from a bandpass filter.

y[k] = 3.01*10^-8*u[k] - 3.01*10^-8*u[k-2] - y[k-2] - 2y[k-1]

This is implementing the transfer function
3.01 × 10−8 (z2 − 1)/(z2 + 2 z + 1),
which is not the same as the one written above: mind the
parentheses.

float y0 = 3.01*10^(-8)*x0-3.01*10^(-8)*x2-2*y1-1*y2;

As explained in Michel Keijzers’ answer, the constant should be written
3.01e-8. Also, you can save one multiplication by writing it as
float y0 = 3.01e-8*(x0 - x2) - 2*y1 - y2;

if (isTime()) { out=second_filt(analogRead(0)); ... }

You cannot expect to get a uniform sampling time with analogRead(), as
your timing will depend on how long your program takes to get trough the
loop, which is data dependent and affected by interrupts.

sysd=c2d(sys,9615,'tustin')

I assume 9615 is the expected sampling rate, which translates to
104 µs between samples. This is the time it takes for the ADC to
perform one reading. You cannot achieve this rate if you do computations
in between the readings.
Here your best option is to configure the ADC in free-running mode. In
this mode it will take one sample every 104 µs, and you will
achieve the desired sampling rate. You should also do the filtering in
parallel with the readings, and have the CPU and the ADC work
concurrently instead of sequentially. For implementing this, you will
first have to read the datasheet of the ATmega328P powering your Uno.


text:
Why am I receiving this Error: Debug exception reason: Stack canary watchpoint triggered (task1) in ESP32 using a FreeRTOS program?
I'm getting this error by running a FreeRTOS program on my ESP32 using arduino ide, I don't understand why this happens because this same program works on an arduino Uno with no errors:
Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception).
Debug exception reason: Stack canary watchpoint triggered (task1)
Core  0 register dump:
PC      : 0x40088a4f  PS      : 0x00060636  A0      : 0x800d3155  A1      : 0x3ffb9130
A2      : 0x3ffb8eb4  A3      : 0xffffffff  A4      : 0x00060620  A5      : 0x00060623
A6      : 0x00060623  A7      : 0x00000001  A8      : 0x00000001  A9      : 0x00000000
A10     : 0x00060623  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000000
A14     : 0x007bee88  A15     : 0x003fffff  SAR     : 0x00000000  EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000

This is the code I'm using:
//#include <Arduino_FreeRTOS.h>
//Overload happens if xTaskGetTickCount – lastTickCount (the first parm to vTaskDelayUntil) is >= period in ticks

void task1(void *pvParameters);
void task2(void *pvParameters);
void task3(void *pvParameters);

void setup() {

  Serial.begin(115200);

  //Create tasks
//xTaskCreate(Task function, Task name, , Task parameter, Task priority, );
  Serial.println("111111");
  xTaskCreate(task1, "task1", 512, NULL, 1, NULL);
  Serial.println("222222");
  xTaskCreate(task2, "task2", 512, NULL, 2, NULL);
  xTaskCreate(task3, "task3", 512, NULL, 3, NULL);
  //vTaskStartScheduler();

}

void loop() {}

void task1(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1){

    Serial.println('M'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period)
      Serial.println("Overload in task 1");

    vTaskDelayUntil(&waketime, period);

  }

}

void task2(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('E'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 2");
    vTaskDelayUntil(&waketime, period);

  }

}

void task3(void *pvParameters) {

  (void) pvParameters;
  TickType_t waketime, period = 1000 / portTICK_PERIOD_MS;

  waketime = xTaskGetTickCount();

  while(1) {

    Serial.println('S'); //This happens almost immediately, so we need to add an artificial delay, a  to simulate a task running for a few ms, it only serves as a notification that the task started
    vTaskDelay(10);
    if(xTaskGetTickCount() - waketime >= period) Serial.println("Overload in task 3");
    vTaskDelayUntil(&waketime, period);

  }

}

I tried increasing the task stack memory in xtaskcreate and the same error occurs, although when I increased it to 1024 nothing shows up in the serial monitor. This same program works flawlessly on arduino uno and raspberry pi pico. I also tried changing the tasks' period and their execution time, which is the delay, and it still doesn't work

although when I increased it to 1024 nothing shows up in the serial monitor.

Doing nothing to your code except using 4096 for stack size causes it to print things on serial.
rst:0x1 (POWERON_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:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0
111111
222222M

E
S
S
E
M
S
ME

I won't tell you that it's correct, but it seems fairly clear that you haven't given it enough stack to work with.
With my current setup
Serial.println(configMINIMAL_STACK_SIZE);

is printing 828. I don't know how exactly how to interpret that number. But unless I found otherwise, I could default to considering it the requirement to start a task that uses no stack of it own (no local variables, no calling). The memories of the esp32 seem large enough that no matter how you're using them it doesn't make sense to go so minimal for a handful to tasks. I chose 4096 somewhat arbitrarily. I'm not suggesting is a good value.


text:
Error with Mega2560 via SPI
I tried the following code to communicate via SPI with MPU9250 and Mega2560 But I got the following error:
Error initializing communication with IMU
Why I got this error?
/*
* Brian R Taylor
* brian.taylor@bolderflight.com
*
* Copyright (c) 2021 Bolder Flight Systems Inc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the “Software”), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#include "mpu9250.h"

/* Mpu9250 object, SPI bus, CS on pin 10 */
bfs::Mpu9250 imu(&SPI, 10);

void setup() {
  /* Serial to display data */
  Serial.begin(115200);
  while(!Serial) {}
  /* Start the SPI bus */
  SPI.begin();
  /* Initialize and configure IMU */
  if (!imu.Begin()) {
    Serial.println("Error initializing communication with IMU");
    while(1) {}
  }
  /* Set the sample rate divider */
  if (!imu.ConfigSrd(19)) {
    Serial.println("Error configured SRD");
    while(1) {}
  }
}

void loop() {
  /* Check if data read */
  if (imu.Read()) {
    Serial.print(imu.new_imu_data());
    Serial.print("\t");
    Serial.print(imu.new_mag_data());
    Serial.print("\t");
    Serial.print(imu.accel_x_mps2());
    Serial.print("\t");
    Serial.print(imu.accel_y_mps2());
    Serial.print("\t");
    Serial.print(imu.accel_z_mps2());
    Serial.print("\t");
    Serial.print(imu.gyro_x_radps());
    Serial.print("\t");
    Serial.print(imu.gyro_y_radps());
    Serial.print("\t");
    Serial.print(imu.gyro_z_radps());
    Serial.print("\t");
    Serial.print(imu.mag_x_ut());
    Serial.print("\t");
    Serial.print(imu.mag_y_ut());
    Serial.print("\t");
    Serial.print(imu.mag_z_ut());
    Serial.print("\t");
    Serial.print(imu.die_temp_c());
    Serial.print("\n");
  }
}

Source code:
https://github.com/bolderflight/invensense-imu/blob/main/examples/arduino/mpu9250/spi/spi.ino
Connection:
MPU9250                 Mega 2560
    GND <.............> GND
    3V3 <.............> 3.3V
    SCL <.............> pin 52
    SDA <.............> pin 51
SDC/SA0 <.............> pin 50
    CSB <.............> pin 53

This is the sensor ( IMU 10DOF SENSOR MODULE MPU9250 BMP280 ( GY-91 ))
But I only interested on the MODULE MPU9250 readings via SPI

Is your Mega 5 VDC? Do the I/Os on the MPU9250 operate at 3.3 volts or are they 5 volt tolerant?

did you use the correct pins?

you got that error because the following program line runs when IMU does not return a successful start status ... Serial.println("Error initializing communication with IMU");

so, your question should really be asking why does imu.Begin() fail?


text:
Creating Arduino library file
I need to create a library file for Arduino. While surfing the Internet, it shows me to use C, C++. Is a C++/C compiler mandatory to create library files in Arduino? Or we can use the Arduino IDE to create library files?

Libraries are just text files. Use your favourite text editor (such as Sublime Text, Notepad++, etc. NOT a word processor like Word) to create and edit them. It is up to the IDE to compile them for you. You don't need anything else.

The Arduino IDE has a compiler, and will in the end compile the library with whatever .ino script you'll write. But you don't need any compiler to write a library. All you need is a text editor, and produce .cpp and .h files.
However when you test the library, you'll have to use the Arduino IDE to compile it.

Thank you.. So there's no need to install an external IDE to compile library files.

no, there is no such need


text:
Program Arduino Uno via Nano
To keep the question short:
I'm trying to burn a bootloader on my Arduino Uno using an Arduino Uno. Could someone please tell me the pin connections? Thanks.

To burn a bootloader from source Nano to target Uno make the following connections:
Nano.Pin   Uno.Pin

10         Reset

11         11

12         12

13         13

GND        GND

See here for more details: https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard


text:
How to store a string in an object and retrieve it safely later?
I'm writing a program where I will be able to toggle between multiple banks, and each bank has 4 presets on it. Right now, I'm trying to give each preset a name that is assigned on creation.
I have an object I called StoredDataManager, which will handle all the banks. In its constructor, I do this:
for (byte i = 0; i < NUMBER_OF_BANKS; i++) {
  Bank bank;
  _banks[i] = &bank;
}

_banks is declared like this: Bank* _banks[NUMBER_OF_BANKS]; in the .hfile of StoredDataManager.
A bank has 4 presets, like this:
Preset* _A;
Preset* _B;
Preset* _C;
Preset* _D;

Which I initialize as this:
Preset preset(presetName, presetData);
...
_A = &preset; ...

Where presetName is "CHR", and presetData doesn't matter, because I'm just trying to get the name to work.
In the preset, the name is saved like this: char _presetName[4];.
It is returned like this:
char* Preset::getPresetName() {
  return _presetName;
}

I try to print a preset's name like this:
Serial.println(_banks[0]->getPreset('A')->getPresetName());

But, right now it simply returns C§.
Why is that? I suspect it has to do with the memory being erased or overwritten.
EDIT:
Here is the code of getPreset:
Preset* Bank::getPreset(char presetLocation) {
  switch (presetLocation) {
    case PRESET_LOCATION_1:
      return _A;
    case PRESET_LOCATION_2:
      return _B;
    case PRESET_LOCATION_3:
      return _C;
    case PRESET_LOCATION_4:
      return _D;
    default:
      return NULL;
  }
}

I think now that I'll turn this into 4 separate functions, like getA, getB and so on, but this what it is the moment. PRESET_LOCATION_1 is just a #define PRESET_LOCATION_1 'A'.
EDIT 2:
I start in the main arduino .ino file with this:
void setup() {
  Serial.begin(9600);
  StoredDataManager storedDataManager;
}

This triggers this constructor:
StoredDataManager::StoredDataManager() {
  for (byte i = 0; i < NUMBER_OF_BANKS; i++) {
    Bank bank;
    _banks[i] = &bank;
  }
  _currentBankIndex = 0;
  Serial.println(_banks[0]->getPreset('A')->getPresetName());
}

This is _banks: Bank* _banks[NUMBER_OF_BANKS];.
The initializing of the bank object runs this constructor: (PRESET_LOCATION_1, 2, 3, and 4 just being 'A', 'B', 'C', 'D')
Bank::Bank() {
  addPreset("CHR", "Some data", PRESET_LOCATION_1);
  addPreset("CHR", "Some data", PRESET_LOCATION_2);
  addPreset("CHR", "Some data", PRESET_LOCATION_3);
  addPreset("CHR", "Some data", PRESET_LOCATION_4);
}

Which calls this function:
void Bank::addPreset(const char* presetName, String presetData, char presetLocaton) {
  Preset preset(presetName, presetData);
  switch (presetLocaton) {
    case PRESET_LOCATION_1:
      _A = &preset; break;
    case PRESET_LOCATION_2:
      _B = &preset; break;
    case PRESET_LOCATION_3:
      _C = &preset; break;
    case PRESET_LOCATION_4:
      _D = &preset; break;
  }
}

Then, above in the StoredDataManages constructor, this line is hit:
Serial.println(_banks[0]->getPreset('A')->getPresetName());

And that's where I try to log out the preset name.

The use of dynamic memory on a constrained system like avr and the word "safely" as a goal probably do not belong in the same posting.  That said, an immediate problem is that 'A' does not mean what you think it does - specifically it is an integer constant of value 65, ie, the ascii code of a capital A  You should probably show the code of getPreset()

@ChrisStratton I posted the code for getPreset(). I do know that it is the character 'A', though. As I mention at the end there, I'm probably going to change how I get the presets.

Where do you call preset()?  With a pointer to what?  That was initialized how?  Without including your code, this is unanswerable.

@ChrisStratton Tried to explain the flow together with the code now.

Just as a style thing, identifiers starting with an underscore and followed by an upper-case letter are reserved by the C++ standard. You should get out of the habit of using them for your own variables.

@Nick Gammon Thanks, didn't know that. Just seemed like the natural name when the preset location name was A :) Ill change it.

void Bank::addPreset(const char* presetName, String presetData, char presetLocaton)
{
  Preset preset(presetName, presetData);

  switch (presetLocaton)
  {
    case PRESET_LOCATION_1:
      _A = &preset; break;
    case PRESET_LOCATION_2:
      _B = &preset; break;
    case PRESET_LOCATION_3:
      _C = &preset; break;
    case PRESET_LOCATION_4:
      _D = &preset; break;
  }
}

I can't see how this is going to work because you are storing somewhere outside a function a pointer to a local variable inside the function. As soon as addPreset exits the variable preset will go out of scope, and a pointer to it will be undefined.

You should probably do a new to make a new instance of Preset which it is then valid to store outside the scope of the function.

Ah, ok. I was thinking as long as I stored a reference to it, the data at that memory location wouldn't be removed. I'll work on changing that tomorrow. Thanks! Any idea as to how I could create an object that would not be garbage collected that would work in this situation?

I'll try newing the objects tomorrow. I guess I have the same problem with the banks, then.

Yes, very much so. Don't assign to some variable a thing that will go out of scope, as you did there. As for garbage collection, there is no default garbage collection in C++.

Ah, right. It has been some time since I coded C++ :) Thanks!


text:
How to programmatically upload an Arduino sketch generated by node.js (electron) or from browser?
We are trying to make an app that generates an Arduino sketch (.ino) using Google's Blockly and node.js, and uploads it to Arduino.
Even after searching a lot, I am unable to find how to build and upload the generated code to the board. Is there any tool or API available for node.js to do the same?
Or could I call some binary for this function. Please help.

The tool for uploading to an Arduino is "avrdude", it's a command line application that Arduino uses in the background. I'm quote dure you can invoke/run it from nodejs

There is also arduino-builder.exe command line tool in Arduino IDE (since 1.6.6) so you can build and upload sketch programmatically.

Or you can install Sudar Muthu's Arduino Makefile (package arduino-mk on Debian-bases OSes), then just require("child_process").exec("make upload", callback);.

There are two things you need to do:

Compile the sketch into a .HEX file
Upload the sketch to the board

The first part can be done with arduino-builder which is part of the IDE since 1.6.6, or you can use one of various Makefile projects on a platform that supports make, or you can manually script it yourself calling the correct avr-gcc and avr-g++ commands. You can check the output of the IDE for what those are.
The second part is done, usually, using avrdude - again see the output of the IDE for the correct command format.

Thanks a lot.. Also can I package only the required files/folders from the Arduino IDE into my software (without any license issues)?


text:
Huge nested loop in Arduino
I am completely new to programming and I am trying a brute force programming on my garage door opener. I want to use an Arduino for learning purposes. I wrote the following program that finally did what it should and now I am wondering whether there is a shorter code that does the same. Is anyone able to help me in that matter?
I do know that about 2^12 possibilities existed so I ran through all of them. I also knew that some parts of the "pulsetrain" (the set of necessary pulses) start with a particular sequence that is always the same (for all "brute forced" trains) and that the closing sequence is also always identical. I then simply wrote that down in the following, nasty code:
/*
  Transmitter is connected to Arduino Pin #2
*/

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

void pulsetrain(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m) {
  PORTD &= ~_BV(PD2);
  //set to LOW, hardwired to make it faster, see http://www.instructables.com/id/Arduino-is-Slow-and-how-to-fix-it/?ALLSTEPS
  delayMicroseconds(283); // (D2)
  PORTD |= _BV(PD2); //set to HIGH
  delayMicroseconds(566);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(283);
  PORTD |= _BV(PD2);
  delayMicroseconds(566);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(a);
  PORTD |= _BV(PD2);
  delayMicroseconds(b);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(c);
  PORTD |= _BV(PD2);
  delayMicroseconds(d);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(e);
  PORTD |= _BV(PD2);
  delayMicroseconds(f);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(g);
  PORTD |= _BV(PD2);
  delayMicroseconds(h);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(i);
  PORTD |= _BV(PD2);
  delayMicroseconds(j);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(k);
  PORTD |= _BV(PD2);
  delayMicroseconds(l);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(m);
  PORTD |= _BV(PD2);
  delayMicroseconds(283);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(566);
  PORTD |= _BV(PD2);
  delayMicroseconds(283);
  PORTD &= ~_BV(PD2);
  delayMicroseconds(566);
  PORTD &= ~_BV(PD2); // last LOW
}

void loop() {
  int signals[2] = {283, 566};
  for (int a = 0; a < 2;  a++) {
    for (int b = 0; b < 2;  b++) {
      for (int c = 0; c < 2;  c++) {
        for (int d = 0; d < 2;  d++) {
          for (int e = 0; e < 2;  e++) {
            for (int f = 0; f < 2;  f++) {
              for (int g = 0; g < 2;  g++) {
                for (int h = 0; h < 2;  h++) {
                  for (int i = 0; i < 2;  i++) {
                    for (int j = 0; j < 2;  j++) {
                      for (int k = 0; k < 2;  k++) {
                        for (int l = 0; l < 2;  l++) {
                          for (int m = 0; m < 2;  m++) {
                            pulsetrain(signals[a], signals[b], signals[c], signals[d], signals[e], signals[f], signals[g], signals[h], signals[i], signals[j], signals[k], signals[l], signals[m]);
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Just look at at like 283 is a low bit, and 566 is a high bit. So a-m would become a 13 bit number. Loop through those numbers with a for loop (0-8191). Then in the pulsetrain function read one bit, apply the delay of 283 or 566 based on the bit being 0 or 1. Then shift all the bit (left or right), and repeat (13 times).

My problem is not that I cannot program the opener (the above code did what it should) and I also understand the Manchester Coding. I wanted a code that does the same but consists of less than the above 84 lines! I do not know how to handle binary() and DecimalToBinary() (if it is even defined) with an arduino.

All those variables a, b, etc. are just the individual bits of a
13-bit number. When you loop through all combinations, you are actually
looping through all the possible numeric values of a 13-bit number.
This can be simplified as this (warning: not tested):
void setup() {
    pinMode(2, OUTPUT);
}

// the bitstream is: 0.101x xxxx.xxxx xxxx.0101
void pulsetrain(uint16_t code) {
    uint32_t bitstream = (((uint32_t) code) << 4) | 0x0a0005UL;
    for (uint8_t i = 0; i < 21; i++) {
        PIND = _BV(PD2);    // toggle pin
        if (bitstream & 0x100000)
            delayMicroseconds(566);
        else
            delayMicroseconds(283);
        bitstream <<= 1;
    }
    PORTD &= ~_BV(PD2); // last LOW
}

void loop() {
    for (uint16_t code = 0; code < 0x2000; code++) {
        pulsetrain(code);
    }
}


text:
Error taking address of temporary array when passing compound literal array
I have an Arduino sketch that passes an array into a method as a compound literal, but for some reason I keep getting the following error:

void setup() { }
void printConcatLine(char chunks[][20]) { }

void loop() {
  printConcatLine((char[][20]){ "{", "255", "}" });
}

I've also tried passing the number of the pointers/length of the array, and explicitly terminating it:
void setup() { }
void printConcatLine(char *chunks[]) { }

void loop() {
  printConcatLine((char*[]){ "{", "255", "}", NULL });
}

...and
void setup() { }
void printConcatLine(char chunks[][20]) { }

void loop() {
  printConcatLine((char[][20]){ "{", "255", "}", "" });
}

But they both produce the same error.
What is the correct method of passing the compound literal array as a method parameter?

You can't. You have to assign it to something then pass that variable.

Either that or rewrite your function to use variadic arguments.

Is this limitation specific to Arduino? From what I understand you can do this in C.

I am not sure, but I suspect it's a consequence of the AVR being a Modified Harvard Architecture CPU.

https://stackoverflow.com/questions/32941846/c-error-taking-address-of-temporary-array

What are you actually trying to achieve with that function anyway?

I needed a method to print any number of strings/variables together in a single line, to get past the limitation of having to send one at a time to Serial.print. I wanted to achieve the same functionality of something similar to: Serial.println( "{" + var1 " - " + var2 + "}" );

Actually Arduino uses C++.

You can't with the Arduino. I am not quite sure why, but I think it may be because it's a Modified Harvard architecture machine.
You can better achieve what you want with variadic arguments, however:
void printConcatLine(int num, ...) {
    va_list ap;
    const char *s;

    va_start(ap, num);
    for (int i = 0; i < num; i++) {
        s = va_arg(ap, const char *);
        Serial.print(s);
    }
    va_end(ap);
    Serial.println();
}

void setup() {
    Serial.begin(115200);
    printConcatLine(3, "{", "255", "}");
}

void loop() {

}

The first argument is the number of arguments that follow, and all the rest are string constants.


text:
HTTP request is not being executed in Arduino script for sending sensor data to Thingspeak cloud
I am trying to send the data from DHT sensor (temperature and humidity on 2 channels of Thingspeak cloud server) and firstly display them on Thingspeak cloud. Afterwards I will need to get those data from the cloud and use them with Python in order to make some calculations. Sensor data is sent via SIM900 GSM module.
I succeeded to send some constant value to Thingspeak by executing AT commands, one by one, which I put later in this code: https://pastebin.com/4bP6hgk7 EDIT: Here is the code:

#include <SoftwareSerial.h>
#include "DHT.h"

#define DHTPIN 2
#define DHTTYPE DHT11

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);

// Create global varibales to store temperature and humidity
float t; // temperature in celcius
float f; // temperature in fahrenheit
float h; // humidity

SoftwareSerial gsm(7, 8);

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

  gsm.begin(9600);
  Serial.begin(9600);

  gsm.println("AT+IPR=9600");
  delay(1000);

  gsm.println("AT+CGATT=1");
  delay(1000);

  gsm.println("AT+SAPBR=1,1");
delay(1000);

  ShowSerialData();

  gsm.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
  delay(1000);

  ShowSerialData();

  gsm.println("AT+SAPBR=3,1,\"APN\",\"prepaidnet\"");
  delay(1000);

  ShowSerialData();

  gsm.println("AT+SAPBR=3,1,\"USER\",\"mts\"");
  delay(1000);

  ShowSerialData();

  gsm.println("AT+SAPBR=3,1,\"PWD\",\"064\"");
  delay(1000);

  ShowSerialData();

  gsm.println("AT+SAPBR=1,1");
  delay(1000);

  ShowSerialData();

  gsm.println("AT+SAPBR=2,1");
  delay(1000);

   ShowSerialData();

   gsm.println("AT+HTTPTERM");
  delay(1000);

   ShowSerialData();

  gsm.println("AT+HTTPINIT");
  delay(2000);

  ShowSerialData();

  gsm.println("AT+HTTPPARA=\"CID\",1");
  delay(3000);

  ShowSerialData();

}

void loop() {
  // put your main code here, to run repeatedly:
  while(gsm.available()) {
    Serial.write(gsm.read());
  }
  if(Serial.available()) {
    gsm.write(Serial.read());
}

 t=readTemp();
h=readHum();

gsm.print("AT+HTTPPARA=\"URL\",\"https://api.thingspeak.com/update?api_key=Z1Q5633A4S1GHIHU&field1=26");
//gsm.print(t);
//gsm.println();
delay(5000);
//gsm.println((char)26);

ShowSerialData();

delay(1000);
gsm.println("AT+HTTPPARA=\"REDIR\",1");
delay(3000);
gsm.println("AT+HTTPSSL=1");
delay(3000);
gsm.println("AT+HTTPACTION=0");  /* Start POST session */
delay(5000);
gsm.println("AT+HTTPREAD");
delay(3000);
gsm.println("AT+HTTPTERM"); /* Terminate HTTP service */
delay(5000);
gsm.println("AT+SAPBR=0,1");
delay(3000);
ShowSerialData();

}

float readTemp() {
  // Read temperature as Celsius
  t = dht.readTemperature();
  //Read humidity
  h = dht.readHumidity();

  // Compute temperature values in Celcius
  t = dht.computeHeatIndex(t,h,false);

  // Check if any reads failed and exit early (to try again).
  if (isnan(t)) {
    Serial.println("Failed to read temp from DHT sensor!");
    return 1;
  }

  return t;
}

float readHum() {
  //Read humidity
  h = dht.readHumidity();
  // Read temperature as Celsius
  t = dht.readTemperature();

  // Compute temperature values in Celcius
  t = dht.computeHeatIndex(t,h,false);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h)) {
    Serial.println("Failed to read hum from DHT sensor!");
    return 1;
  }

  return h;
}

void ShowSerialData()
{
  while(gsm.available()!=0)
    Serial.write(gsm.read());
    if(Serial.available()) {
    gsm.write(Serial.read());
  }
}

The problem is that not the whole script is executed - AT+HTTPPARA command with the parameter "URL" and the URL where the data should be sent is not being executed. I have read many answers but could't find the answer for this. Could anybody help with this issue? Thanks in advance!

Line 99 should be a gsm.println not a gsm.print.

Thanks for the suggestion, but putting println didn't resolve the problem.


text:
Global JsonObject (ArduinoJson)
I know a global JsonObject shouldn't be used, but I have my reasons.
I have a JsonObject* functions and I want him to save the content of a file.
With

functions=new JsonObject(jsonBuffer.as<JsonObject>());

I can access the JsonObject, but not when I leave the method. Can someone help me to understand why?
(Don't give me a solution like: copy into a struct, I need a JsonObject ready to be read in all my code.
Full code:
JsonObject* functions;

void loadFunctions() {
  File file = SPIFFS.open("/functions.json", "r");
  if (!file) {
    Serial.println("Failed to open the file");
  }else{
    size_t size = file.size();
    if (size > 512) {
      Serial.println("File size is too large");
    }else{
      std::unique_ptr<char[]> buf(new char[size]);
      file.readBytes(buf.get(), size);
      DynamicJsonDocument jsonBuffer(256);
      DeserializationError error = deserializeJson(jsonBuffer, buf.get());
      if (error) {
        Serial.println("Failed to parse file ");
      } else {
        functions=new JsonObject(jsonBuffer.as<JsonObject>());
        Serial.println((*functions)["test"].as<String>()); //this doesn't work in another method
      }
    }
  }
}

did you call loadFunctions anywhere?

Yes and the last Serial.println works, but not if I use it in another method (after this method)

jsonBuffer is local to the function. When you leave the function the contents of jsonBuffer are lost.
functions just points to the internals of jsonBuffer to get its data (to save memory).
You can either:

Make the jsonBuffer global so it sticks around all the time, or
Have a secondary DynamicJsonDocument or StaticJsonDocument that is global to which you copy your objects once read from jsonBuffer.

Thank you, solved by using the second choice.


text:
Error while reburning bootloader to atmega328p by usbasp in Arduino IDE
I have got the Bootloaded ATMega328P-PU from China and I want to reburn new bootloader into it. For this I use UsbAsp programmer. I want to do it in Arduino IDE. But when I try to flash, for example, an empty flash it says that error:
 Using Port                    : usb
         Using Programmer              : usbasp
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : usbasp
         Description     : USBasp, http://www.fischl.de/usbasp/

avrdude: auto set sck period (because given equals null)
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: error: program enable: target doesn't answer. 0
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

But when I work in Avrdudeprog, it works without any problems.
How can I fix it?

what's the circuit ? the error is mainly about a bad connection to the chip.

Nop. When I work whith programs as Khazarma, AVRDUDESS andAvrdudeprog v3.3 it works without broblems

use Zadig 2.4 to change the driver for USBasp. USBasp works with 3 drivers but it seems the type of installed driver causes some problems in various software. khazama, progisp on one hand and Arduino on the other hand. despite all of them using avrdude.
libusb-win32 : khazama works, Arduino does not
WinUSB       : khazama doesn't work, Arduino works
libusbK      : both work

I must select libusbK. OK. I test

Can I ask one question? This chip is fron china and it worked very slow and in internal clock 8 MHZ. I watched video and here said that I must set fuse bits as:

L: 0xFF H: 0xDE E: 0x05 Lock:0x3F as in bootloader. But my chip broke. WHY? I don't know! How can I fix it without fuse doctor?

@E.M. the arduino has to operate from 16MHz. and when you use the 328 for the first time, it has a clock of internal 8MHz divided by 8 = 1MHz.
the fuses seem right except for Efuse. the value 0x05 means 256 words for bootloader which is not sufficient. use 0xFD for 2K words

@E.M.http://www.engbedded.com/fusecalc

But Bro this chip wont to work

Chip won't working. How can I write fuses here?


text:
Arduino digital pin input used to power device?
I am attempting to debug a W65C02 and I am using an Arduino Mega to look at the inputs and outputs of the device, which is behaving weird.
I have Pin 22 to 52 connected as INPUT on the MEGA and they are all connected to A0-A15 and D0-D7 on the 6502. However when I unplug my Arduino and keep the 6502 powered on it seems to stay on in that the power light is on. Is something fried or is this normal behavior?
Nothing else is plugged in to the Arduino except GND and the digital inputs.

EEVBlog covered this behaviour with a great explanation of what’s going on: https://youtu.be/2yFh7Vv0Paw

Arduino get the power from the port of 6502 via the protecting diod in the Arduino port. This the normal behavior.
// Mikael

It may be "normal" behaviour, but it is far from desired behaviour. Damage to the Arduino can be caused by it as the internal protection diodes get overpowered and blow. Best case: the diodes fail open circuit and you don't notice any difference. Worst case: diode fails short and the pin is permanently HIGH.

The best case is bad too, because it means that pin no longer has a protection diode, and can be burned out. This answer should be edited to say "DON'T DO THAT" in very strong terms.

tl;dr: Don't do that.
As a general rule with CMOS digital circuits you don't want logic pin input voltages to be significantly higher than the VCC power input. (The same is true for TTL for that matter.) Doing that risks damage to the circuit.
That means that if a chip/board is not powered, you should not drive the logic lines at all.
Carlmikael says the behavior you are seeing is normal. I would call it expected, but I would not call it normal. It's "a normal error response" to a circuit being driven in a way that could damage it.

I agree, that is " a normal error response" // Mikael


text:
ESP8266 returning 400 bad request
I am trying to get JSON data from my website using an HTTP GET request, but I'm getting a 400 bad request error. Can someone let me know why am I getting this error and how to fix that? I am tired of looking at online resources.
I am trying to fetch data from www.himalayavats.com/to_fetch/system_info.json
I am using this code:
#include <SoftwareSerial.h>

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

SoftwareSerial ESP8266 (rxPin, txPin);

unsigned long lastTimeMillis = 0;

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

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

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

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

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

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

I get this response every time:
AT+CWMODE=1

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

WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP

OK
AT+CIPMUX=1

OK

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

4,CONNECT

OK

AT+CIPSEND=4,43

OK
>
Recv 43 bytes

SEND OK

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

My JSON file on the website looks like this:
{"power" : "high"}

Why are you putting delay(1000); between ESP8266.println(cmd); and ESP8266.println("");? That's bound to break things...

@dda getting error on removing delay

What kind of error?

And anyway you should build your request so that the two CRLF are in the string, and send that.

@dda I have no idea about that

the delays are a substitute for waiting on confirmation from the esp. better use a library that makes the AT communication for you. for example the WiFiEsp library https://github.com/bportaluri/WiFiEsp

Take a look at the HTTP specification:
Request       = Request-Line              ; Section 5.1
                *(( general-header        ; Section 4.5
                 | request-header         ; Section 5.3
                 | entity-header ) CRLF)  ; Section 7.1
                CRLF
                [ message-body ]          ; Section 4.3

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

You don't send the CRLF (carriage return, line feed) at the end of your request line and at the end of the header at the same time of the request. Why the delay?
You also miss the obligatory host header.
Host = "Host" ":" host [ ":" port ] ; Section 3.2.2

getting the error without delay
AT+CWMODE=1
OK
AT+CWJAP="moto g","hvats555"
4,CLOSED
WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP
OK
AT+CIPMUX=1
AT+CIPSTART=4,"TCP","himalayavats.com",80
busy GET /to_fetch/system_info.json HTTP/1.1
ERROR


text:
Change the baud rate of HC-05
#include <SoftwareSerial.h>

SoftwareSerial BTSerial(10, 11); // RX | TX

void setup() {
  pinMode(9, OUTPUT);
  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
  BTSerial.begin(38400);
  // HC-05 default speed in AT command more
}

void loop() {
  // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTSerial.available())
    Serial.write(BTSerial.read());

  // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
    BTSerial.write(Serial.read());
}

I have tried this code but I am not able to change the baud rate. Please suggest me a solution.

Is your Serial Terminal set up with CRLF line endings?

Check you dont have the BT version with the button, then you use the button instead of pin 9

I played a lot with HC-05 and HC-06 until I understand the way they work. Now i've big Android App communicating with HC at 115200 bauds and sending and receving heavy data.
I hope these tips will help you and other guys and save you time:
1) the way the HC-05 and HC-06 detect end of AT command is different:
HC-05 (can be slave and master): each AT command must end by CRLF. So or you add CRLF in your Android code or you select the option "CRLF line ending" in your console.
HC-06 (only slave): need a "time" between AT Command. According to the data sheet if there is more than 1 sec, the HC consider this is the end. Even if your question is about the HC-05 I think it can be VERY interesting to understand the big problem which can happened with the "delay" between AT.
If you use a communication at 9600 bauds and type AT commands on serial monitor and echo both what HC reply and what you send, you will have such things: type AT+VERSION and see on serial monitor AT+OVKERSION  Why ? Because as the delay between each char is long, as soon as the HC had receive "AT" he thinks that's the command and start to reply "OK".
So with a HC-06 you must send the AT command in one "shoot" and then add a delay of 2 sec to be sure.
2) Problem of settings.
The HC save the speed you set as the name and the pin code. So trying to set the pin, name and speed in the setup funcion is not usefull as at each time the Arduino will reset, each time you'll try to set the data.
Also, factory setting of HC seems to be 9600 bauds.
So you have to create a small sketch, which you'll use only ONE time to set the HC. Like this:
Serial.begin(9600);
delay(2000);

// AT+NAMEXXX where XXX is the new name
Serial.print("AT+NAMEJOHNDOO");
delay(2000);

// AT+PINXXXX where XXXX new code (4 number)
Serial.print("AT+PIN1999");
delay(2000);

// AT+BAUDX where X from 1 to 8
// 1 -> 1200 Bauds
// 2 -> 2400 Bauds
// 3 -> 4800 Bauds
// 4 -> 9600 Bauds
// 5 -> 19200 Bauds
// 6 -> 38400 Bauds
// 7 -> 57600 Bauds
// 8 -> 115200 Bauds
Serial.print("AT+BAUD8");

This for HC-06. For HC-05 you must add CRLF and you don't need the delay.
Important: as, at the end of this sketch, the HC is now at 115200 bauds, you must havea serial.begin(115200) for comunicating with it. If you run this sketch two time, the second run will do nothing as the Arduino will try to comunicate at 9600 bauds with a HC listening at 115200.
3) Problem of speed.
On the Arduino, you can use the software serial lib only if you plan to send and receive at up to 19200 bauds. Some say it work at 38400 but I've had problems at this speed.
The best way it to avoid Software serial and use directly the basic RX and TX of the Arduino. Using that you can run at 115200 without any problem.
Even if this answer is a bit "outside the question" I hope this will help you working with the HC.

HC-05+Arduino+Android
The problem is the baud rate of devices. The default baud rate of HC-05 is 38400.  First of all set baud rate of HC-05 by using the AT commands (i.e. AT+UART=9600,0,0) to 9600. This baud rate will work with serial in Arduino as well as in android Bluetooth libraries/app without any problem.


text:
Arduino FM transmitter
I am wondering if it's possible to transmit on all frequencies at once using this module.
I know it's illegal to take over regular stations when others are trying to listen but I'm only planning to use it for short range (less than the length of my house).

No, this is a receiver only, not a transmitter.

I am wondering if it's possible to transmit on all frequencies at once using this module.

it is definitely possible to transmit on all frequencies at once NOT using that module: square waves are a combination of all sorts of frequencies and your arduino is good at producing that.


text:
4-wire shielded cable for I2C and power
I have two PCBs with ATmega328 that will communicate through I2C protocol. The master will also provide power for the slave, which is located at a relatively short distance (30-40cm or 12-16 inches).
Is it feasible to use the same cable for power (3.3V) and communication?
Thank you.

Sure. Why wouldn't it be? Power is (pretty) static and noiseless.
Just be warned that having the clock and data in the same twisted pair (if your cable has twisted pairs) could cause issues over longer distances. I2C isn't designed for running over cables like that - it's designed for routing round short traces on a PCB.

Thanks for the detailed answer. I'll give it a try and if something goes wrong, i'll try to find solution for noise mitigation. The thing is that near the cable(10 cm or 4 inches) there is a solenoid powered pump which is the reason i chose a shielded cable.


text:
For loop not running
I've been trying to get a for loop to run 9 times using the below code but can't get the loop to run.
void output() {
  int r;
  r = 1;
  Serial.println("Output");
  digitalWrite(Latch, LOW);
  for (int r=1; r >= 9;  r = r + 1) {
    Serial.println("Test");
    digitalWrite(DataOutput, Q[r]);
    digitalWrite(ClockPin, HIGH);
    digitalWrite(ClockPin, LOW);
  }
  Serial.println("Done For");
  digitalWrite(Latch, HIGH);
  digitalWrite(Latch, LOW);
}

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

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

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

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


text:
ATTiny85 Digispark clones failing USB handshake - how to program them?
I've recently bought a batch of ATTiny85 modules (Digispark clones) from China, and tried to write a first test program into them now. I noticed that they do seem to have some bootloader already installed since the P1 LED is flashing, but they do not seem to make any reasonable USB handshake.
(I have ordered other seemingly identical modules from a different seller on Ali before and was able to use them just fine.. so I generally know how to work with these.)
Linux dmesg shows me that a device was plugged in, but does not get any vendor or model ID. Windows tells me that 'the device last plugged in has failed enumeration'. This looks to me like the bootloader is incomplete or somehow broken.
So, as a next step, I tried to rewrite the AVR with an USBASP adapter over ISP, only to find out that the /reset pin apparently has been disabled via fuse bit.
I'm in some kind of a loop now... If the bootloader doesn't speak USB correctly, I can't use the Arduino IDE or avrdude or anything to write to it, and if the /reset is remapped I can't replace the bootloader via ISP to get USB working.
Can anyone provide a hint on how I can get these modules to work? Or should I just assume I bought a bad batch, throw them away and order fresh ones?

maybe you shouldn't order fresh ones, but not from sketchy Chinese clone manufacturers? Just a hunch, though...

maybe there is no usb firmware loaded into the devices  ... can you post the seller's device homepage?

@jsotola Their page said "arduino compatible" and the same standard feature list copied from all other vendors on AliExpress. A non-usb firmware makes little sense, since ISP needs a working /reset pin which is definitely deactivated...

"arduino compatible" may be referring to the hardware

Maybe needs install the bootloader and than try to upload the sketch.

I had problems too - SHORT: all about USB-hub or PC's root-hub and extension cables +Luck.
My ebay items were going under the name "Digispark Kickstarter ATTINY85 Arduino Micro USB Development Board" and naturally it came with no Digispark-(c)-right infringing markings from China. I kept my fingers crossed that my items would at least be AVRisp-programable..
So in high hopes I plugged in my China import into my trusty USB HUB2.0(which I always use at least as a current limiter) – after testing it first on a powerbank (>5secs blinky-blink)  .. checked for enumeration (which it did-but no driver yet) .. installed the DPinst[64].exe drivers.. and then kept getting messages like >>device failed to enumerate<<, etc. - the list of my failures:

determined directly plugged into a PC's USB root-hub rigged/minimalistic usb devices do not enumerate at all (all 0s)
with a certain USBAmale-to-USBAfemale extension cable with plastic-encasing(female side) the USBA device’s was not allowed to go "in" probably just for some millimeters to short.. the Data-lamella do not connect correct – just power's okay (blinky-blink) .. but no Windows device-recognition .. No-No!
AND reminding the FTDI black-listing dilemma I used PCs without out the drivers still – using the good old “USBview.exe” program to check on the enumeration (on all my available device the same .. previously plugged into my driver-enable PC or just into an “out of the fab”-one
idVendor:           0x16D0
idProduct:          0x0753
bcdDevice:          0x010B

so no mis-configuration of the bootloader through a >possibly mallign< Digispark clone dis-configurator (as I was thinking the FTDI schemes .. of course FTDI only did it to protect their name X-) – to stop getting accused for faulty devices coming from cheap chinese fake or clone-producers)
* EVEN tried to deinstall the Drivers with DPinst[64].exe /D .. which gave me .. Yes .. yet again “Drivers all installed properly!”..
.. and IN THE END .. I just went back to my old, initial “USB HUB-behind root-hub” configuration .. and Abra-ca-Zang .. the device just enumerated and registered as “Digispark Bootloader” (windows device manager under libusb-win32 Usb Devices)
and all went okay - reprogramming with the Arduino IDE - NO FUZZ!
.. The !very same! config I was using on my “first testings” (minus some fair time and headaches of debugging)
So my advice .. always do a Basic-Test on a USB Powerbank, USE an USB-Hub, check your cables - use ones you trusted before! – try as many options as you (may) have .. and use the tools at your hand .. down to PC-progs or an logic-analyzer or an Beagle USB / protocol analyer to check where the problem may be.. trace back your tracks and even retry..
There may be a suprise for you at the end of the rainbow!

Using Arduino IDE 1.8, I had a Windows did not recognize USB Device message.
I successfully installed the DigiSpark drivers but still the PC was not recognizing the Tiny85 development board. In the Arduino IDE I had  initially selected the DigiSpark (16.5 MHz default) as instructed in a YouTube video. I did some more research,  someone suggested trying a different board. I selected the DigiSpark (No USB 16 MHz) uploaded the Blink example.
The LED started to flash and windows stopped complaining about the unrecognized device. I removed the flashed board and plugged in another, Windows started complaining, I uploaded the sketch successfully windows stopped complaining. I removed the second board and installed the first one and there were no further issues with Windows.

What YouTube video, do you have a link?

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