message:
Heart Pulse sensor analog value doesn't change even if sensor pressed by finger

I have recently bought a Heart Pulse Sensor. Then, to check whether the sensor is working correctly or not, I uploaded this below code:

    void setup() {

     Serial.begin(9600);
    }

    void loop() {
     int sensorValue = analogRead(A0);

     Serial.println(sensorValue);
     delay(1);        // delay in between reads for stability
    }

I know, that this code doesn't calculate the actual BPM. It sends 380-400 sensor value through
the Serial monitor, while the sensor is not being pressed by my finger. But when I press it with
my finger, the sensor value doesn't even come out of the range 380-400. But the sensor value was supposed to jump over 500 when a beat happened.

I think, that probably means my sensor is unable to detect beats. And now, my question is, why
my sensor is unable to detect beats?

After looking at some forums, I learned that this sensor can be a clone. After looking at my sensor
carefully, I found some little differences in my sensor than the sensors other people used in their
tutorials. And, the most spottable differences were:
*the colors of my sensor's pre-soldered jumper wires were different than other sensors.
*"pulsesensor.com" was written in the other sensors, but it wasn't written on my sensor

There were also some other differences. I have given three pictures of my pulse sensor below.

[![enter image description here][1]][1]
[![enter image description here][2]][2]
[![enter image description here][3]][3]

My final questions:-
1) Why my pulse sensor is unable to detect beats?
2) Is my pulse sensor a clone or not?
3) If it is a clone, can it be fixed somehow?
4) Do I need to buy another one?

That's all I know. Can anyone help me! Any help appreciated.

Thanks a lot!

  [1]: https://i.stack.imgur.com/jvfRL.jpg
  [2]: https://i.stack.imgur.com/t3n0r.jpg
  [3]: https://i.stack.imgur.com/Cxg4I.jpg

body:
Why my pulse sensor is unable to detect beats?

Chances are something wrong.  The only way to tell what specifically is to keep debugging.  If you don't have access to an Oscilloscope or Multimeter, this will involve checking your wiring and altering code.  To check wiring, make sure:
1) Minus (-) is to ground
2) Plus (+) s to your + voltage
3) S is to the A0.

Is my pulse sensor a clone or not?

It is likely.  Open-Source Hardware tends to have many clones.

If it is a clone, can it be fixed somehow?

Clones sell repeatedly if they work.  There is little point making a clone sensor that does not- if scamming was the point, one could ship empty envelopes.  If two different people make the exact same electronics, we hope that they behave very similarly regardless of who made them.

Do I need to buy another one?

Possible but unlikely.  If you can prove your sensor is defective, a seller might be willing to ship a replacement.

Try the following code to test the sensor.  My guess is that you are missing something due to Serial spamming.  Beyond that, taking a pulse may be tricky - the unskilled can easily pronounce some of the living as dead from just the wrist.  I suggest putting it to your throat to be on the safe side.

~~~

int minSV;
int maxSV;
unsigned int Frame;

void setup() {
 minSV=500;
 maxSV=0;
 Serial.begin(9600);
}

void loop() {
 int sensorValue = analogRead(A0);
 if(sensorValue > maxSV) maxSV = sensorValue;
 if(sensorValue < minSV) minSV= sensorValue;
 Frame = Frame +1;
 if(Frame > 10000) //would be 1s if frame takes 0.1 ms
 {
  //might want to reset min and max here after debug is complete and sensor is verified to work.  Until then, reset the arduino to reset min and max.
  Frame =0;
  Serial.print("Min: ");
  Serial.print(minSV);
  Serial.print("; Max: ");
  Serial.println(maxSV);
 }
 // removed: delay(1);        // delay in between reads for stability
}
~~~


sender: user

message:
Whats the best way to keep an Arduino in a waterproof junction box and prevent overheating?

I am trying to make an automatic garden gate unlock that runs on a timer. I plan on running an arduino uno 24/7 with a software timer that activates a motor to release a bolt lock. I am going to fit all the electronics and extension cord into a waterproof junction box. Will this cause over heating? Is there a need for some kind of waterproof cooling system? Has anyone ever built outdoor electronics and ran into this problem?

sender: assistant

body:
The linear regulator on an Arduino works by converting excess voltage to heat. If you power it with 12V and draw a full amp from it it will turn (12-5)*1a or 7 watts of power to heat, and quickly overheat even if it's not in a box.

If you power it from 6.5V and only draw 300mA from it, it will turn (6.5-5)*.3, or a little under half-a-watt. While the Arduino is idling it will probably only draw 50mA, so less than 1/10th of a watt of heat.

For infrequent, short bursts of a few seconds you can probably get away with drawing 500mA of power without overheating.

Or skip the internal regulator and use a buck style voltage regulator. Those generate a LOT less heat.

## Edit:

For a project I did recently, I used an external 5V regulated supply for everything. I cut a USB cable and soldered the red and black (+5V and ground) to the 5V supply, and plugged that into the Arudino's USB connector. That feeds 5V into the Arduino.


body:
The simplest selection is Aluminum water proof box.

You can make it yourself, using aluminum U profiles,
and mount arduino heat generator parts on the internal surface of the box.


message:
what library should I #include when using switch-case statement

I receive an error code of: `'switch' was not declared in this scope`

The code is correct so I assume that the necessary library was not included.

Please tell me the correct `#include` to use.

```c
swith(pwm){
  case 0:   Serial.print(pwm); Serial.print("   ");_delay_ms(2000);
            break;
  case 31:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 63:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 95:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 127:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 159:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 191:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 124:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 156:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 188:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 220:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  case 252:  Serial.print(pwm); Serial.print("   ");_delay_ms(100);
            break;
  default:  break;
}
```

body: It seems you have a syntax error: write `switch` instead of `swith`.


message:
how to convert the following code into one using direct port manipulation

Following is the program for scanning a keyboard for MIDI transfer.
At present the code works fine, but it could be faster.
I need to know how to use direct port manipulation inside the for loop.

    boolean keypressed[6][6]; //for storing key states
    int midinote[6][6] ={ 60 ,61 ,62 ,63 ,64 ,65
                     ,66 ,67 ,68 ,69 ,70 ,71
                     ,72 ,73 ,74 ,75 ,76 ,77
                     ,78 ,79 ,80 ,81 ,82 ,83
                     ,84 ,85 ,86 ,87 ,88 ,89
                     ,90 ,91 ,92 ,93 ,94 ,95  }; //code for various midi notes C3 to C6

    void setup() {

       Serial.begin(38400);
       for(int i=0; i<6; i++){
          pinMode(i+2,OUTPUT);
          digitalWrite(i+8,HIGH);
       }
       for(int i=0; i<6; i++){
          pinMode(i+8,INPUT);
          digitalWrite(i+8,HIGH);
       }
       for(int i=0; i<6; i++){
          for(int j=0; j<6; j++){
              keypressed[i][j] = false;
              }
          }
       }
    void loop() {

       for(int i=0; i<6; i++){
          digitalWrite(i+2, LOW);
          for(int j =0; j<6; j++){
             if ((digitalRead(j+8) == LOW) && !keypressed[i][j]){
                Serial.write(0x91);
                Serial.write(midinote[i][j]);
                Serial.write(127);
                keypressed[i][j] = true;
               }
             if ((digitalRead(j+8) == HIGH) && keypressed[i][j]){
                Serial.write(0x91);
                Serial.write(midinote[i][j]);
                Serial.write(0);
                keypressed[i][j] =false;
             }
          }
    digitalWrite(i+2, HIGH);
       }

     }

body:
It is better to use interrupts instead of pooling pins.
but this is related to your arduino controller.
what is you arduino core controller?
if you can select I prefer "Nano 33 IoT " which has 9 pins (2, 3, 9, 10, 11, 13, 15, A5, A7) available for interrupt.
this page may be usable:
https://playground.arduino.cc/Main/PinChangeInterrupt/


message:
What is the maximum size of Static Json Document in Arduino JSON?

I'm trying to do serial communication between Arduino mega and a esp8266, and having issues with determining the size of the JSON document. I have read that the receiver buffer size should be greater than the sender buffer, but what's the maximum buffer size we can use for the JSON document?

body:
The Arduino Mega has 8 KB of RAM, all of which you could use in a [StaticJsonDocument](https://arduinojson.org/v6/api/staticjsondocument/).

The ESP8266 has 80 KB of RAM, but the [core limits the stack to 4 KB](https://github.com/esp8266/Arduino/blob/eea9999dc5eaf464a432f77d5b65269f9baf198d/cores/esp8266/cont.h#L27). If you need something bigger, switch to a [DynamicJsonDocument](https://arduinojson.org/v6/api/dynamicjsondocument/).

In both cases, you need to leave a lot of room for other variables and libraries. As an example, I wouldn't create a [StaticJsonDocument](https://arduinojson.org/v6/api/staticjsondocument/) bigger than 6 KB on the Mega, and 2 KB on the ESP8266.

By the way, I heard this library is [very well documented](https://arduinojson.org/v6/doc/), did you have a look?
Do you know you can use the [ArduinoJson Assistant](https://arduinojson.org/v6/assistant/) to help you decide the capacity of the JsonDocument?


message:
Arduino CH340 Driver Problem

I'm trying to connect my Arduino Uno to the Arduino IDE in Windows, but the only way it works is with a CH340 driver.

I am concerned about this as I can only find a download of it published by two Chinese companies- wch.cn or Jiangsu Qinheng Co., Ltd.- maybe they're both 1 company; even when Windows looked for a driver on the web that was the one it downloaded.

When I went to Device Manager to look for the driver in the official Arduino download zip, Windows said it couldn't find any drivers.

I am concerned about the security implications of the driver being Chinese and wonder if there are any other CH340 drivers (unless CH stands for China...)

Anyway thx for answering!!! :)

body: WCH is the manufacturing company that first produced the CH340. They are Chinese.


message:
Serial Monitor shows a continuous "word salad" without a loop

I have written a little program which should (at the end) host a little website. This is just my setup. But for some reason, it writes "srl?" endlessly onto the serial monitor. I just connected the ESP8266-01 to my Arduino UNO, using 115200 baud with the nodeMCU board. Using different boards results in an error telling me I should use nodeMCU.

As I have written in the title, I do not understand how it can produce an endless output without a loop with ```Serial.print/write``` in it.

```
#include <ESP8266WiFi.h>

const char* NAME = "x"; //ssid
const char* PWRT = "x"; //password

WiFiServer server(80);

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

  Serial.printf("connect with %s \n", NAME);
  WiFi.begin(NAME, PWRT);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }

  server.begin();
  Serial.printf("webserver open, access with %s\n", WiFi.localIP().toString().c_str());

}

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

}
```

body:
The `ESP8266WiFi.h` is for running on an ESP8266 host, but your are trying to use it on an Arduino Uno. This caused the crash of your sketch on Arduino Uno.

Based on the connection diagram you provided, you are using the ESP-01 as an wifi-shield and the ESP-01 by default is having an AT commands firmware. In order to use the ESP-01 as a wifi shield, you need an library like [WiFiEspAT](https://github.com/jandrassy/WiFiEspAT).


message:
I can't upload codes to my ESP8266

[![This is the error it gives ][1],this is the error I encounter when i try to upload my code][1]

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

    #include <ESP8266WiFi.h>
    #include <ESP8266WiFiMulti.h>

    #ifndef STASSID
    #define STASSID "your-ssid"
    #define STAPSK  "your-password"
    #endif

    const char* ssid     = STASSID;
    const char* password = STAPSK;

    const char* host = "192.168.1.1";
    const uint16_t port = 3000;

    ESP8266WiFiMulti WiFiMulti;

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

      // We start by connecting to a WiFi network
      WiFi.mode(WIFI_STA);
      WiFiMulti.addAP(ssid, password);

      Serial.println();
      Serial.println();
      Serial.print("Wait for WiFi... ");

      while (WiFiMulti.run() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
      }

      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

      delay(500);
    }

    void loop() {
      Serial.print("connecting to ");
      Serial.print(host);
      Serial.print(':');
      Serial.println(port);

      // Use WiFiClient class to create TCP connections
      WiFiClient client;

      if (!client.connect(host, port)) {
        Serial.println("connection failed");
        Serial.println("wait 5 sec...");
        delay(5000);
        return;
      }

      // This will send the request to the server
      client.println("hello from ESP8266");

      //read back one line from server
      Serial.println("receiving from remote server");
      String line = client.readStringUntil('\r');
      Serial.println(line);

      Serial.println("closing connection");
      client.stop();

      Serial.println("wait 5 sec...");
      delay(5000);
    }

body: Try updating the Serial Driver in your system or try using lesser baud rate, i.e. 9600 instead of 115200.


message:
double type sensor data is not displayed on bluetooth terminal app on phone

Hi I am working on a project in which I am supposed to tell if a person is running/standing/walking and going upstairs/downstairs or he is on straight road. The person will carry a arduino uno module to which gps,bluetooth and altitude sensor is attached. Also I am trying to send my phone his speed and current altitude he is experiencing using HC-05 bluetooth module. I am sure that there is no problem with altitude sensor. Also I must note that my gps module(GY_NE06MV2) is not acting proper when it comes to speed of the person. I believe this is because I experimented in my house and not outside. The problem is that I cannot see speed and altitude data on bluetooth terminal app"ArduTooth" on my phone. It is just like a blank space which should have been my data. I am presenting my code which is not very long and I hope you could help me get through this.

    #include <SoftwareSerial.h>
    #include <TinyGPS++.h>
    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BME280.h>

    TinyGPSPlus gps; //gps object to be used
    SoftwareSerial BTserial(10, 11); //bluetooth serial connection
    SoftwareSerial gps_serial(4,3); //gps serial connection
    Adafruit_BME280 bme; //altitude measuring sensor object

    #define SEALEVELPRESSURE_HPA (1011) //sea level pressure in Turkey/Eskisehir

    double speed = 0; //speed of a moving body
    double current_altitude = 0;
    double previous_altitude = 0;

    void setup() {
    Serial.begin(115200); // serial connection to computer
    BTserial.begin(9600);
    gps_serial.begin(9600);
    bme.begin(0x76);

    delay(3000);

    previous_altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);

    }

    void loop() {
    //data from gps device is fed to gps object
    while (gps_serial.available() > 0){
        gps.encode(gps_serial.read());
    }

    if(gps.speed.isValid()){
    speed = gps.speed.kmph();
    BTserial.write(speed); // this is where the problem-1 is, this data is not shown on mobile phone
    bluetooth terminal application
    BTserial.write(",");

      if(speed <= 5 && speed > 0.5){
        BTserial.write("walking");
        BTserial.write(",");
      }
      if(speed <= 0.5){
        BTserial.write("standing");
        BTserial.write(",");
      }
      if(speed > 5){
        BTserial.write("running");
        BTserial.write(",");
      }

      }else{
        BTserial.write("m.s.n.n"); //stands for "moving status not known"
        BTserial.write(",");
      }

    current_altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
    BTserial.write(current_altitude); //this is where problem-2 is, this data also is not displayed
    on phone
    BTserial.write(",");
    //this part determines either the body goes upstairs or downstairs or he is on straight road
    if(current_altitude - previous_altitude >= 0.7){
      BTserial.write("going ups.");
      previous_altitude = current_altitude;
    }
    if(previous_altitude - current_altitude >= 0.7){
      BTserial.write("going downs.");
      previous_altitude = current_altitude;
    }
    if((current_altitude - previous_altitude <= 0.3) || (previous_altitude - current_altitude <=
    0.3)){
      BTserial.write("on s.r");
      previous_altitude = current_altitude;
    }
    BTserial.write(";");

    delay(1000);

    }

I must note that purpose of BTserial.write(",");  is that every seperate entry sent to phone via bluetooth must be seperated by ",".

body: You can convert you double data to string type.this trick may help. And you also can just sent a byte for different positions and decode them in app.


body:
`SoftwareSerial` is a very badly behaved library. It blocks interrupts
while sending or receiving bytes. Using it with whatever depends on
interrupts is asking for trouble. Using two instances of
`SoftwareSerial` concurrently is doubly asking for trouble. It is very
likely that they are interfering with one another, as each one blocks
interrupts for an unreasonably long time, and each one relies on
interrupts for detecting incoming data.

You don't seem to be using the hardware serial interface (`Serial`),
which is a shame, as it is the only serial port you have that works
really well. I suggest you try to use this interface for one of your
devices (maybe the GPS), and a single software interface for the other
one.

Or, better yet, use `Serial` for both. The transmit and receive parts of
a serial port are fairly independent, save for the fact that they work
at the same speed. You could use the transmit part for the Bluetooth
module and the receive part for the GPS. This should ensure reliable
communication with both devices, without ever blocking interrupts for
too long.


message:
Accessing struct's variable parametrically on ESP8266

I have 2 instances of a struct. One has def values stored and second stores values read from a file on `SPIFFS`.

I'm trying to use a for loop over all struct's variables - if file was read OK and key was found, store its value in `final_par` else get value from `def_par`.

For that, I've created `keys` array - but I can't find a way to iterate, in a for loop

as `final_par.keys[i] = def_par.keys[i]` - but this is not possible.

How can it be done ?

    struct parameters
    {
      bool ext_inputs;
      bool auto_relay_off;
      bool useSerial;
      bool useWDT;
      bool useOTA;
      bool useResetKeeper;
      bool useFailNTP;
      bool useDebugLog;
      char deviceTopic[20];
      char groupTopic[20];
      char prefixTopic[20];
      int inputUpPin;
      int inputDownPin;
      int outputUpPin;
      int outputDownPin;
      int inputUpExtPin;
      int inputDownExtPin;
      int auto_relay_off_timeout;
    };
    char *keys[] = {"ext_inputs", "auto_relay_off", "useSerial", "useWDT", "useOTA", "useResetKeeper",
                    "useFailNTP", "useDebugLog", "deviceTopic", "groupTopic", "prefixTopic", "inputUpPin",
                    "inputDownPin", "outputUpPin", "outputDownPin", "inputUpExtPin", "inputDownExtPin",
                    "auto_relay_off_timeout"};

    parameters def_par{false, false, false, true, true, false, true, "devTopic", "noGroup", "myHome", 2, 1, 14, 12, 0, 2, 60};

    parameters final_par;

body:
You can do it but it can be awkward. You'll need an array of structs, each member of which describes one member of your 'struct parameters' - essentially, an expansion of your present 'keys[]'.

Then you can consult this array randomly or in order to find the name, data-type, and memory offset of a given parameter (indexed by parameter order), or search it, to access the same information by parameter name.

Here's your parameter struct with some (incomplete but runnable) code to list the descriptor array, and incidentally, show how to build and use the array. Note that the code compiles but with a warning that a member of your 'parameters' was not initialized. I chose not to fix that; it isn't used here and doesn't prevent compilation.
```
struct parameters
{
  bool ext_inputs;
  bool auto_relay_off;
  bool useSerial;
  bool useWDT;
  bool useOTA;
  bool useResetKeeper;
  bool useFailNTP;
  bool useDebugLog;
  char deviceTopic[20];
  char groupTopic[20];
  char prefixTopic[20];
  int inputUpPin;
  int inputDownPin;
  int outputUpPin;
  int outputDownPin;
  int inputUpExtPin;
  int inputDownExtPin;
  int auto_relay_off_timeout;
};
//char *keys[] = {"ext_inputs", "auto_relay_off", "useSerial", "useWDT", "useOTA", "useResetKeeper",
//                "useFailNTP", "useDebugLog", "deviceTopic", "groupTopic", "prefixTopic", "inputUpPin",
//                "inputDownPin", "outputUpPin", "outputDownPin", "inputUpExtPin", "inputDownExtPin",
//                "auto_relay_off_timeout"};

parameters def_par{false, false, false, true, true, false, true, "devTopic", "noGroup", "myHome", 2, 1, 14, 12, 0, 2, 60};

parameters final_par;

// A couple of functions to extract data from an array or struct:
#define countof(a) (sizeof(a)/sizeof(a[0]))        // ret # of array elements (not bytes)
#define offsetof(struc, member) ((int)(&(((struc*)(0))->member))) // ret byte-offset from start of struct to the given member

// Enumerate possible parameter types
typedef enum {
   t_bool,
   t_char,
   t_int
} parType;

// Descriptor table - contains name, type, and offset of each parameter
// Could go in flash to save a bunch of RAM
struct descriptor {
   const char *name;
   parType pType;
   uint8_t offset;
} Descriptors[] = {
   { "ext_inputs", t_bool, offsetof(parameters, ext_inputs) },
   { "auto_relay_off", t_bool, offsetof(parameters, auto_relay_off) },
   // ...
   { "inputUpPin", t_int, offsetof(parameters, inputUpPin) },
   // ...
   { "auto_relay_off_timeout", t_int, offsetof(parameters, auto_relay_off_timeout) }
};

void setup() {
 Serial.begin(115200);
 Serial.println("parameter        type          offset\n");
 // List the parameters' names, types, and offsets within 'struct parameters'
 for( uint8_t i = 0;  i < countof(Descriptors);  ++i ){
  Serial.print(Descriptors[i].name);    Serial.print(", ");
  Serial.print(Descriptors[i].pType);   Serial.print(", ");
  Serial.println(Descriptors[i].offset);
 }
}

void loop(){
 ;
}
```


body:
You can create a 'hardcoded' copy function:

    void CopyParameter(int parameterIndex)
    {
        switch (parameterIndex)
        {
        case 0: final_par.ext_inputs = def_par.ext_inputs; break;
        case 1: final_par.auto_relay_off = def_par.auto_relay_off; break;
        ...
        default: // Error
        }
    }

Of course you can also pass `final_par` and/or `def_par` as arguments.

If you don't want to use an index, create an `enum` with the index values for each parameter, like:

    enum EParameters
    {
        ExtInputs,
        AutoRelayOff
        ...
    };

    void CopyParameter(EParameter parameter)
    {
        switch (parameter)
        {
        case ExtInputs   : final_par.ext_inputs     = def_par.ext_inputs    ; break;
        case AutoRelayOff: final_par.auto_relay_off = def_par.auto_relay_off; break;
        ...
        default: // Error
        }
    }

The disadvantage is that you have to keep the structure and the copy function manually synchronized.

The advantage is that you can do a shallow, deep copy or even add more logic depending on each struct member.


message:
Why do NRF24L01 modules only communicate in 1 direction

I have 2 NRF24L01 +pa +lna modules connected to 2 arduino mini pros. One of the modules is on a joystick and the other one is on a airplane. Everything worked perfectly until last week when they stopped communicating. So I wrote a simple receiver and transceiver code to see if they worked. The result is that if the module on the plane is the transceiver and the joystick is the receiver everything works fine. If they have the opposite roles then I only get empty messages onto the serial monitor way more often than the transceiver sends a message.

Receiver code:
```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8);

const byte address[6] = "00001";

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

  radio.begin();
  radio.openReadingPipe(0, address);
  radio.startListening();

}

void loop() {
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.println(text);
  }

}
```
Transceiver code:
```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7,8);

const byte address[6] = "00001";

void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.stopListening();

}

void loop() {

  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));
  delay (1000);
  // put your main code here, to run repeatedly:

}
```

body:
In receiving code....try only defining variable.
char text[32];

You change the datarate , palevel and channel in nrf24l01.
See datasheet for more info.
Or visit https://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/

You may have power issue because pro mini might not deliver sufficient....to neglect use a 10uf Cap in nrf.


message:
Arduino Uno + SIM808 EVB 3.2.4 not working properly?

So recently I found this tutorial online about the SIM808. It looked super cool so I ordered the sim808 evb 3.2.4 off amazon. Hooked up the module and connected the RX (11) and (10) TX pins.

Here is the code I'm working with tried to follow along as best I could with the tutorial but now I am completely confused, purchased a SIM card activated the SIM card and it seems to be connecting just fine

In the serial monitor sometimes I receive this: 14:05:06.243 -> Init Success, please send SMS message to me!

But most of the time I'm receiving this: 14:04:37.586 -> Sim808 init error

#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define MESSAGE_LENGTH 160
char message[MESSAGE_LENGTH];
int messageIndex = 0;
char MESSAGE[300];
char lat[12];
char lon[12];
char wspeed[12];

char phone[16];
char datetime[24];

#define PIN_TX 10
#define PIN_RX 11
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

void sendSMS();
void getGPS();
void readSMS();

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

  //******** Initialize sim808 module *************
  while(!sim808.init())
  {
      Serial.print("Sim808 init error\r\n");
      delay(1000);
  }
  delay(3000);

  Serial.println("SIM Init success");

  Serial.println("Init Success, please send SMS message to me!");
}

void loop()
{
  //*********** Detecting unread SMS ************************
   messageIndex = sim808.isSMSunread();

   //*********** At least, there is one UNREAD SMS ***********
   if (messageIndex > 0)
   {

      readSMS();
      getGPS();
      sendSMS();

      //************* Turn off the GPS power ************
      sim808.detachGPS();

      Serial.println("Please send SMS message to me!");
   }
}

void readSMS()
{
  Serial.print("messageIndex: ");
  Serial.println(messageIndex);

  sim808.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);

  //***********In order not to full SIM Memory, is better to delete it**********
  sim808.deleteSMS(messageIndex);
  Serial.print("From number: ");
  Serial.println(phone);
  Serial.print("Datetime: ");
  Serial.println(datetime);
  Serial.print("Recieved Message: ");
  Serial.println(message);
}

void getGPS()
{
  while(!sim808.attachGPS())
  {
    Serial.println("Open the GPS power failure");
    delay(1000);
  }
  delay(3000);

  Serial.println("Open the GPS power success");

  while(!sim808.getGPS())
  {

  }

  Serial.print(sim808.GPSdata.year);
  Serial.print("/");
  Serial.print(sim808.GPSdata.month);
  Serial.print("/");
  Serial.print(sim808.GPSdata.day);
  Serial.print(" ");
  Serial.print(sim808.GPSdata.hour);
  Serial.print(":");
  Serial.print(sim808.GPSdata.minute);
  Serial.print(":");
  Serial.print(sim808.GPSdata.second);
  Serial.print(":");
  Serial.println(sim808.GPSdata.centisecond);
  Serial.print("latitude :");
  Serial.println(sim808.GPSdata.lat);
  Serial.print("longitude :");
  Serial.println(sim808.GPSdata.lon);
  Serial.print("speed_kph :");
  Serial.println(sim808.GPSdata.speed_kph);
  Serial.print("heading :");
  Serial.println(sim808.GPSdata.heading);
  Serial.println();

  float la = sim808.GPSdata.lat;
  float lo = sim808.GPSdata.lon;
  float ws = sim808.GPSdata.speed_kph;

  dtostrf(la, 4, 6, lat); //put float value of la into char array of lat. 4 = number of digits before decimal sign. 6 = number of digits after the decimal sign.
  dtostrf(lo, 4, 6, lon); //put float value of lo into char array of lon
  dtostrf(ws, 6, 2, wspeed);  //put float value of ws into char array of wspeed

  sprintf(MESSAGE, "Latitude : %s\nLongitude : %s\nWind Speed : %s kph\nMy Module Is Working. Mewan Indula Pathirage. Try With This Link.\nhttp://www.latlong.net/Show-Latitude-Longitude.html\nhttp://maps.google.com/maps?q=%s,%s\n", lat, lon, wspeed, lat, lon);
}

void sendSMS()
{
  Serial.println("Start to send message ...");

  Serial.println(MESSAGE);
  Serial.println(phone);

  sim808.sendSMS(phone,MESSAGE);
}`

body:
I recommend you to use AT command ..then using some kind of library. You need to dig into library for better information.

https://randomnerdtutorials.com/sim900-gsm-gprs-shield-arduino/
Go through this link....this will give you a rough idea.


message:
How do I connect 4 or more Arduinos to a single shared GSM Module?

Is it possible to connect 4 or more Arduinos to a single GSM Module.?
All the Arduinos need to send SMS at a specific time daily.
How do I make sure thet don't time collide with each other, other than sending sms at different times for each Arduino?.
I want the SMS to be queued up, and be sent one by one.

body:
You should consider connecting one Arduino to the GSM module, and connect the 4 Arduinos together using SPI, I2C, or any other inter-hardware comms protocol. Before I knew these options existed, I once wrote a bit of code to send data between Arduinos by having one pin represent the data being sent and another pin changing every time a new bit was available. You could do something similar with an extra line per pairing, so an Arduino could tell the primary that it had new data to send.

Anyway, check out the "Wire Library" - it's basically for this kind of work. I think you'll be happier trying to have one Arduino "in charge" and connected to the CSM while the rest vie for its attention.


message:
Longruner Nano ATMega 328P input stays HIGH for 1s longer than the reality

I have a Longruner Nano ATMega 328P (copy of arduino nano, main difference being the USB connector, CH340 instead of the usual FT232, from what I could find using google searches).

I wrote a super basic code to test its signal detection capabilities:

```
setup(){
  pinMode(13, OUTPUT);
  pinMode(2, INPUT);
}

loop(){
  digitalWrite(13, digitalRead(2));
}
```

Hard to make it simpler to test a simple thing: when I give a HIGH signal to D2, D13 is HIGH too.

To test it, I used a simple male-male jump cable and connected VIN pin to the D2 one, for a very brief moment. And I notice D13 stays HIGH for around a second (measured with serial, lowest I could get was 996ms after super quickly touching D2 with the jump cable).

I tried to change the pinMode to INPUT_PULLUP following a similar question I found, but it didn't change anything regarding this delay.

Am I doing something wrong? Maybe a wrong configuration? Or is this just a hardware issue due to the fact that I'm using a copy and there's more than just the USb connector that changes?

I can adapt and work with this if it's required, but being able to have an accurate signal detection would help me greatly.

body:
Don't use Vin as a logic source. Use the +5V pin.

Also, disconnecting the pin is not the same as grounding it. It is "floating". For a proper test, connect a +5V to the pin, and follow it with a Gnd.

A floating pin has an undefined logic level.

What would work in your case is to have a (say) 1k resistor between D2 and Gnd. That way, the moment you disconnect the voltage input the "pull-down" resistor will return it to 0V.


message:
Sending data struct with 2 int fields from Arduino to Raspberry via NRF24L01

I'm trying to do wireless thermometer on max31865 arduino and nrf24l01 but I'm having problem sending whole data struct I can send int or char arrays but when I try to send whole struct I got output as
```
id: 131073 temperature: 0
```
Is there error in my code or there is some issue with differences in how arduino and raspberry store data? I don't really have experience in this so my question is how do I send struct that contain two fields of int or there is some better way? I need to transmit id and temperature in one package.

Transmitter code(Arduino)
```
#include <SPI.h>
#include "RF24.h"
#include <Adafruit_MAX31865.h>

#define RREF      430.0
#define RNOMINAL  100.0

typedef struct{
  int id = 100;
  int temperature = 100;
}
temp;

temp data;

bool radioNumber = 0;
int i =0;
Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);
RF24 radio(7,8);

byte addresses[][6] = {"1Node","2Node"};
bool role = 0;

void setup() {
  Serial.begin(115200);
  thermo.begin(MAX31865_3WIRE);
  radio.begin();
  radio.setChannel(125);
  radio.setPALevel(RF24_PA_MIN);
  radio.powerUp();
  radio.setDataRate(RF24_1MBPS);
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.stopListening();
}

void loop() {
      data.id = 1;
      data.temperature = 2;
    //int temp = 2; //thermo.temperature(RNOMINAL, RREF);
    Serial.println(temp);
    if (!radio.write( &data, sizeof(data) )){
        Serial.println(F("failed"));
     }
     delay(1000);
}
```
Receiver code(Raspberry pi b3+)
```
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <RF24/RF24.h>

using namespace std;

typedef struct{
        int id = 99;   // debug value
        int temperature = 99;
}
temp;

RF24 radio(22,0);
temp data;

bool radioNumber = 1;
const uint8_t pipes[][6] = {"1Node", "2Node"};

int main(int argc, char** argv)
{
    radio.begin();
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_MIN);
    radio.setDataRate(RF24_1MBPS);
    radio.setRetries(15, 15);
    radio.printDetails();
    if (!radioNumber) {
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1, pipes[1]);
    } else {
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(1, pipes[0]);
    }

    radio.startListening();

    while (1) {
            if (radio.available()) {
                int tem = 0;
                while (radio.available()) {
                    radio.read(&data, sizeof(data));
                }
                cout << tem  << "  " << "id: "<< data.id<< " temperatura: " << data.temperature << endl;
                delay(925);

            }
        }
    return 0;
}

```

EDIT:
Ok after running sizeof(data) on both devices, I notice that structs have different size 4 bytes for arduino and 8 for raspberry. So change on raspberry side to
```
typedef struct{
  uint16_t id = 100;
  uintt16_t temperature = 100;
}
temp;
```

And this is working but, may I ask why int have various size on arduino and raspberry?

body:
Your problem is that you are communicating between an 8-bit and a 32-bit architecture.

On an 8-bit architecture `int` is 16 bits. On a 32-bit it's 32 bits. Why the difference? Because "it is". It's how it's always been since the dawn of C. The concept of `int` is a flexible idea with no fixed defined size - the size is largely defined by the architecture and the compiler. Although conventions now dictate that an `int` will be 16 bits on an 8-bit system and 32-bits on a 32-bit system.

You can think of it as the integer size being the same as the internal register width of the processor *but with a lower bound of 16 bits*.

This is precisely why the fixed width integer types `uint16_t` etc exist - so that you can enforce the same data size on different architectures.

Incidentally you should also be aware of the *endianness* of your systems. In your case they are both "little endian", but "big" (and even "middle") endian systems also exist.  This defines what order each byte of an integer (and other multi-byte data types) is stored in memory. If you send an integer from a little-endian to a big-endian system and don't apply any transformation to the data to reverse the bytes then the values will be completely wrong.


message:
WebSocket Server for MKR1000

I was looking for a websocket server for my MKR1000 but nothing I found works.

I tried all the libraries that come with Arduino but half of those don't compile on the MKR1000 and those that do it don't work at all.

Your help would be greatly appreciated!

body:
This relatively simple one has always worked for me on several Arduinos (but I haven't tried it on the MKR1000 specifically):

https://github.com/morrissinger/ESP8266-Websocket

I have forked it and made some changes, but nothing fundamental:

https://github.com/ocrdu/NINA-Websocket

Have a go; it will probably work for you. Note that it works on more Arduinos than the name suggests; it's quite universal.


message:
sensitive distance detection using 2 HC-05 module/ 2 arduino unos

Hi I am doing a project in which I use 2 HC-05 modules and 2 arduino unos driving them. 1 bluetooth module is master and the other is slave. Master module is stationary while slave is moving. If the distance between these 2 modules is less than 1.5 meter, master device turns on a led. If the distance is more than 1.5 meter, the led will not be turned on. This is the basic idea and it works but not as I wanted. I present the code

master device code:

    #include <SoftwareSerial.h>
    //master device code
    SoftwareSerial BTSerial(5, 6); // RX | TX
    #define LED 4
    unsigned long timer = 0;
    unsigned long timeDifference = 0;
    char data;

    void setup()
    {
      Serial.begin(9600);
      BTSerial.begin(9600);
      pinMode(LED, OUTPUT);
      delay(5000);
    }

    void loop()
    {
      BTSerial.write('A');
      timer = millis();
      while(!BTSerial.available()){}
      data = BTSerial.read();
      if(data =='B'){
        timeDifference = millis()-timer;
      }
      Serial.println(timeDifference);

      if(timeDifference < 280){
        digitalWrite(LED,HIGH);
      }else{
        digitalWrite(LED,LOW);
      }
      delay(500);

    }

slave device code:

    #include <SoftwareSerial.h>
    //slave device code
    SoftwareSerial BTSerial(5, 6); // RX | TX

    char data;

    void setup()
    {
      BTSerial.begin(9600);
    }

    void loop()
    {
      while(!BTSerial.available()){}
      data = BTSerial.read();
      if(data =='A'){
        BTSerial.write('B');
      }

    }

So what happens here is that master device sends a char and starts timer. Slave receives the char and send another char to master device. When master device receives char, it stops timer and looks at how much time passed. The problem is that when I put those bluetooth devices together, the time difference is like 280ms. When I move away in the room with slave device, it is still like same. It is not sensitive. What can I do to make this more sensitive? I am waiting for your opinions

body:
The approach you're using will not work. You're trying to use speed of light time measurement to gauge distance. There are a whole host of problems with that. First, the clock on the Arduino is not fast enough (high enough resolution). You need accurate, sub-nanosecond time resolution for that (see this video: https://www.youtube.com/watch?v=9eyFDBPk4Yw). Second, BLE is a packet protocol. The overhead and variability of sending packets will totally swamp the **tiny** difference in round-trip time due to speed of light delay.

The usual way to gauge distance with BLE is to measure signal strength. That is also error-prone, but you can at least get rough "immediate", "near", "middle" and "far" distance measurements.

Alternately you could use and ultrasonic range sensor.


body:
In addition to the concerns above, your code won't work the way you want it to. You are initializing timer every loop so the time difference will always be 0. Instead, you should only write `A` from master device when it receives the response `B` and only then reset `timer`.

    void loop()
    {
      while(!BTSerial.available()){}
      data = BTSerial.read();
      if(data =='B'){
        timeDifference = millis()-timer;
        timer = millis();
        BTSerial.write('A');
      }
      Serial.println(timeDifference);

      if(timeDifference < 280){
        digitalWrite(LED,HIGH);
      }else{
        digitalWrite(LED,LOW);
      }
      delay(500);
    }


body:
Your approach is never going to work no matter how hard you try; it's like trying to use a hammer to bake bread!  If you need accurate time-of-flight distance measurements, use a sensor designed to do that, like the [ST Micro VL53L0X time-of-flight IR LIDAR module][1].

  [1]: https://www.fpaynter.com/2020/06/replacing-hc-sro4-ultrasonic-sensors-with-vl53l0x-arrays/


message:
Send JSON body with SIM900 board

I'm trying to send JSON, but i'm not able to set `Content-Type` header.\
Other commands are successful:
```
[23:49:41:856] AT+SAPBR=3,1,"CONTYPE","GPRS"␍␊
[23:49:41:899] ␍␊
[23:49:41:899] OK␍␊
[23:49:52:327] AT+SAPBR=3,1,"APN","internet"␍␊
[23:49:52:367] ␍␊
[23:49:52:367] OK␍␊
[23:49:59:585] AT+CSQ␍␊
[23:49:59:594] ␍␊
[23:49:59:610] +CSQ: 18,0␍␊
[23:49:59:610] ␍␊
[23:49:59:621] OK␍␊
[23:50:07:449] AT+SAPBR=1,1␍␊
[23:50:08:501] ␍␊
[23:50:08:512] OK␍␊
[23:50:13:900] AT+SAPBR=2,1␍␊
[23:50:13:928] ␍␊
[23:50:13:928] +SAPBR: 1,1,"127.0.0.1"␍␊
[23:50:13:955] ␍␊
[23:50:13:955] OK␍␊
[23:50:21:261] AT+HTTPINIT␍␊
[23:50:21:291] ␍␊
[23:50:21:291] OK␍␊
[23:50:40:284] AT+HTTPPARA="CID",1␍␊
[23:50:40:320] ␍␊
[23:50:40:320] OK␍␊
[23:50:47:652] AT+HTTPPARA="URL","http://127.0.0.1:5000/data"␍␊
[23:50:47:713] ␍␊
[23:50:47:713] OK␍␊
[23:50:54:359] AT+HTTPPARA="CONTENT","application/json"␍␊
[23:50:54:414] ␍␊
[23:50:54:414] +CME ERROR: operation not allowed␍␊
[23:51:06:576] AT+HTTPDATA=38,10000␍␊
[23:51:06:612] ␍␊
[23:51:06:612] DOWNLOAD␍␊
[23:51:12:034] ␍␊
[23:51:12:050] OK␍␊
[23:51:19:386] AT+HTTPACTION=1␍␊
[23:51:19:414] ␍␊
[23:51:19:414] OK␍␊
[23:51:27:747] ␍␊
[23:51:27:758] +HTTPACTION:1,500,290␍␊
[23:51:35:599] AT+HTTPREAD␍␊
[23:51:35:628] ␍␊
[23:51:35:628] +HTTPREAD:290␍␊
[23:51:35:635] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">␊
[23:51:35:692] <title>500 Internal Server Error</title>␊
[23:51:35:735] <h1>Internal Server Error</h1>␊
[23:51:35:766] <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>␊
[23:51:35:935] ␍␊
[23:51:35:935] OK␍␊
```
*ip addresses aren't real.*

My server received invalid request (with JSON body, but without special header), and replied `500 Internal Server Error`.

Revision: 1137B08SIM900M64_ST_DTMF_JD_MMS

body:
Thanks for **@Majenko**.\
I solved problem by upgrade firmware to **1137B15SIM900M64_ST**.


message:
Best strategy to parse 5 byte arrays to find a pattern

Ok here it goes, my first ever question posted to stackexchange! Please be gentle on me!

I am using an Arduino UNO (at the moment, will move to a faster micro later - but still use an Arduino sketch) to read in data as an SPI slave to extract the display data off of a commercial product that has no other exploitable data output that I can use. I am using a very generic sketch that Nick Gammon posted for the purpose of demonstrating the capability - and I can read the SPI data coming in ok. (Thanks Nick!)

The data is being pulled from a commercial product that has a 8 character, 5X7 dot matrix LED display that was specially made for this product and after exhaustive searches and emails to Broadcom/Avago - has no datasheet, but there are slightly similar products that I was able to use to get a bit of a handle on how the part works, I just went on the assumption that even if the interfaces are not the same, they probably didn't reinvent their command structure. However; the display doesn't have a nice driver chip embedded like your typical parallel LCD display.

I had to do a bit of reverse engineering using a logic analyzer to figure out:
1. It is SPI data at 4MHz.
1. The gist of the commands coming in and in what order
1. Used excel to convert the pixel mapping of the display to the font actually getting displayed on the device.
1. That the displayed font/text for each of the 8 characters is made up of 5 bytes - where the bit positions of those bites end up lighting a tiny LED in the display so the letter 'H' looks like 0x7F, 0x08, 0x08, 0x08, 0x7F. Each byte controls a column of 7 LEDs, ignoring a row.

Right now:
- I am using a modified version of Nick's slave sketch to simply extract the first 44 bytes of the command string to display something on the display
- all that is important to me is the 40 bytes after the first 4
- because those bytes are what get displayed. I am taking 5 elements of the 44 byte array that I know correspond to a character and spitting them out on the serial monitor such as:
   ```
   0x00, 0x01, 0x5F, 0x11, 0x00 // i
   0x7F, 0x08, 0x08, 0x08, 0x7F // H
   etc...
   ```

And now after a lengthy introduction - my actual question:

*I need to parse the patterns of each of the 5 bytes that makes up a letter and convert it to ASCII text so that the actual word is displayed on the serial monitor.*

Back when I used to use another programming language / environment on PICs we had things like LOOKUP and LOOKDOWN which made comparing patterns a bit more abstracted, which is weird considering Arduinos...

I need help coming up with a function that takes the 5 bytes that I need to build each letter from and maybe compares it to an array that represents each possible letter and then maybe passes the matching result to another function to build / concatenate the displayed word out of those characters? That method sounds wildly inefficient, but it's all my little brain can come up with and I'm drawing a blank on how to even do that... I don't need a lot of error checking because thus far the data I'm getting is spot on with what I see on the actual display - we are also talking one 8 character word (max) at a time and it is fairly static, no scrolling words or a lot of chatter - just a single word or some data that changes relatively infrequently. But the displayed data can be different enough than the last to make trying to match entire words out of the question unless it's a side feature to speed things up. I think work properly it needs to work on one character out of 8 - one at a time. Another thought is maybe summing the 5 bytes to determine if we have a match or not, but I'm not sure if two different characters might end up having the same sum? Math is not my strong suit. Thanks for any and all help.

body:
This is really a pure programming problem rather than an Arduino one, but to get you started, you could do a table lookup, like this:

<!-- language: lang-c++ -->

    #include <stdio.h>
    #include <string.h>

    // number of items in an array
    #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

    unsigned char patterns [] [5] =
      {

        { 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H

        // other byte patterns here

      };  // end of patterns

    char patterns_converted [] =
      {

      'H',

      // other letter equivalents here

      };  // end of patterns_converted

    char convert_pattern (unsigned char what [5])
      {
      for (int i = 0; i < ARRAY_SIZE (patterns_converted); i++)
        if (memcmp (what, patterns [i], 5) == 0)
          return patterns_converted [i];

      return '?';

      } // end of convert_pattern

    int main ()
    {

      unsigned char test1 [5] = { 0x7F, 0x08, 0x08, 0x08, 0x7F };
      unsigned char test2 [5] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };  // won't be found

      char x = convert_pattern (test1);

      printf ("Result for test1 is %c\n", x);

      x = convert_pattern (test2);

      printf ("Result for test2 is %c\n", x);

    }

You would find out all your bit patterns and put them in the patterns array, and then put the equivalent letter in the patterns_converted array.

The function convert_pattern does a linear search of the table of patterns, returning the corresponding letter, or "?" if not found.

I coded that in pure C++, but since the Arduino IDE basically uses C++ you should be able to convert it for your use.


message:
can i use L298N H bridge with 12v 7AH battery?

guys i am working on a rare project so i just need to ask some questions

I have a L298N H bridge motor driver, a Aduino uno board, 12v dc 4000rpm 2ampere motor and a 12v 7ah battery
I just want to ask can i use 12v 7ah battery with my L298N H bridge motor driver
please answer this project is very important to me
please help

body:
Yes, though at 2A you're at the top end of the L298N current limit. Expect excessive heating. You will have to manage your thermal environment appropriately.

You should consider a more capable driver with more current headroom and less heat problems. (Note: the L298N is a very old chip and uses old technology. It's not a good choice for modern drive systems and a more appropriate device should be investigated, for example the MC33931 as the first hit on google).


message:
What's the most direct way to assign Serial.read() bytes to an array?

I'm trying to send NMEA 0183 sentences through LoRa.
Every dinstict NMEA message looks like several char arrays (sentences) followed by '\n'.
In the below picture we see one NMEA distinct message:

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/4L2DU.png

This message arrives in the Arduino input buffer every 1 second with differentiated values (numbers) and it has to be sent over LoRa as fast as possible.
In order to send it over LoRa I need to read all bytes on the input buffer and assign them to an array and send them as an array, not one by one. I know that Serial.read() reads only one byte, and that's the problem.
How can I read all bytes and send them as a whole?

This is my code:

      if (Serial.available()) {
         c = Serial.read();
         rf95.send((char *)c, sizeof(c));
         rf95.waitPacketSent();

I use RadioHead library, and the definition of **rf.95.send** is:
*RH_RF95::send (const uint8_t * data, uint8_t len)*

**c** is of char type.

body:
All more complex Serial reading methods are based on `read()`.

Luckily there's a terminating character `'\n'` in your case, so you can implement something similar to `readBytesUntil` by yourself, if you want to.


body:
@DataFiddler suggested something like `readBytesUntil`.  In fact, you can just use `readBytesUntil`.  It returns either when timeout happens or when you reach the specified terminator.  It consumes, but does not include the terminator.  The timeout defaults to 1000 milliseconds, and can be modified with the `setTimeout()` method.

One downside is that you can't differentiate timeout, full buffer, and terminator reached.  This shouldn't be a problem except for serial transmission errors.
If your data is coming in at the NMEA standard 4800 baud, you could reasonably change the timeout to 5 milliseconds and still work.

<hr>

One thing that might bite you, is the line:
```
     rf95.send((char *)c, sizeof(c));
```
It is a mistake to cast the first parameter.  The error you got indicated you should write:
```
     rf95.send(&c, sizeof(c));
```
But the sizeof is also wrong.  The return type of `Serial::read()` is `int`, in part because there are 257 possible values.  If you declared c as an int, its size would be 2, not 1.

In any case, if you are using readBytesUntil, you pass the same buffer you passed it to rf95.send(), and the return value from the first as the second parameter of the second.


body:
I was missing a null termination character. That got me reading garbage from all over the buffer.
Adding a '0' at the end of the buffer's length is mandatory.
Plus, as David G. noticed, sizeof() function is incorrect. strlen() must be used.


message:
How to connect more than one arduino serial port together

The idea is to connect more than 1 arduino slave to master as shown in schamatic

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/WtU2Z.png)

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

body:
You can do it with two diodes and a resistor:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/YgEq7.png)

<!-- End schematic -->

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


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

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

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/B1tAl.png


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

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

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

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

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

and enable it again with:

```cpp
UCSR0B |= _BV(TXEN0);
```

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

```cpp
const uint8_t TX_PIN = 1;

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

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

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


message:
Four temperature SHT31 sensors on ESP32

I have to read out the teperature and humidity of four independent SHT31 sensors with the help of an ESP32. Is there any prefered way to do this, since the only examples I can find online are only with one sensor. I have no access to the address pins of the sensors.

Thank you in advance for any help!

body:
Yes, reading 4 SHT31 is possible with an ESP32.

If you have the analog version, readout is quite trivial: you simply use 8 analog inputs (2 for each) to read the signal.

If you have the digital version, which has an I2C interface, you need to control each sensor's address pin separately to select the specific sensor you want to read. Otherwise, there will be an address collision on the bus.


body:
Try using TS3A5018, part from TI.
You can then connect 4 independent I2C devices (SHT31).

There are also dedicated I2C channel multiplexers such as these. ![enter image description here](https://i.stack.imgur.com/dzics.jpg)

Below is the example for I2C multiplexer from TI

![enter image description here](https://i.stack.imgur.com/Qf2vl.jpg)


message:
Windows upload from command line gives Access Denied

saw somewhere that in order to upload a hex file to an arduino you can look at the Arduino IDE - see the command it runs, then replace the hex file with your file.
this is the command I see in the output window:

```C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\yossi\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i ```

I try running this from command (as admin):
```
cd "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr\bin"
avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\foosMaster\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i
```
gives me ```Access is denied.```
in fact, just running ```avrdude``` gives the same error, so really - this has nothing to do with the COM port (which works fine from the IDE)
I tried closing the IDE and running again, tried rebooting - the same.

*** edit 1 ****

I actually ran this:

    cd "C:\PROGRA~1\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr\bin"
    avrdude -CC:\PROGRA~1\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\foosMaster\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i

since I didn't want to mess with wrapping the params - but I don't really think it matters - as the problem is running avrdude without any parameter still gives me the same error: ```Access is denied.```

body:
This is because you are running the Windows App Store version of the IDE.

Windows doesn't like you messing with the insides of App Store programs (I think it scares it...).

Install the *real* version of the IDE from the Arduino.cc website and it will work.


message:
Is there a method of figuring out whether or not my stepper drivers are dead?

I'm working on a project that involves stepper motors, and I'm mainly using DRV8825 stepper drivers. At the moment, it seems like only one of my drivers actually gives the motors any current. The others usually return 0s when I measure their VREFs. One returns a value but still can't pull the motors. After checking all of my DRV8825s and finding only two returned VREFs, I checked my A4988s and none of them gave anything (aside from power supply voltage when measuring different pins). Is there a way I can figure out whether my stepper drivers are actually fried? I have a suspicion that maybe the potentiometers on the drivers are thrown off or there's some other issue I can't place. I'm happy to give more information if that can help to figure out what's going on here. Thank you!

body:
Most surefire way to tell if your drivers work is to wire them up CORRECTLY and try them out.  You should not be frying them if you have the correct setup (including current limit) for your conditions.  That said, conditions include your heat sink install and the environmental temperature.

The usual gotchas:

 - Note that DRV8825 and A4988s may have different pin locations so be sure to orient them correctly (check their EN pin location) if using a shield.
 - Also note that the gains from the voltage to the current limits will be different for the different model #s.  Be sure to use an appropriately sized screw driver and attach the meter to the screw driver as you turn to adjust the current limit.


message:
Switching a Solenoid Using Arduino's 5V Output?

I'm a bit stumped on how to switch on a solenoid using a transistor using my Arduino Nano's 5v Output. The solenoid runs on 12V, so I used an NPN transistor to connect the 12V source to the solenoid whenever Arduino sends current to the transistor's base. I connected all the grounds together to the Nano's ground pin, but the solenoid still doesn't switch.

I know the transistor works properly, because the solenoid switches when I use the battery to send base current instead of the Nano. I would think the Nano is capable of sending enough current to activate the Collector -> Emitter path but might be wrong. I'm also wondering if it's an issue with grounding the circuit, but I've made sure there is a common ground. What do you think I'm doing wrong? BTW the transistor I am using is D882P. I would appreciate any help.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/KeaJW.png)

<!-- End schematic -->

body:
## Low-side switching an inductive load (such as a relay) using a microcontroller (such as Arduino), NPN BJT transistor (with full base resistor calculations), and snubber/flyback diode

_Note: this answer demonstrates using the 2N3904 NPN transistor for all of the calculations, since that's what's in the schematic in the question. However, after writing the answer, I noticed the words at the end of the question state it is a D882P (also an NPN type) transistor. So, just follow my methodology here but use the appropriate values for your NPN transistor type, which you can obtain from the datasheet. A quick [Google search for "d882p datasheet"][1] reveals [this as a potential datasheet][2]._

2N3904 is an NPN transistor ([datasheet](https://www.onsemi.com/pub/Collateral/2N3903-D.PDF)), as opposed to a PNP transistor, so it must be connected directly to GND and switch the low side of the circuit only, so wire it like this instead:

![schematic](https://i.stack.imgur.com/I7mhC.png)

Notice I've added a diode, D1, to dissipate inductance-induced voltage spikes created when electromagnetic fields (a form of energy storage) collapse in the inductor each time you turn the switch OFF. This diode, due to its *function* (not type), is called a ["flyback", "snubber", or "clamp" diode][3]. Again, it protects the transistor and other components from inductance-induced voltage spikes from the relay coil/inductor. When a voltage spike occurs, it will simply travel around that loop through the diode, relay, and resistor R2 again and again and again until it has all been dissipated as heat in those components and there is no more voltage spike remaining.

I've also added a resistor R2 to limit current through the relay coil. You'll have to size this appropriately to get the correct current through your relay coil, based on the relay's datasheet. If your relay's datasheet says to hook up the relay to 12V directly, you can remove this resistor.

And you'll definitely need a base resistor (R1 in my circuit) or else you'll burn up your Arduino pin.

## First, let's collect some necessary values from the [Datasheet][4]. These will be used in the calculations below:
1. **VBE(sat)** = 0.65 to 0.95V.
    1. This is the diodic voltage drop from Base to Emitter when the transistor is "saturated", or fully ON.
1. **hFE_min** = 30
    1. Notice in the screenshots below that I have crossed out all of the 2N3903 transistor hFE entries so they don't distract us from the 2N3904 entries, which is the transistor type I'm using for this example. I then chose the *lowest* hFE entry for this transistor, which is 30.
    1. This is the "guaranteed" minimum, or worst-case, DC current gain. The formula is simply: `I_max_permitted_from_Collector_to_Emitter = gain * I_Base_to_Emitter`. So, if your gain is 30, for example, and you drive a base current of 5mA from Base to Emitter, then the "guaranteed" maximum **_possible_** current allowed from the Collector to the Emitter will be `30 gain * 5mA = 150mA`. Again, this is not what you *will* get into the Collector, this is what you *could* get before the transistor itself starts limiting the current into the Collector rather than your load limiting the current through the Collector.
1. **Ic_max_continuous** = 200mA
    1. This is the max continuous current you can get from Collector to Emitter without overheating the transistor (assuming, I think, you have adequate cooling through conduction and possibly even convection and radiation via heat sinks--I need to brush up on the thermal and power equations myself). The datasheet may specify if a heat sink is required to achieve this current, but regardless, you should keep your continuous current down to about half this value or less if possible, as the device may reach crazy high temperatures of like 150 C or something with this current and no convective cooling or heat sink. For short bursts, hitting this current is just fine.

Here are some screenshots of where to find these values in the datasheet:

[![enter image description here][5]][5]

Notice in this next image I've crossed out all of the 2N3903 hFE lines so they don't distract us from the 2N3904 entries, which are for the transistor we care about in this example. Choose the lowest hFE value as the gain you will use in your estimates in order to have a "conservative" estimate, virtually guaranteed to fully turn on your transistor in all cases (ie: for all Collector current values you might like to switch on and off).

[![enter image description here][6]][6]

## Now, let's calculate a Base resistor value for an NPN BJT transistor, assuming your goal is to _fully turn on_ (saturate the Base-Emitter channel of) the transistor:

VBE(sat) has a diodic voltage drop of **0.65 to 0.95V**, so your resistor would have to burn off `5 - 0.95 = 4.05V` to `5 - 0.65 = 4.35V`. Let's just use the lower 4.05V value so we will size for higher currents and faster turn-on speeds.

Your minimum hFE (gain) value for the 2N3904 transistor (not the 2N3903) is **30**. Maximum continuous Collector current, Ic is **200mA**, so let's **increase that by a factor of 2 to 4** and size for `200mA * 3 = 600mA` to 1) more fully saturate the Base to Emitter channel and get closer to full turn on under all cases, 2) get faster turn-on, and 3) overcome the fact that decreased gain occurs at higher Collector currents. In **Figure 15. DC Current Gain**, from the datasheet, for instance, shown below, it shows that the normalized gain decreases from ~0.28 at 100mA Collector current to ~0.13 at 200mA Collector current, which means that the gain of 30 found in the datasheet at 100mA Collector current indicates the gain at 200mA Collector current will actually be approximately `30 gain/(0.28/0.13) = 13.9 gain`. Simply multiplying the Collector current we are sizing for by a factor of 2 to 4 (3 in our case) accounts for this fact, so we will use 600mA instead of 200mA in our maximum Collector current calculations below.

[![enter image description here][7]][7]

So, `600mA / 30 gain = 20mA` Base to Emitter to get rock solid turn-on performance. Arduino can do up to **40mA** per pin so this is Ok. Note that I recommend **30mA** max per Arduino pin (for the ATmega328 microcontroller), and there is also a _combined output limit_ for the ATmega328 microcontroller of _**200mA** for all pins combined_, which you should keep in mind. I describe this on my website in my article ["Arduino Power, Current, and Voltage Limitations" here][8].

`V = IR`, so `R = V/I`, so resistor, R that we need `= 4.05V/0.020A = 202.5 Ohms`. This is the minimum recommended base resistor size. Don't go too much smaller than **200 Ohms**, if you go smaller than that at all. A 100 Ohm resistor, for instance, would allow a maximum base current of `I = V/R =` (I intentionally use the higher voltage value here) `4.35V/100 Ohms = 43.5mA`, which could damage your pin.

Don't go larger than **600 Ohms** or else you risk not turning on the transistor fully by not saturating the Base to Emitter channel. A 600 Ohm resistor would give you a guaranteed max Base to Emitter current of `I = V/R =` (I intentionally use the smaller voltage value here) `4.05V/600 Ohms = 6.75mA`, which with a gain of 30 would give you a max Collector current (based on your relay coil resistance now) of `6.75mA * 30 gain = 202.5 mA`. However, as indicated from Figure 15 shown above, a more realistic gain at 200mA Collector current might be only 13.9, which means your maximum allowed Collector current with a 600 Ohm resistor would be `6.75mA * 13.9 gain = 93.8mA`. But, at this current your gain would actually be > 30, not 13.9, which leads back to the 200mA Collector current number. You can see this is a juggling game of numbers since the gain is NOT constant NOR linear, but rather is a function of Collector current, as shown by Figure 15 above. So, perhaps your actual maximum allowed Collector current with a resistor of 600 Ohms would be more like 130mA or something. The point is: any larger of a base resistor than 600 Ohms and you most likely won't be able to achieve the transistor's rated maximum continuous Collector current even if you wanted to. **So, there's a reasonable R value range!: 200 Ohms to 600 Ohms,** perhaps even leaning more towards the 200 Ohms side if you expect to have high momentary Collector currents anywhere near your maximum continuous Collector current rating of 200mA.

---------

## Additional notes on high-side vs low-side driving with NPN BJT or N-Channel MOSFET transistors, for clarity:

An NPN transistor can switch high-side voltages too--you just have to drive the necessary Base to Emitter current is all (and don't exceed any maximum ratings)! That's it! So...if you try to drive the high side, think about it: you turn it on with 5V so your voltage from Collector to GND can't exceed ~5V now because as current starts to flow through the collector, voltage would come up on the Emitter side until your base current no longer flows. Your system would be fighting itself. Even if you gave it 12V before the Collector you'd never see more than ~5V at the Emitter, assuming your Base drive voltage was 5V. If you can design around it, go for it, but generally the "easy" or "normal" way to do things is to use NPN to switch low-side voltages and PNP to switch high-side voltages.

The same goes for N-channel and P-channel MOSFETS. Use N-channel to switch low-side voltages and P-channel to switch high-side voltages, UNLESS you are doing some fancy driving (again), of N-channel to switch high-side voltages, as N-channel MOSFETs are more efficient and can switch higher currents than their equivalent P-channel pairs, due to some electron hardware mumbo jumbo stuff.

Keywords: transistor sizing; BJT transistor circuit calculations, equations, and datasheet; arduino and electrical engineering: transistor (BJT) sizing, equations, datasheet, and calculations example

## Additional reading:
1. [my answer] [Electronics Stack Exchange: When is a MOSFET more appropriate as a switch than a BJT? [and a BJT more appropriate than a MOSFET]](https://electronics.stackexchange.com/questions/13079/when-is-a-mosfet-more-appropriate-as-a-switch-than-a-bjt/527268#527268)

  [1]: https://www.google.com/search?q=d882p datasheet&oq=d882p datasheet&aqs=chrome..69i57j69i59j69i60.210j0j7&sourceid=chrome&ie=UTF-8
  [2]: https://www.st.com/resource/en/datasheet/2sd882.pdf
  [3]: https://en.wikipedia.org/wiki/Flyback_diode
  [4]: https://www.onsemi.com/pub/Collateral/2N3903-D.PDF
  [5]: https://i.stack.imgur.com/YSKUO.png
  [6]: https://i.stack.imgur.com/31x6p.png
  [7]: https://i.stack.imgur.com/lMY8F.png
  [8]: https://www.electricrcaircraftguy.com/2014/02/arduino-power-current-and-voltage.html


message:
How to connect neo 6m 6pin module with nodemcu v3

I got this neo 6m gps module from a broken drone. and i would like to connect it to nodemcu v3 board.
most of the gps module that i have seen are with 4 pins (vcc,gnd,tx,rx) , but this module has 6 pins (gnd,vcc,txd,rxd,scl,sda) .

i am not sure how to wire it up and what library to use.

![Neo 6](https://i.stack.imgur.com/EVVCf.jpg)
![NodeMcu v3](https://i.stack.imgur.com/6G21M.jpg)

body:
The 4 pins VCC/GND/TX/RX are the same as any other GPS module.

The other two pins, SCL and SDA, are nothing to do with the GPS. They connect to the HMC5883L compass chip.

Use the normal TinyGPS library for the GPS, and a HMC5883L library (such as [this one](https://github.com/jarzebski/Arduino-HMC5883L)) for the compass.


body: Rx and tx pin are for UART communication and SCL and SDA are for I2C communication. Most common gps module use UART communication method .... You can go with UART too this will help you to choose better  library option. Most library file are coded for UART method.  I recommend you to use vcc , gnd ,rx and tx pin. Escape scl and sda pins.


message:
Do Arduino Nano Every devices short out?

I have an Arduino Nano Every device that seems to have shorted out.

I use a lighted USB hub with buttons that turn connections on and off.  Each button has its own LED that indicates power state for its associated port.

Anyway, when I plug my Arduino Nano Every into that USB hub, the lighted buttons turn off for half of the hub, like the Arduino is shorting out the hub.

I use a different Arduino and have no problems, so it's definitely the Arduino.

Any idea what could have caused this?  I was using the Arduino with a TMUX1511 switch chip and using pins  D9-D12 to turn on and off the 4 internal switches in the chip.  It's using very low voltage (5v) and amperage is (25 mA).  I used the 5v and gnd pins on the Arduino to power the TMUX1511 chip, but with such low amperage, I can't see how that could have caused the Arduino to fry.

Any ideas?

body: this might because of powering issue...try using different source having a good number of current capability. likely up


message:
Estimating CPU load of a task scheduler

First off, I should note that I'm not sure what tags best apply here, and I can't seem to find any that relate to schedulers, etc. Please inform me if they are not the right ones.

I have a simple, portable task scheduler (it only relies on millis(), and runs on different Arduino-supported systems) that is called via a function in loop() and that picks and then runs a function pointer (the "task") from a list of tasks with status, sleep, and priority information.

I would like to have a way to determine and to tell the user how much CPU time is being spent on running tasks vs. being idle.

The problem is that there can be other functions being called from loop(), not just my scheduler. It would thus be a bad idea to track total time vs. time spent in a task. If I did, the CPU use would always read low, since the actual task time cannot use all of the CPU time since the other tasks in loop() would be quietly using some of it.

However, if I specifically track time in the scheduler vs. time spent in task, I run into a new issue. I would use more memory (a few more bytes, but I'm using a lot already...) and more CPU*, since I'd have to keep track of the total so far *and* also the current runtime for that iteration of the scheduler. That's on top of the similar construct determining the runtime of the task. Mainly, though, the issue is that the loop() function and scheduler run fast enough that the millis() timer can tick slower than the changeover between my scheduler and the loop() function. This causes the timing to also be off, since it would be counted if it ticks in the scheduler even if it was mainly loop()'s fault.

Is there a general methodology for computing the CPU time? It would be difficult to time-slice the scheduler, and that would run slower anyway. I could count the proportion of scheduler calls that run/don't run tasks, but that won't work because tasks take longer than the no-op that happens if a task doesn't run, and it makes no accounting for task length.

*On an AVR system, the 8-bit CPU uses a surprising aggregate time on all those 32-bit operations, between the sleep time calculations (on sleeping tasks only, to be fair) and the elapsed time calculations that fed into my prior CPU use attempt. It wasn't the only cause, but I saw quite a bit of timing slip on one attempt of coding the scheduler because of a similar issue.

body:
The only metric you have is time. The only thing you can do is compare that time over iterations / task calls. The typical approach is to note the time at the start of a task "tick", and note it at the end. Then add the difference to the total for that task.

When you want to then look at usage percentages you can compare those totals to the total time the system has been running.

The total runtime is already done for you, in the form of `millis()`, so you don't need to worry about that.

Recording each task's total runtime in microseconds is simple enough, but of course will entail an overhead. That is unavoidable no matter what strategy you take. It's kind of quantum: the act of measuring changes the results.

If you treat your "idle" task the same as any other task (which is the normal way of doing things - the idle task is just a task that does nothing) then the sum of all the time counts for all the tasks = (within a certain granularity) the total amount of time your task scheduler has been running. The difference between that and the system runtime (`millis()`) is the proportion of the time your scheduler has been running compared to other things happening in `loop()`.

Whether you compare to `millis()` or `micros()` for the system runtime is up to you. By storing `micros()` per task you're getting a reasonable resolution for each tasks's runtime (but with a limit to how long before it wraps - but you can handle that in software by carrying over to another lower resolution counter if you want), but you can then discard some of that resolution when doing your calculations if you don't need it at the time.

Estimating runtime in a co-operative multitasking system like this is never good, and often not bothered with because of that. It's always a guestimate with the results being skewed by the measuring, since the measuring is synchronous with the execution of the tasks.

In a proper context-switching multitasking system you would normally operate on the number of "ticks" of the system rather on time. That is, simply count 1 each time a task is switched in by the context switcher. Since each task has a fixed runtime controlled by the granularity of the scheduler it's then trivial to know that task X has been running for X/TOTAL_TICKS % of the time. Any calculations will be themselves done in a task - maybe the idle task, or a system accounting task.


message:
ISR Issue: Arduino Pro Micro

I'm trying to do a small test where I am using the ISR on the Arduino Pro Micro it up from sleep mode. I'm using a Force Sense Resistor (FSR, a resistor that changes it's resistance depending on how hard you press it) with a voltage divider circuit with the output of the voltage divider connected to an analog pin and the digital interrupt pin. I'm not able to get the interrupt to trigger no matter what condition I have. I don't believe the Vout on the voltage divider is too low since the ADC registers values between 0 to 1000 (0V to about 4.8V) when the FSR is pressed. Is there anything wrong with my code that is preventing my test from working properly?

    uint8_t LED = 9;
    uint8_t wakeup = 2;
    uint8_t enable = 0;

    void Wakeup(void);

    void setup() {
      // put your setup code here, to run once:
      pinMode(LED, OUTPUT);
      pinMode(wakeup, INPUT);
      attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);
      Serial.begin(115200);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      //Serial.println(analogRead(A2));
      if (enable == HIGH)
        digitalWrite(LED, HIGH);
      else if (enable == LOW)
        digitalWrite(LED, LOW);
      if (analogRead(A2) < 700)
        enable = 0;
    }

    void Wakeup(void) {
      enable = 1;
      Serial.println("Interrupt");
    }

body:
* Don't do serial prints inside an ISR.

* Your variable `enable` should be declared `volatile` as it changes inside an ISR. The compiler is entitled to cache the variable value if you don't do that.

* You are inconsistent in your use of `enable`. You test for LOW or HIGH but set it to 0 or 1. Now they happen to be the same, but someone might wonder. If you are going to test for LOW or HIGH, then assign LOW or HIGH to it.

See my reference question [How do interrupts work on the Arduino Uno and similar boards?](https://arduino.stackexchange.com/questions/30968/how-do-interrupts-work-on-the-arduino-uno-and-similar-boards/).

> I thought 0 and 1 were serial pins. I'm using digital pin 2

Not in the code you are not:

    attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);

Do you mean:

    attachInterrupt(digitalPinToInterrupt(wakeup), Wakeup, RISING);

It's kind of confusing to have two names which differ only in case.


message:
Problem with serial input from android serial usb app

I'm using two (nrf24L01 + Arduino Uno) nodes to communicate with each other. Serial input from node1 will be sent to node2. A special character 'p' when sent to node2, it will reply that it's available. It is working fine when using arduino ide serial monitor on pc. When I use serial usb app on android to get serial input only the text is sent to another node and the special character sent does nothing and prints like any other message.

body:
I solved this problem by turning off CR+LF and selecting None for newline in send section. CR+LF was adding something extra to my input. By removing that program works fine with Android.

About CR,LF :
"Newline is a control character or sequence of control characters in a character encoding specification that is used to signify the end of a line of text and the start of a new one. Some text editors set this special character when pressing the ↵ Enter key." - (Wikipedia)


message:
Counter program

I'm an absolute beginner, and lately I had some problem with this program I was trying to do.
Basically I wanted with the Arduino to count 3 pulses from an oscillator and store the time  of these 3 pulses, but as I said I am a beginner so I have no Idea on how to do it, I would appreciate your help.

body:
Simple code
```
int pin = 7;
unsigned long duration;

void setup() {
  Serial.begin(9600);
  pinMode(pin, INPUT);
}

void loop() {
long duration = pulseIn(pin, HIGH);
 Serial.println(duration);
//delay(100);
}
```
Assuming that you are mentioning a squrewave this code mesures the time that squrewave pulse stays in `HIGH` and prints out in computer serial monitor.

You should send the signal to digital pin 7 (or put any pin you won't modify code `int pin = 7;`) 5 V HIGH and 0 V LOW.

The time unit measuring in here is in microseconds.
If you won't to measure low then `pulseIn(pin, LOW);`

**I took the example from Arduino official site you can refer more here**

https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/

Remember this is the basic example there are other good methods than this...

Analog wave is bit too complex.


body:
While this is likely to need tweaks for your needs, it should get you looking at the right things - millis, interrupts, etc.
Official references at:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
https://www.arduino.cc/reference/en/language/functions/time/millis/

~~~

#define pulsesToStore 3
#define interruptPin 2
volatile unsigned char index;
unsigned long storedTimes[pulsesToStore];

void restartStorage() {
 index = 0;
 attachInterrupt(digitalPinToInterrupt(interruptPin), storeTime, RISING);
}

void storeTime() {
 storedTimes[index] = millis();
 index = index + 1;
 if(index >= pulsesToStore) { //stop storage
  detachInterrupt(digitalPinToInterrupt(interruptPin));
 }
}

void setup() {
 pinMode(interruptPin, INPUT_PULLUP);
 restartStorage();
}

void loop() {
  // does nothing for now.  this is where you would do something with the stored pulses, print to serial, etc.
}

~~~


message:
L298N Motor Driver with Nodemcu/ESP32

I have seen a lot tutorials on L298N motor driver with nodemcu and ESP 32, which are 3.3v logic boards where the motordriver is a 5v logic board, now in Arduino while doing speed control 255 means 5v or even a high means 5v but in nodemcu/ESP32 this means 3.3v, so my question is how it will work ?

body:
It's not a question of voltage. You make a basic mis-assumption:

> in Arduino while doing speed control 255 means 5v

No, it doesn't.  255 means "Provide a logic HIGH signal all the time".

128 means "Provide a logic HIGH signal 50% of the time".

The 255 (or whatever number) is the "duty cycle" of a PWM signal. That is a digital signal that can be LOW or HIGH which is switching on or off rapidly. The duty cycle defines the ratio of ON time to OFF time.

You're not providing a voltage - you're providing an ON/OFF signal.

As long as the HIGH voltage of that signal is above the *threshold* of the receiving device (the L298N in this case) then it will see it as an ON/OFF signal.

According to [the datasheet for the L298](https://www.st.com/resource/en/datasheet/l298.pdf) the HIGH logic threshold (VIH) is 2.3V. That means anything above 2.3V is seen as ON and anyting below that is seen as OFF (actually there is hysteresis, so it has to drop below 1.5V to switch to OFF).

So your 3.3V from the NodeMCU is above that ON threshold, so the ON/OFF PWM signal is received properly as such.

Incidentally, it's because of this PWM signal that motors make a whining sound when they start up slowly. Because of this most proper motor drivers run the PWM at above 25kHz instead of the 500-ish Hz of the Arduino, so that whine is above the threshold of human hearing.


message:
Is AT command the only way to connect from Arduino to esp2866?

If I am programming an arduino and I wanted to communicate with the internet thru the esp2866 then is AT command the only thing that I can do?

I see a lot of this in the web

    void loop() {
     valSensor = getSensorData();
     String getData = "GET /update?api_key="+ API +"&"+ field +"="+String(valSensor);
    sendCommand("AT+CIPMUX=1",5,"OK");
     sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
     sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
     esp8266.println(getData);delay(1500);countTrueCommand++;
     sendCommand("AT+CIPCLOSE=0",5,"OK");
    }

If I set my Board -> Arduino Uno, I was thinking I can use the following library [https://arduino-esp8266.readthedocs.io/en/2.7.4_a/esp8266wifi/readme.html][1]

    #include <ESP8266WiFi.h>

    const char* ssid     = "my-ssid";
    const char* password = "my-password";

    void setup() {
      Serial.begin(115200);
      // We start by connecting to a WiFi network

      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

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

But I am getting

    exit status 1
    ESP8266WiFi.h: No such file or directory

Looks like the following library is only available when you set the Board-> Generic ESP8266 Module and is only used when you want to program the ESP8266 in the Arduino IDE?  Is this correct?

So in my question, does it mean that to communicate from the Arduino into the internet, I will be sending the AT command and communicate thru the SoftwareSerial.h?

  [1]: https://arduino-esp8266.readthedocs.io/en/2.7.4_a/esp8266wifi/readme.html

body:
> is AT command the only thing that I can do?

No. The AT commands are provided by the AT command firmware. You can replace that firmware with whatever you want.

It is common to write your own software for the ESP8266 to do your communication for you and communicate with other devices (including an Arduino) in whatever way is suitable.

Many times you don't even need the Arduino any more as the ESP8266 can do everything (it struggles with analog signals as there is only one rather inferior ADC pin).

> Looks like the following library is only available when you set the Board-> Generic ESP8266 Module and is only used when you want to program the ESP8266 in the Arduino IDE? Is this correct?

That is correct. That is for when you are writing your own ESP8266 firmware to replace the AT firmware.

> So in my question, does it mean that to communicate from the Arduino into the internet, I will be sending the AT command and communicate thru the SoftwareSerial.h?

Only if you retain the AT firmware on the ESP8266. To be honest that firmware is terrible and all the tutorials are bad. You should at the first available opportunity learn to program the ESP8266 directly and maybe retire the Arduino unless you need to use it as a glorified IO expander.


message:
Controling 5V relay with Wemos D1 R1

I would like to control a 5V relay with Wemos D1 R1 module through webserver. I'm using the following modules:
 - Tongling 5vdc Relay
 - Wemos D1 R1

I'm using the following schematic:
[![Sketch][1]][1]

and here is the code I'm using:

    #include <ESP8266WiFi.h>

    const char* ssid = "Myssidname";
    const char* password = "Myssidpass";

    int ledPin = D3;
    WiFiServer server(80);

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

     pinMode(ledPin, OUTPUT);
     digitalWrite(ledPin, LOW);

     // Connect to WiFi network
     Serial.println();
     Serial.println();
     Serial.print("Connecting to ");
     Serial.println(ssid);

     WiFi.begin(ssid, password);

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

     // Start the server
     server.begin();
     Serial.println("Server started");

     // Print the IP address
     Serial.print("Use this URL : ");
     Serial.print("http://");
     Serial.print(WiFi.localIP());
     Serial.println("/");

    }

    void loop() {
     // Check if a client has connected
     WiFiClient client = server.available();
     if (!client) {
       return;
     }

     // Wait until the client sends some data
     Serial.println("new client");
     while(!client.available()){
       delay(1);
     }

     // Read the first line of the request
     String request = client.readStringUntil('\r');
     Serial.println(request);
     client.flush();

     // Match the request

     int value = LOW;
     if (request.indexOf("/LED=ON") != -1) {
       digitalWrite(ledPin, HIGH);
       value = HIGH;
     }
     if (request.indexOf("/LED=OFF") != -1){
       digitalWrite(ledPin, LOW);
       value = LOW;
     }

     // Return the response
     client.println("HTTP/1.1 200 OK");
     client.println("Content-Type: text/html");
     client.println(""); //  do not forget this one
     client.println("<!DOCTYPE HTML>");
     client.println("");

     client.print("Led pin is now: ");

     if(value == HIGH) {
       client.print("On");
     } else {
       client.print("Off");
     }
     client.println("

");
     client.println("Click here Turn relay ON
");
     client.println("Click here Turn relay OFF
");
     client.println("");

     delay(1);
     Serial.println("Client disconnected");
     Serial.println("");

    }

After uploading the code **successfully** and watching the monitor, the light gets turned on and I get the following message:

    16:02:20.400 -> WiFi connected
    16:02:20.425 -> Server started
    16:02:20.479 -> Use this URL : http://192.168.100.7/
    16:02:41.680 -> new client
    16:02:41.680 -> GET / HTTP/1.1
    16:02:41.680 -> Client disconnected

However, when I turn on or off the relay using the browser, nothing happens:

    19:38:56.010 -> new client
    19:38:56.010 -> GET /LED=ON HTTP/1.1
    19:38:56.010 -> Client disconnected
    19:38:57.016 -> new client
    19:38:57.016 -> GET /LED=OFF HTTP/1.1
    19:38:57.063 -> Client disconnected

However nothing happens to the light and relay doesn't click.

**a few more notes:**
 - I tried in upload the code with relay at high to disconnect the circuit but light is still on
 - Wemos Network name appears in my network list
 - It doesn't not respond to AT Commands

  [1]: https://i.stack.imgur.com/BNGXC.png

body:
Is the Wemos D1 R1 a 5V board, or 3.3V? If it's a 3.3V board, that's your problem. Get a 3.3V relay.

(From a little digging it looks like the Wemos is a 3.3V device. If so, that is your problem. Those "digital relays" are available in 5V and 3.3V models. Replace your 5V relay with a 3.3V relay.)

What are the current requirements of the relay, and what is the max current you can draw out of the Wemos? How are you powering the Wemos?

I would say break this into pieces and solve them separately. Put a multimeter (OR an LED with a current limiting resistor) on pin D3 and make sure the pin is turning on and off. If it is, it is a problem with your relay. If it's not, it's a problem with your sketch or your Arduino.

If the pin is turning on and off, try attaching the IN pin on your relay directly to +5V. Does your lightbulb light then?


body:
The issue lies with Wemos Module where it only outputs 3.3V which insufficient to 5V Relay so this can be solved by implementing 2N2222 Transistor as per schematic below.[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/NhhVd.png