message:
multiple RC522 RFID on arduino yun

I was trying for one month to make multiple **RC522 rfid readers** work together on SPI on an arduino yun, one works fine, but if **I plug 4**, each with a specific slave select, **only one, sometimes 2, sometimes none are working**.

The library i use is `RFID.h` (i think the miguelbalboa one) , but I had the same results with `MFRC522.h` wich have a specific `readUidMultiReader` so I dont think my code is at fault.

Searching for this issue, I found [this question][1] wich is basically my issue, as I suspect [the readers I bought][2] are not supporting multidrop. [These readers][3] dont work either.

I read about solutions using [multiplexers][4] for SPI lines, tristate buffers on miso lines and/or [diodes][5] but these are workarounds, and there should be a more straightforward solution.

Also I tested with **no resistors** most of the time, but tried putting 10kΩ from all MISO to 3v3, no change, as i really dont understand what their use are, even if I feel they could be mandatory.

---
*I am using a yun for the builtin ethernet, because I tried nanos with ethernet shields and again the shields are ignoring the Slave select and thus not working with spi multidrop, so each time I plugged the shield on nano, even not using it, rfid stopped working.*

[![wiring][6]][6]

  [1]: https://arduino.stackexchange.com/questions/18313/issue-sharing-miso-with-multiple-rc522-rfid-readers
  [2]: https://www.amazon.fr/AZDelivery-lecteur-Arduino-Raspberry-démarrage/dp/B074S9FZC5/ref=sr_1_2
  [3]: https://www.gotronic.fr/art-module-rfid-13-56-mhz-vma405-25477.htm
  [4]: https://github.com/miguelbalboa/rfid/issues/191#issuecomment-242631153
  [5]: https://github.com/miguelbalboa/rfid/issues/290#issuecomment-549559010
  [6]: https://i.stack.imgur.com/PDIKZ.png

body:
I suppose that digital output power from yun is insufficient to drive all four readers - so, you need to add some [digital buffers][1] to MOSI, SCK, and RST lines.

74LS07 digital buffer:

[![74LS07][2]][2]

  [1]: https://www.electronics-tutorials.ws/logic/logic_9.html
  [2]: https://i.stack.imgur.com/mflqI.png


sender: user

sender: assistant

body:
Multiple SPI devices on the same bus shouldn't be a problem. I would try the following steps to narrow down the problem:

1. Add Pull-Up resistors to each CS line (10k should be enough)
(The is no need for resistors on the MISO, MOSI or CLK lines since they a push/pull when active)

2. Make sure each CS is set to `HIGH` before you attempt to access the reader

3. Use a simple sketch that only access 1 reader.
    - if you could access the first reader -> change the sketch to use the second one without changing the hardware setup. Continue until you've checked all readers.
- if you are not able to communicate with one reader, you still have a bug in your hardware setup

4. When the readers work independently, you could start to write your sketch using more than one at a time. (depending on the libraries this could be quite difficult since the lib must support multiple instances, but first we should check the hardware setup)


message:
Mediatek GPS periodic mode

I'm trying to build a low power GPS datalogger and I am trying to get the Mediatek based GPS module (Quectel L80-R) to run in periodic mode. I've sent the PMTK225 code to the module with various parameters, but it never seems to go into stand by or back up mode. Code below.

    //Testing that commands sent to the GPS unit work

    #include <NeoSWSerial.h>
    NeoSWSerial gpsPort(3,2); // pins 3/2

    #include <NMEAGPS.h>
    NMEAGPS gps;

    void setup() {

      // connect at 115200 so we can read the GPS fast enough and echo without   dropping chars
      // also spit it out
      Serial.begin(115200);

      gpsPort.begin( 9600 );
      gps.send_P( &gpsPort, F("PMTK605")); //firmware version
      delay(100);
      //gps.send_P( &gpsPort, F("PMTK314,-1")); //reset to default
      //gps.send_P( &gpsPort, F("PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC_GGA
      //gps.send_P( &gpsPort, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only
      delay( 100 );
      //gps.send_P( &gpsPort, F("PMTK220,200") );  // 5Hz
      //gps.send_P( &gpsPort, F("PMTK220,1000") ); //1hz
      delay( 100 );
      //gps.send_P( &gpsPort, F("PMTK225,0")); // normal mode
      //gps.send_P( &gpsPort, F("PMTK223,1,25,180000,60000")); // ephemeris data receiving
      gps.send_P( &gpsPort, F("PMTK225,2,3000,10000")); //period mode but not working
      //gps.send_P( &gpsPort, F("PMTK161")); //stand by mode
      //gps.send_P( &gpsPort, F("PMTK103")); //cold start
      delay(100);
      gps.send_P( &gpsPort, F("PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC only

      //gps.send_P( &gpsPort, F("PGCMD,33,0") );   // No antenna status messages needed
      delay( 100 );

      Serial.println("Ready!");
    }

    void loop() {
      if (gpsPort.available())
        Serial.write( gpsPort.read() );
    }

body: Quectel L80-R does NOT have periodic mode, while the L80 does.


message:
how can i conect a lipo charger to a teensy 4.0?

I have the battery charger product https://www.adafruit.com/product/2124
and a teensy 4.0, that I would like to use to power it.
what, if any pin would I connect from bat, to the teensy?
Its my understanding that the Lion backpack is a voltage regulator, and thats it. it takes Vin, ground, and Vout.
I understand the 5v output goes to the 5volt pin of the teensy.
the gnd goes to gnd. should Vin go someplace? Or should I leave it off?
Please assist.

body:
The output voltage of the charger board is marked with `BAT`. You should connect it to the Vin pin of the Teensy, which then will convert the batteries 3.7-4.2V down to 3.3V.

Of course you need to connect the grounds of the charger board and the Teensy (on the charger board ground is marked with `G`).

The 5V pin on the charger board is no output. The board does not give you 5V. This is actually the pin for the charging voltage, which is 5V. Here it depends on how you want to charge the battery. If you use an external source, you can simply connect it's 5V to the board. If you want to use the USB jack of the Teensy, you can connect the boards 5V to the Teensys 5V. **But:** Be sure to cut the little trace between Vin and VUSB/5V at the back of the Teensy. You don't want to connect the battery voltage with an USB power source.


message:
How to multitask with interrupts on Arduino?

I am trying to build a cashless RFID based water dispensing unit. I am using Arduino mega 2560, PN532, relay, flow sensor. Here is the flow of the program in I2C mode; I have two functions, one to scan the card and the other for the flow sensor. As soon as the RFID card is placed on the NFC module, data stored in the card (i.e, date of expiry and balance amount) is obtained and is checked for validity. If the card is valid, then the relay is turned on. A flow sensor measures the quantity of water dispensed. As soon as the limit of 1000 ml is reached, the relay is turned off. The whole process happens serially, when the card scanning is complete, it waits for the entire 1000 ml of water to be dispensed. What I want to achieve is after one card is scanned, 1st relay with the flow sensor has to be turned on and simultaneously the scanning of the second card has to begin. If the first relay is busy, second relay has to be assigned to it. Can I achieve this using Arduino Mega? How do I manipulate the atmega to perform all these tasks at once?

body:
You do not necessarily need a build a "multitask with interrupts on Arduino".  Instead consider using a [state machine][1].  First define the problem by drawing a [state diagram][2]:

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

Consider all state you wish to be in.  Including your example "...after one card is scanned, 1st relay with the flow sensor has to be turned on and simultaneously the scanning of the second card has to begin...".  Once you have defined all states and the rules that need to be tested for before jumping to a new state you can start programming your state machine.

There are plenty of tutorials [including this one][4] on the web specifically for people who want to implement a state machine on an Arduino.  But, briefly, you will want to create a loop that will execute with out stopping over and over again as fast as possible.  This loop will (1) know what the current state is and (2) will repeatedly test to find out if the program can change to any of the possible next states. When you change states is when, if you need to, you perform tasks such at turning the water on or off.

If you forsake the state machine and only use interrupts, testing the code tends to be very difficult.  As controlling exactly when an interrupt occurs relative to other interrupts and the state of the processor becomes problematic and nearly impossible to reliably repeat.  This is why the state machine is suggested. Interrupts can still detect external events. But by using a state machine the program is in control of what happens next. Instead of leaving it up to luck.

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine
  [2]: https://en.wikipedia.org/wiki/Finite-state_machine#/media/File:Finite_state_machine_example_with_comments.svg
  [3]: https://i.stack.imgur.com/l79xX.png
  [4]: https://create.arduino.cc/projecthub/gusgonnet/using-finite-state-machines-fdba04


body:
There is no real multitask on Arduinos. The Arduino can only do one thing at a time.

But, you can do things sequentially, one after another, so fast, that a human will think, that it happens simultaneously. This involves a non-blocking coding style, which needs no interrupts

- Every delay in your code (at least the long onces) need to be removed. if you want to do timed things, you should use the coding principle from the `BlinkWithoutDelay` example, that comes with the Arduino IDE.

- Also no function should wait for something to happen. Think of a function, that waits for a command from the serial interface. Blocking code would wait indefinitely, until a command was received, preventing any other code from execute. Instead the function could exit fast, when there is currently no command to process, leaving time for the other code to execute.

The whole principle relies on the `loop()` function executing very fast, so that your code can still be reactive. This works for most of the situations. Only sometimes you need to react that fast, that you need interrupts. Your usecase doesn't seem to belong to the interrupt needed faction.


message:
Increasing ESP32 AP max connections

It has already been asked how many clients can connect to an ESP32 AP, but the answer is far from clear; the best one is from a year and half ago ([ESP32 AP max connections: 4 or 10?][1]) :

> The answer is as clear as any other EspressIf configuration data, it is 4 or maybe 5, or 8, or 12, 16 or even 20 (the same as a ESP8266!)

As I'm trying to move a project from the ESP8266 because it does not have enough AP connections, two questions can be asked :

1. what is the maximum number of AP connections supported by the 4.0 ESP-IDF framework ?

2. can it be increased in any way ?

Thank you.

  [1]: https://arduino.stackexchange.com/questions/54459/esp32-ap-max-connections-4-or-10

body:
According to [the documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/network/esp_wifi.html#_CPPv416wifi_ap_config_t):

> `uint8_t max_connection`
>
> Max number of stations allowed to connect in, default 4, max 4

The WiFi interface and AP can support up to 10 connections in its internal structures, but that is only practical for WiFi Mesh usage (which doesn't use all 7 layers of the ISO model), and for actual WiFi station connections, which entails the allocation of far more resources (IP addresses, ARP tables, etc) only a maximum of 4 are supported.

If you need more connections I suggest you invest in a *real* access point / router which can deal with the network management for you (i.e., an access point or router which can do the DHCP and other networking housekeeping for you, leaving your ESP32 free to be a simple station).


body:
After some extensive testing with several modules (not just blindly trusting the documentation), here's what I found.

Short answer : **maximum 10 AP connections** for the ESP32 running ESP-IDF 4.0 (updated around 1st of march 2020), and **no, it can't be increased** (easily).

Details :

 - The maximum number of AP connections is defined somewhere in libnet80211, and can't be modified since I have no access to the source code.
 - when the 11th station tries to connect, libnet80211 prints `I (39682043) wifi: max connection, deauth!`, more or less like the ESP8266 for the 5th station
 - Changine the `ESP_WIFI_MAX_CONN_NUM` (defined in esp_wifi_types.h:258) from 10 to anything else ends up in unpredictable behavior (I'm labelling this as unpredictable since without the libnet80211 code, it can't be reliably assessed).

I'm not giving up on increasing the number of stations yet, so maybe there'll be an update to this answer.


message:
Why does my Arduino 3.3v fluctuate?

![Imgur](https://i.imgur.com/r9wYwGP.gif)

For some reason, my 3.3v on my Arduino is fluctuating a lot, and I am not sure why.
The multimeter is measuring dc voltage and is connected between GND and 3.3v of an Arduino Mega.

The multimeter works fine. Connecting between 5v and GND gives 5V on multimeter.

body:
Arduino output voltages may "fluctuate" a few mV but what you showing us in that gif is really unstable.

What you should be doing is:

1. Disconnect everything from Arduino except the power source
2. measure the voltage again;

Is it stable? the problem was because of pulling too much current that causing voltage drop and instability .

Is it unstable?

3. Try checking with another MM and/or change auto-range to manual.

Is it stable when measuring the voltage with another MM? something was wrong with your previous MM.

Still unstable?

4. Connect the Arduino to a 9V power adapter and disconnect the USB cable.

Measure the voltage again, if it's stable the problem was because of some error in the cable or USB power source.

Voltage is still unstable?

5. change the 3.3V voltage regulator.

It should fix the problem if not report back to do some more in-depth problem solving.


message:
Task watchdog gets triggered during Bluetooth initialization

The board ESP32-Dev-WROOM-32D cannot establish a bluetooth connection due to the task watchdog. Here's my code:

    #include "BluetoothSerial.h"
    //check if Bluetooth is enabled
    #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
    #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
    #endif

    BluetoothSerial SerialBT;

    void setup() {
      Serial.begin(115200);
      SerialBT.begin("ESP32test");
      Serial.println("The device started!");
    }
The program runs fine until `SerialBT.begin("ESP32test");` where it freezes, and does not continue to run. The message `The device started!` is not printed. Instead, the task watchdog gets triggered after some time: `E (24791) task_wdt: Task watchdog got triggered.`

Is there any way to turn off the task watchdog? Or is there any other issue?

body:
`SerialBT.begin("ESP32test")` is hanging, and because ESP32 doesn't deal well with code that hangs, so it complains about it.

ESP32 runs a Real-Time OS ([FreeRTOS](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html)).
The fact that it is a real-time OS means that execution of code needs to be guaranteed to finish within a certain time-frame. You'll often see RTOS functions containing the time limit in which that a blocking function should finish executing, such as:

```c
    uart_wait_tx_done(uart_num, 100); // wait timeout is 100 RTOS ticks (TickType_t)
```
(from [ESP-IDF docs](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html))

FreeRTOS comes with a task API. Each task can execute code, but they need to give other tasks the chance to execute code too. I think that when a task blocks, it doesn't allow other tasks to do work on the same CPU. (but I can't find sources to back this up)

`setup()` runs in one of the RTOS tasks, and when `SerialBT.begin()` blocks the task for too long, the task watch dog complains that the task is hanging.
If the task is blocked by some kind of looping code, then it generally helps to run `vTaskDelay()` to yield the task to the task watchdog for a bit.

Because your task is blocked by a single call, there isn't much to do about it, given that `SerialBT.begin()` doesn't seem allow you to specify when it should time out.


message:
How to Set Sensor Data Parameters?

Good day! How to set sensor Data parameters?

Like the data only set for example it starts with minimum value of 3 and ends with maximum value of 6 and it will turn on led 1 and if minimum value of 1 and maximum value of 2 turn on led 2 just like that?

My actual code for that:

    float basa = scale.get_units();
    if( basa >= 4 )
    {
      digitalWrite(led1, HIGH);
    }
    else if( basa >= 2 )
    {
      digitalWrite(led2, HIGH);
    }

This code shows that if ever it reaches value of 4 the value of 2 will react also so my question is how set sensor data value like it will only react Value1 - Value2 like that.

thank you

body:
For example:

    float basa = scale.get_units();

    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);

    if( basa >= 2 && basa < 4 )
    {
      digitalWrite(led2, HIGH);
    }

    if( basa >= 4 )
    {
      digitalWrite(led1, HIGH);
    }

**EDIT: as suggested by @chrisl (see comments)**

If understand you problem correctly, you try to light up 2 LEDs according to the value you read from a scale. IMHO you want to assign three intervals (ranges) like so:

    (-INF, 2) : none of the LEDs is switched on
    [2, 4)    : only LED 2 is switched on
    [4, +INF) : only LED 1 is switched on

* `[x` or `x]` means the x belongs to the interval.
* `(x` or `x)` means the x does not belong to the interval.
* `+INF` and `-INF` are the positive or negative infinity.

My code does the following:

I use the observation, that the intervals do not intersect and the union of the intervals are the complete real number space. (Although your scale has a more narrow range: (0-?kg). The program can handle a wider range compared to the the scale, so it is not a problem.)

If the first condition `(-INF, 2)` is `true`, none of the others would be and we can be sure that the LEDs I switched off with the `digitalWrite(ledX, LOW);
` statements will stay off. If the value is in the range of `[2, 4)` I switch on LED2 and can be sure that the other LED stays off because the condition `basa >= 4` can not be `true`. And if the value is in the range of  `[4, +INF)` I switch on LED1 and can be sure that LED 2 has not been switched on because the condition `basa >= 2 && basa < 4` can not be `true`.


message:
Sound sensor signals with time bracket

I've tried many codes for this to work but anything isn't helping at all, so my code should work like this: If a sound sensor (3 pins, A2) sends 5 signals into the Arduino within 10 seconds (the time gap of every signal varies, but doesn't matter as long as it sends 5 signals), the LED (13) will light up. This is my recent code if it could help

    int led=13;
    int sensor=A2;

    void setup()
    {
       pinMode(led, OUTPUT);
        pinMode(sensor, INPUT);
        Serial.begin(9600);
    }

    void loop()
    {
        unsigned long StartMillis = millis();
        unsigned long CurrentMillis = millis();
        int signal_count=digitalRead(sensor);
        int signal_limit=5;
        Serial.println(signal_count);

        while ((CurrentMillis - StartMillis)==5000)
        if (digitalRead(sensor)=0)
        {     signal_count ++;
            Serial.println(signal_count);
        }
        if (signal_count>signal_limit) {
            digitalWrite(led, HIGH);
        }
        else {
        digitalWrite(led,LOW);
        }
    }

body:
Your handling of `millis()` is wrong. With these two lines:

    unsigned long StartMillis = millis();
    unsigned long CurrentMillis = millis();

`StartMillis` will always have the same value as `CurrentMillis`. (Ok, I guess its possible for `millis()` to return a value that's increased by 1 the second time it's called, but that is **extremely** unlikely. The 2 lines takes much less than a millisecond to execute.)

Your

    while ((CurrentMillis - StartMillis)==5000)

will never evaluate to true, so the code in the while block will never execute.

This `if` statement is also wrong:

    if (digitalRead(sensor)=0)

You want `==` (comparison) not `=` assignment. I'm surprised the compiler even allowed that to compile, since you are trying to set the function `digitalRead(sensor)` to 0, which doesn't make sense.

Change that code to read:

    if (digitalRead(sensor)==0)

(Assuming you want the body of the if statement to execute when your sensor value is 0.)


message:
Moving an object in an area

I am planning to build a little game and I would need to move a small magnet inside a rectangular area. Ideally I would be able to control movement arbitrarily e.g. using a joystick.
I am trying to find a way of doing this, something like an actuator, I guess, but allowing movement in 2D.
Any suggestions on which parts to use?

Edit : in brief, what I'm trying to do is this. I have a piece of plywood, underneath which I want to put a magnet. The magnet will be moveable using a joystick (everything controlled through an Arduino) and will be used to move a magnetised figurine on the other side of the plywood. I guess in term of precision of movement I am not looking for extreme precision, having something accurate to 2-3mm would be absolutely fine. Haven't really thought of speed... But not looking for extreme high speeds.

body:
First you need to think about your axes configuration, then about the actual implementation. I for example can directly think of 2 options:

- You could arrange your axes perpendicular to each other, like a Cartesian coordinate system. Here you might need more parts to build it, than with other arrangements, though it is a sturdy system and the positions and paths are easily to calculate. For implementation there are 2 common ways, both using stepper motors in most cases:

    - You could let the magnet travel on the 2 perpendicular axes pulled by a belt and stepper motor for each axis. As you have to mount one axes onto the other, you might need to use 2 stepper motors (one for each side) for the first axis (depending on your dimensions, how smooth the axes glide and how much force is introduced by dragging the figurine). This approach is mostly used by 3D Printers, since they need rather fast movement, which is also rather precise, but don't need to accommodate high forces.

    - Instead of belts and pulleys you could use threaded rods for each axis. The magnet is mounted on nuts on these rods. Rotating the rots will move the magnet over the axis, since the magnet is fixed in it's orientation. The precision is highly dependent on the used rods, but all in all it is often more precise, than belts. But it is also way slower.

- You could use only rotational axes, like a SCARA robot. It has a rod on a rotational axis and another axis at the end of it. This approach might use less parts, than the Cartesian approach, but you need good servos to have precise and jitter-free positioning (though you could also go for a geared stepper motor here). Also the arm of the robot can look out under the field quite a bit, when positioning it to the far one side.

---

All of the above approaches can be way more precise, than you need it. They are all viable options.

I personally would go the first way, Cartesian axes with belts and pulleys. The principle is straight forward and you can easily hide it under your piece of plywood (including a margin for all the mechanical stuff of course).


message:
2 Fingerprint scanner using 1 arduino

I have problem in using 2 fingerprint scanner in arduino mega, every time I need to register I need to go and register my fingerprint on each fingerprint module,

> what i am planning to do is when I registered on 1 fingerprint scanner
> then the other fingerprint module automatically registered the
> fingerprint and vise versa.

 Can anyone help me with my project thanks. btw my project was already working but I have problems in registration of bio-metrics.

here is my code in verifying the registered fingerprint

    #include <Adafruit_Fingerprint.h>
    int door1 = 8;
    int door2 = 11;
    Adafruit_Fingerprint finger1 = Adafruit_Fingerprint(&Serial2);
    //fplabas
    Adafruit_Fingerprint finger2 = Adafruit_Fingerprint(&Serial3);
    void setup() {
    Serial.begin(9600);

    pinMode(door2, OUTPUT);
      pinMode(door1, OUTPUT);
    //  pinMode(Buzzer, OUTPUT);
    //
      digitalWrite(door2, HIGH);
      digitalWrite(door1, HIGH);

     finger1.begin(57600);
      finger2.begin(57600);
        if (finger1.verifyPassword() || finger2.verifyPassword()) {
        Serial.println("Found fingerprint sensors!");
      } else {
        Serial.println("Did not find any fingerprint sensors :(");
        while (1) { delay(1); }
      }

      finger1.getTemplateCount();
      finger2.getTemplateCount();

      Serial.print("Fingerprint Sensor1 contains "); Serial.print(finger1.templateCount); Serial.println(" templates");
      Serial.print("Fingerprint Sensor2 contains "); Serial.print(finger2.templateCount); Serial.println(" templates");
      Serial.println("Waiting for valid finger...");
    }

    void loop () {
      getFingerprintdoor2();
      delay(50);
      //Fingerprint Sensor Labas
      getFingerprintdoor1();
      delay(50);
    }

    uint8_t getFingerprintdoor2() {
      uint8_t p = finger1.getImage();
      switch (p) {
        case FINGERPRINT_OK:
          //Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
         // Serial.println("No finger detected");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
        //  Serial.println("Communication error");
          return p;
        case FINGERPRINT_IMAGEFAIL:
          //Serial.println("Imaging error");
          return p;
        default:
          //Serial.println("Unknown error");
          return p;
      }
      // OK success!

      p = finger1.image2Tz();
      switch (p) {
        case FINGERPRINT_OK:
          //Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          //Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
         // Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
         // Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
         // Serial.println("Could not find fingerprint features");
          return p;
        default:
          //Serial.println("Unknown error");
          return p;
      }

      // OK converted!
      p = finger1.fingerFastSearch();
      if (p == FINGERPRINT_OK) {
        Serial.println("Found a print match!");
        digitalWrite(door2, LOW);
    //    sendsms(textForSMS + " Noah", f1001);
    //    Serial.println(textForSMS);
    //    Serial.println("message sent.");
        delay(3000);
        digitalWrite(door2, HIGH);
        delay(1000);
       // Serial.print(finger1.fingerID);
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        //Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_NOTFOUND) {
    //    Serial.println("Did not find a match");
    //    digitalWrite(Buzzer,LOW);
    //    delay(1000);
    //    digitalWrite(Buzzer,HIGH);
        return p;
      } else {
        //Serial.println("Unknown error");
        return p;
      }

      return finger1.fingerID;
    }

    uint8_t getFingerprintdoor1() {
      uint8_t p = finger2.getImage();
      switch (p) {
        case FINGERPRINT_OK:
          //Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
         // Serial.println("No finger detected");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
        //  Serial.println("Communication error");
          return p;
        case FINGERPRINT_IMAGEFAIL:
          //Serial.println("Imaging error");
          return p;
        default:
          //Serial.println("Unknown error");
          return p;
      }

      // OK success!

      p = finger2.image2Tz();
      switch (p) {
        case FINGERPRINT_OK:
          //Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          //Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
         // Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
         // Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
         // Serial.println("Could not find fingerprint features");
          return p;
        default:
          //Serial.println("Unknown error");
          return p;
      }

      // OK converted!
      p = finger2.fingerFastSearch();
      if (p == FINGERPRINT_OK) {
        Serial.println("Found a print match!");

        digitalWrite(door1, LOW);

       delay(5000);
        digitalWrite(door1, HIGH);

      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        //Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_NOTFOUND) {

        return p;
      } else {
        //Serial.println("Unknown error");
        return p;
      }

      // found a match!
      return finger2.fingerID;
    }

And here is the problem code where I need to register on both Fingerprint scanner:

    #include <Adafruit_Fingerprint.h>
    Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial2);

    Adafruit_Fingerprint finger2 = Adafruit_Fingerprint(&Serial3);

    uint8_t id;

    void setup()
    {
      Serial.begin(9600);
      while (!Serial);  // For Yun/Leo/Micro/Zero/...
      delay(100);
      Serial.println("\n\nAdafruit Fingerprint sensor enrollment");

      // set the data rate for the sensor serial port
      finger.begin(57600);

      if (finger.verifyPassword()) {
        Serial.println("Found fingerprint sensor!");
      } else {
        Serial.println("Did not find fingerprint sensor :(");
        while (1) { delay(1); }
      }
    }

    uint8_t readnumber(void) {
      uint8_t num = 0;

      while (num == 0) {
        while (! Serial.available());
        num = Serial.parseInt();
      }
      return num;
    }

    void loop()
    {
      Serial.println("Ready to enroll a fingerprint!");
      Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");

     if (Serial.available()>0)
       switch(Serial.read())
      {
        case 'A':

            id = readnumber();
            if (id == 0) {
               return;
            }
            Serial.print("Enrolling ID #");
            Serial.println(id);

            while (!  getFingerprintEnroll1() );

          break;

           case 'B':

            id = readnumber();
            if (id == 0) {
               return;
            }
            Serial.print("Enrolling ID #");
            Serial.println(id);

            while (!  getFingerprintEnroll2() );

          break;

    }

    }

    uint8_t getFingerprintEnroll1() {

      int p = -1;
      Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
      while (p != FINGERPRINT_OK) {
        p = finger.getImage();
        switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          Serial.println(".");
          break;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          break;
        case FINGERPRINT_IMAGEFAIL:
          Serial.println("Imaging error");
          break;
        default:
          Serial.println("Unknown error");
          break;
        }
      }

      // OK success!

      p = finger.image2Tz(1);
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          Serial.println("Could not find fingerprint features");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      Serial.println("Remove finger");
      delay(2000);
      p = 0;
      while (p != FINGERPRINT_NOFINGER) {
        p = finger.getImage();
      }
      Serial.print("ID "); Serial.println(id);
      p = -1;
      Serial.println("Place same finger again");
      while (p != FINGERPRINT_OK) {
        p = finger.getImage();
        switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          Serial.print(".");
          break;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          break;
        case FINGERPRINT_IMAGEFAIL:
          Serial.println("Imaging error");
          break;
        default:
          Serial.println("Unknown error");
          break;
        }
      }

      // OK success!

      p = finger.image2Tz(2);
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          Serial.println("Could not find fingerprint features");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      // OK converted!
      Serial.print("Creating model for #");  Serial.println(id);

      p = finger.createModel();
      if (p == FINGERPRINT_OK) {
        Serial.println("Prints matched!");
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_ENROLLMISMATCH) {
        Serial.println("Fingerprints did not match");
        return p;
      } else {
        Serial.println("Unknown error");
        return p;
      }

      Serial.print("ID "); Serial.println(id);
      p = finger.storeModel(id);
      if (p == FINGERPRINT_OK) {
        Serial.println("Stored!");
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_BADLOCATION) {
        Serial.println("Could not store in that location");
        return p;
      } else if (p == FINGERPRINT_FLASHERR) {
        Serial.println("Error writing to flash");
        return p;
      } else {
        Serial.println("Unknown error");
        return p;
      }
    }

    uint8_t getFingerprintEnroll2() {

      int p = -1;
      Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
      while (p != FINGERPRINT_OK) {
        p = finger2.getImage();
        switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          Serial.println(".");
          break;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          break;
        case FINGERPRINT_IMAGEFAIL:
          Serial.println("Imaging error");
          break;
        default:
          Serial.println("Unknown error");
          break;
        }
      }

      // OK success!

      p = finger2.image2Tz(1);
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          Serial.println("Could not find fingerprint features");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      Serial.println("Remove finger");
      delay(2000);
      p = 0;
      while (p != FINGERPRINT_NOFINGER) {
        p = finger2.getImage();
      }
      Serial.print("ID "); Serial.println(id);
      p = -1;
      Serial.println("Place same finger again");
      while (p != FINGERPRINT_OK) {
        p = finger2.getImage();
        switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          Serial.print(".");
          break;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          break;
        case FINGERPRINT_IMAGEFAIL:
          Serial.println("Imaging error");
          break;
        default:
          Serial.println("Unknown error");
          break;
        }
      }

      // OK success!

      p = finger2.image2Tz(2);
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          Serial.println("Could not find fingerprint features");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      // OK converted!
      Serial.print("Creating model for #");  Serial.println(id);

      p = finger2.createModel();
      if (p == FINGERPRINT_OK) {
        Serial.println("Prints matched!");
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_ENROLLMISMATCH) {
        Serial.println("Fingerprints did not match");
        return p;
      } else {
        Serial.println("Unknown error");
        return p;
      }

      Serial.print("ID "); Serial.println(id);
      p = finger2.storeModel(id);
      if (p == FINGERPRINT_OK) {
        Serial.println("Stored!");
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_BADLOCATION) {
        Serial.println("Could not store in that location");
        return p;
      } else if (p == FINGERPRINT_FLASHERR) {
        Serial.println("Error writing to flash");
        return p;
      } else {
        Serial.println("Unknown error");
        return p;
      }
    }

Please help I am stuck in this situation..

body:
The library, that you are using, doesn't seem to support exporting or importing fingerprints. Though if you look into the [user manual][1] of the fingerprint sensor at the Adafruit site, there are two commands mentioned, that seem to do what you need:

> 6.2.2 Upload image:  UpImage

> Description: to  upload  the  image  in Img_Buffer  to  upper  computer.  Refer  to  1.1.1  for  more  about image buffer.

> 6.2.3 Download the image: DownImage
>
> Description: to download image from upper computer to Img_Buffer. Refer to 1.1.1 for more about the image buffer.

These commands can be used to read or write the image buffer, where an image is stored, when it was taken by the sensor (this is only about the image data, not about the recognition or enrolling; that has to be done after loading the image to the buffer). I could not find corresponding functions in the library, so I guess it doesn't support this. So, to get what you need, you need to stop using the library and handle the things yourself (or - maybe better - extend the library to incorporate that feature).

The manual has no good documentation about these functions and the datasheet, that Adafruit has, is in Chinese, so I couldn't read it. You will need to try it out and see, what you get, when issuing the mentioned commands (unless you can read Chinese and there is more useful information in that datasheet).

I guess after requesting the upload of the current image, the module will send data packets in the configured package size, until it has transferred the whole image (Note, that it will only send 4 bits for every pixel over UART, meaning 16-greyscale image). After than you could request the download on the other module. After the acknowledgement packet, I guess you need to send the image data in the same format, as you received it from the first module, in packets with the configured packet size.

When configured to the same packet size, you could request upload and download at the same time for each module and simply let the packets pass through. After transferring the image, you can start the recognition on both modules.

[1]: https://cdn-shop.adafruit.com/datasheets/ZFM+user+manualV15.pdf


message:
Home made drum kit - How can I speed up the response time after my sensor gets triggered?

I am trying to make a psudo drum kit with my Arduino Due and a couple Force Sensitive Resistors (activated with my fingers, no drum sticks). So far in my testing I'm only using one FSR. I've attached an SD Card reader and put a WAV File on there (44100 Hz, 16-bit, stereo). In my 'Loop', I read in the resistance of the FSR to know if it's been triggered, then I play the WAV file accordingly. It works but its not that fast. If this project is going to work, the response time needs to be much faster.

Here's my code:

    #include "SD.h" //Lib to read SD card
    #include "SPI.h" //SPI lib for SD card
    #include <Audio.h>

    #define SD_ChipSelectPin 2

    const int FSR_PIN = A0; // Pin connected to FSR/resistor divider

    const float VCC = 4.875;
    const float R_DIV = 10000.0;

    void setup()
    {
      Serial.println("Starting Drum Kit!");
      Serial.begin(9600);
      while (!Serial) {}

      pinMode(FSR_PIN, INPUT);
      pinMode(LED_PIN, OUTPUT);

      Serial.print("Initializing SD Card...");
      if (!SD.begin(SD_ChipSelectPin)) {
        Serial.println("FAILED!");
        while(true);
      }
      Serial.println("done");

      // 44100kHz stereo => 88200 sample rate
      // 100 mSec of prebuffering.
      Audio.begin(88200, 100);

      void loop()
    {
      File snare_file;
      short snare_buffer[1024];
      int fsrADC = analogRead(FSR_PIN);
      if (fsrADC > 20) // If the analog reading is non-zero
      {
        Serial.println(String(fsrADC));

        snare_file = SD.open("606snare.wav");
        while (snare_file.available()) {
          snare_file.read(snare_buffer, 1024);
          Audio.prepare(snare_buffer, 1024, 1024);
          Audio.write(snare_buffer, 1024);
        }
        snare_file.close();
      }
    }

If I hold down the sensor (constant triggering), the fastest that the file plays is about every half second. Here's the Serial output:

    15:12:28.453 -> Initializing SD Card...done
    15:12:28.487 -> 1023
    15:12:28.930 -> 1023
    15:12:29.510 -> 1023
    15:12:30.050 -> 1023
    15:12:30.628 -> 1023
    15:12:31.136 -> 1023
    15:12:31.744 -> 1023
    15:12:32.328 -> 1023
    15:12:32.834 -> 1023
    15:12:33.411 -> 1023
    15:12:33.955 -> 1023

I've tried playing around with loading the file and buffer in the `setup` section but I can't get it to work properly. There's not a whole lot of documentation on the `Audio` library either.

If you know of a better way to speed this up, or if I should be using a different library, please let me know.

body:
This is not really a 'solution', but it might help you in finding out where the real problem is.

Check out which of the statements in the `loop` function uses up the most time, probably;

1. int fsrADC = analogRead(FSR_PIN);
2. Serial.println(String(fsrADC));
3. snare_file = SD.open("606snare.wav");
4. while (snare_file.available()) {
5. snare_file.read(snare_buffer, 1024);
6. Audio.prepare(snare_buffer, 1024, 1024);
7. Audio.write(snare_buffer, 1024);
8. snare_file.close()

Try improving the most time consuming item if possible.

Some possibilities you can try in the steps above:

1. Do not use AnalogRead but direct port commands
2. Remove this completely or at least remove the String instance.
3. Not much you can do here, except not using a file system but raw SD read (you might have problems getting the files on your SD) without a dedicated program on your PC
4. Not sure about improving this one
5. Read less bytes, although it might even worsen things. Or read the bytes BEFORE waiting on the trigger (if you know which sample will be played).
6. Execute the prepare as before the trigger as 5 if possible.
7. Not sure about this... High likely you cannot keep too many files open at the same time.

Afaik in my synthesizer (Korg Kronos), it reads from all samples the initial part, meaning it can startup the data from RAM, while the rest is read through SSD (in your case SD). However, you might not have enough memory in an Arduino for that.


message:
problem with decrement in a loop

I am trying to write a sketch wherein the led brightness increases in increments of 15 until it reaches 255. At that point I want to make decrements of 15 until it reaches 0. The increment part of the program works well but the decrement part goes haywire. It gets stuck between 255 & 240. I am not sure how can I fix it. Could you please tell how can I make it work?

Here is my sketch:

    int led = 9; //led pin
    int fade = 0; // pwm value

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

      Serial.begin(9600);
      pinMode(led, OUTPUT);
    }

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

       analogWrite(led,fade);
       fade += 15;
       Serial.println(fade);
       delay(250);

      if (fade >= 240){
        fade = fade - 15;
        analogWrite(led, fade);
        Serial.println(fade);
        delay(250);
      }

    }

body:
The problem is that you add 15, and than if it's >= 240, you decrease 15, so it will not change  (I wouldn't consider it haywire though).

You can better use a direction sign. Below is only the relevant code (not the GPIO functionality). What it does in the loop is, in case up is true, it adds fifteen, otherwise it subtracts 15. When 255 is reached, it starts counting down (`up` is false), when reaching 0, it starts counting up (`up` is true). This only works if 255 / the amount to add/subtracts reaches exactly 255, otherwise you have to check for <= 0 and >= 255.

    bool up = true;
    int fade = 0;

    void loop()
    {
        fade += up ? 15 : -15;
        if (fade == 0)
        {
          up = true;
        }
        else if (fade == 255)
        {
          up = false;
        }
    }

**Not considered good coding practices:**

The last `if` statement can be substituted for the following line, which means: if going up and 255 is reached, go down, else if going down and 0 is reached, go up, otherwise don't change `direction`. But it is much less readable, so I prefer the longer `if` statement.

    up = (up && (fade == 255)) ? false : ((!up && (fade == 0)) ? true : up);

Another version: if `fade` is 0 or 255 (only two possibilities), go up if 0 is reached, else (can only be 255) go down, else don't change.

    up = (fade % 255 == 0) ? (fade == 0) : up;


body: The `if` condition is causing the issue. When the global variable `fade` reaches `240`, upon entering the `loop()`, you are incrementing it by `15`, making `fade = 255`. So, the `if` condition becomes `true` and `15` is subtracted from `255` making `fade` to be equal to `240` again. This keeps repeating and hence the value `fade` variable is stuck between the values `240` and `255`.


message:
Reading Buffer from Software-Serial & Writing to Serial

My progress so far:

```
#include <SoftwareSerial.h>

SoftwareSerial ttySerial(10, 11); // RX, TX
byte buffer;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Native USB only
  }

  Serial.println("Serial Initialized");

  //Set the data rate for the SoftwareSerial port
  ttySerial.begin(115200);
  ttySerial.println("tty Initialized");
}

void loop()
{
  ttySerial.listen();
  while (ttySerial.available())
    //byte buffer = ttySerial.read();
    //Serial.write(buffer);
    Serial.write(ttySerial.read());

//    if (Serial.available())
//      ttySerial.write(Serial.read());
}
```

I am really confused because if I write the data as the as the buffer I have defined, the serial monitor goes crazy. If I upload the code as shown, I don't get anything weird in the monitor but the behavior is not what I expect.

I am writing to the software-serial on RX10 & TX11 (from javascript) the following data:
Buffer.from(`[0, 0, 4, 0, 0, 0, 0, 0]`) (keystroke "a")

The `Buffer.from` method comes from `node` using the `serialport` `npm` module. (This is basically irrelevant since sending the data from `Buffer.from('test')` works and is output to the monitor.

As you can see, the buffer is 1 byte (the array forming the 8 bits). Why is the buffer not read as "a" in the monitor? Is it because the Micro has an abstract HID report descriptor (see below)?

Additionally, what does `Serial.write(...)` represent? I.e. when I close the Arduino IDE serial monitor, will my Arduino Micro automatically assume its HID function and write the data as an HID device? S

I know there are already `keyboard` and `mouse` HID libraries but I already have code that generates the raw HID data that I would prefer to utilize. Note that the buffer described above comes from the HID report descriptor for a generic keyboard i.e. the "4" is not merely the ASCII code for "a". [Explained Here](https://www.rmedgar.com/blog/using-rpi-zero-as-keyboard-report-descriptor) Maybe I can use https://www.arduino.cc/en/Reference/HID ?

Thanks in advance!

EDIT 1:
This is the output I see from the code as shown (without the monitor "going crazy")
```
19:51:03.017 -> Serial Initialized
19:51:13.932 -> //Where I was hoping to see "a"
```

EDIT 2: I found the report descriptor in `Keyboard.cpp`:

```
  //  Keyboard
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)  // 47
    0x09, 0x06,                    // USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x85, 0x02,                    //   REPORT_ID (2)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)

  0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)

  0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)

  0x95, 0x06,                    //   REPORT_COUNT (6)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x73,                    //   LOGICAL_MAXIMUM (115)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)

  0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x73,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0,                          // END_COLLECTION
```
I will need to compare this to the data I would be sending to `Keyboard.write()`

body:
Don't use listen() this way. It clears the receive buffer. You loose the data received before listen() call.

You have only one SoftwareSerial instance so you don't need to call listen(). The listen() function clears the receive buffer because there is only one buffer for all SoftwareSerial instances.


message:
Atmega328 standalone not working unless Pin1 connected to Arduino RESET

I'm new into this domain field. My principal occupation is as a .NET developer.
I'm trying to do a personal project in which a AtMega328 takes some output from a scale using HX711 and sends a SMS via SIM800L GSM module. Before creating the whole module I tested each part separately with Arduino and the specific modules directly on breadboard. Everything works fine.I created a standalone using the guide from Arduino website(16Mhz crystal, 2x22 picoFarad capacitors, 10k Resistor to PIN1, RX/TX connected to PIN2/3). I designed the circuit using EasyEDA, printed it into pcb and assembled it. The only issue is that, when the standalone is not connected to the Arduino, and powered up by an external 5V source, unless I connected the pin1 to Arduino(connectd to PC)RESET pin, it's not working. I tried to attach a button for RESET to PCB, and connected it to PIN1 and GND, but like this I cannot upload to Atmega328, unless i disconnect the button from 10k Resistor/PIN1 and GND. In the first picture is the standalone which is not working if powered by an externalSource, unless I remove the button and add wire between Arduino-RESET and Atmega-PIN1. In the 2nd picture is my circuit, without HX711 module and in the 3rd picture is my circuit, working only because I connected the ARDUIN-RESET to Atmega328-PIN1 .[![ATmega328 powered by wallplug, not working][2]][2][![PCB Schema, not working][3]][3][![PCB schema, working, after connecting PIN1 to Arduino RESET][4]][4]enter image description here][5]][5][![enter image description here][1]

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

  [3]: https://i.stack.imgur.com/yiFKY.jpg

body: So, the comments went to chat. Somebody recommended to use decoupling caps as close as possible near the VCC/GND of Atmega. I have 10uF in my workbench, so I used on of these caps and the issue was solved.


message:
How to display CAN BUS information on EPS32 web server?

I try to display the transmitted information from CAN bus on ESP32 web server. I saved the ```CAN.read()``` in a buffer ```receivedChars[i]``` and try to display the data by  ```client.println(receivedChars[i]);} ```. However, nothing shows on the webserver... The complete code shows below,

```
// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <CAN.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Replace with your network credentials
const char* ssid     = "NGW_2.4G";
const char* password = "NextGW2018";

// Set webserver port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

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

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);

  Serial.println("CAN Receiver");
  CAN.setPins(16, 17);
  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop() {

    char receivedChars[10];
  // try to parse packet
  int packetSize = CAN.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Received ");

    if (CAN.packetExtended()) {
      Serial.print("extended ");
    }

    if (CAN.packetRtr()) {
      // Remote transmission request, packet contains no data
      Serial.print("RTR ");
    }

    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);

    if (CAN.packetRtr())
    {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    }
    else
    {
      Serial.print(" and length ");
      Serial.println(packetSize);

      // only print packet data for non-RTR packets
      while (CAN.available())
      {
         for (int i=0; i<5; i++)
         {
           receivedChars[i] = (char)CAN.read();
           Serial.print(receivedChars[i]);
         }
      }
      Serial.println();
    }

    Serial.println();
  }

   WiFiClient client = server.available();   // Listen for incoming clients
   if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the table
            client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}");
            client.println("table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }");
            client.println("th { padding: 12px; background-color: #0043af; color: white; }");
            client.println("tr { border: 1px solid #ddd; padding: 12px; }");
            client.println("tr:hover { background-color: #bcbcbc; }");
            client.println("td { border: none; padding: 12px; }");
            client.println(".sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px; }");

            // Web Page Heading
            client.println("</style></head><body><h1>Can bus</h1>");
            client.println("<tr><td>text: </td><td><span class=\"sensor\">");

         for (int i=0; i<5; i++)
         {
           receivedChars[i] = (char)CAN.read();
           client.println(receivedChars[i]);
         }

            client.println(" .</span></td></tr>");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}
```

body: It looks like the CAN-BUS can not be activated in web server session, I save the transmitted information in a buffer before starting the web server session, and print out the information from the buffer.


message:
Firebase.failed() returns 0 after Firebase.begin(), but returns 1 while reading or writing from/to firebase from ESP8266

The program was running fine, a few days ago, but now it just wouldn't read/write to the database. I'm running on ArduinoJson 5.13.5 and using FirebaseArduino library. I have set all the rules to true, would love to know how to debug this error. Also Firebase.error() does not give any output at all!

body:
Apparently the Firebase's fingerprint has changed recently and has caused the above issue!

from here get [the latest finger print][1] and change it in the ```...\Arduino\libraries\firebase-arduino-master\src\FirebaseHttpClient.h```

In the file mentioned above: update the value of ```static const char kFirebaseFingerprint[]``` to the new one mentioned above.

P.S. One issue going forward for me(planing on implementing it on a long term basis) is how to be ahead of this issue in the future, so that I can get the data uninterrupted!

  [1]: https://github.com/FirebaseExtended/firebase-arduino/issues/476#issuecomment-591931886


message:
Use Low Power Arduino with Solar Panel

I am trying to create an arduino system with radio-transmitters and radio-receivers. The system runs from a rechargable battery that is charged with a solar panel. I am using a __1.1W 6V solar panel__.

My problem is that I don't know how to make such a connection and I don't know what batteries to choose to power the arduino, assuming that I need it to run for __5-7 days__ without solar power and that the solar panel is good enough to recharge the batteries while they power the arduino. We are also assuming that the solar panel has __8 hours of sunlight__.

To the arduino are connected the following sensors:

 - __Flame Sensor__
 - __Light Resistor x2__
 - __Smoke Sensor__
 - __Radio Transmitter__
 - __Radio Receiver__
 - __DHT11 Temperature & Humidity Sensor__

I am also looking to see if I can power down most sensors and power them on later if an event occurs. So probably all the sensors could be sleeping except the __DHT11__ and the __Radio Receiver__. Preferably though, if at all possible, the rest of the sensors should be on, if we can handle __5-7 days _without_ the solar panel__. I don't know if more information is needed but I'd be pleased to help out in the comments, or provide more information by editing the question. :)

body:
You have far too many variables and unknowns there. Primarily you need to know what the average current draw for your circuit is. Secondly you need to decide how long the solar powers are allowed to take to recharge the battery. You have to think not only about runtime but also charge time. The charge time dictates the maximum capacity of the battery, and that then dictates the runtime of the Arduino. So here's some napkin maths to illustrate:

Assuming you want the battery to charge from almost flat to full within 8 hours, and with a 1.1W 6V solar cell, that gives you a peak of 183mA.

Assuming the Arduino circuit takes 83mA on average (let's give ourselves nice round numbers here) that leaves 100mA peak for charging the battery.

If you're charging at, say, 0.2C, that gives a full charge in 5 hours. 100mA / 0.2C = 500mAh capacity (at *peak sunlight and current*).

At 500mAh capacity and 83mA average current draw that would give you (0.5/0.083) 6 hours of runtime without the solar panels.

So that's just not going to work.  It'll be dead by morning.

Now assume that you can turn off *everything* for 99% of the time.  That effectively reduces our average current draw to 0.083*0.01 = 830µA. Let's plug that into the same reasoning as above.

* Current draw = 0.00083A
* Incoming peak current = 0.183
* Available charge current = 0.183-0.00083 = 0.18217
* Charge at 0.2C = 910mAh.
* 1Ah battery would charge in about 5.5 hours of peak sunlight.
* 1Ah would last about 1200 hours, or 100 days.

None of this takes into account varying light levels or light incidence angles. As a rule of thumb, take the light as averaging 50% over the course of the 8 hour period. You will only get 1.1W when the angle of incidence is 90° to the solar panel. At all other times it will be reduced. So if we reduce the current from 183mA to, say, 100mA, the charge capacity changes to:

* Incoming peak current = 0.100
* Available charge current = 0.100-0.00083 = 0.099
* Charge at 0.2C = 496mAh
* A 500mAh battery would charge in about 5 hours.
* A 500mAh battery would run for about 50 days at 830µA average current.

So you see everything really hinges around the current consumption of the Arduino. How much current it consumes dictates how much is available to charge the battery, which in turn dictates the size of battery you can support, which dictates the amount of current you can draw for your desired runtime, which in turn dictates the amount of charge current available, which determines the size of battery you can support, which dictates ... etc.  You get the idea.

You can support larger batteries, of course - I illustrated this at 0.2C charge rate (that's 20% charge per hour to give a 5 hour charge time). As long as the net charge over time increases (so during the periods between the 5-7 days of complete darkness you gain more charge than is expended during the dark period - something which has not been specified) then it should function fine.

Also note that your battery voltage should be below your solar panel voltage. A 6V solar cell would be able to charge a 4.5V lead acid battery (assuming low dropout schottky protection diodes). Also the capacity of the battery depends also on what you determine your "cut-off" voltage to be. That's how low the battery voltage is allowed to go before your system is determined to be unworkable. This could be at a point where the battery is in danger of being damaged by over-discharge, or at a point where your circuit no longer receives enough voltage to function (which could be linked to oscillator frequency on ATMega chips), etc. For this reason it is often better to choose a board that is designed to run at a lower voltage (3.3V) and use high efficiency switching regulation to get the most out of your battery. A 5V Arduino is seldom a great choice.

Finding that right balance is now entirely up to you.

And, in answer to your other question, yes there are ways to turn things on and off. You can "sleep" the Arduino. You can use high efficiency power circuits. You can add power switching circuits (P-MOSFETs) to switch power on and off to other modules. All things can (and mostly should) be done to save power when running on batteries.


message:
Why does Arduino IDE recommend storing 0-255 numbers in "byte" instead of "char"?

I bumped into `byte` datatype recently. My knowledge of C/C++ is shallow, but I know `char` and I couldn't find much on `byte` in C++ docs. I looked it up in the [Arduino docs](https://www.arduino.cc/reference/en/language/variables/data-types/char/):
> It’s recommended to only use char for storing characters. For an
> unsigned, one-byte (8 bit) data type, use the byte data type.

Is `byte` datatype a solely Arduino construct? If so, why is it recommended over `char`? Both are 8-bit so why would it make any difference?

body:
> Is byte datatype a solely Arduino construct?

Yes. Much of the Arduino "language" is "bent" to look like Java, since it originated from Processing, which is Java. So we have data types the "look like" Java ones, including "byte" for "unsigned char" and "boolean" for "bool".

> If so, why is it recommended over char?

Personally I don't ever recommend using it, since it's non-standard. Instead you should use `uint8_t` which is essentially the same thing, but portable.

It is recommended to use "hard signedness" data types for portability.  The problem with `char` is that whether it is signed or not is entirely down to the compiler implementation. Some systems have it as signed, some as unsigned. By using `byte` (or better, `uint8_t`) you are always going to get an unsigned 8-bit value.

For just storing of binary data it doesn't really make any difference, but when it comes to doing mathematics with the stored data you may find you suddenly have negative values when you don't want negative values (a `char` *might* be storing your number as -128 to +127, not 0 to 255).


body:
Just a little add-on to Majenko's answer:

If a function has a char* parameter, it's usually expecting a zero-terminated text.

If a function has a byte* parameter, it's usually any binary data, eventually containing '\0' bytes. The buffer size needs to be an additional parameter in this case.

If there's nothing else to consider, why not use that for your variable definition too:
Use `char` only if it contains an 8bit character. Or something like `char text[]="hello";`
For binary data it might be relevant if it's signed (int8_t) or unsigned (uint8_t).

----------
"usually" implies of course that you *should* read the doc.


message:
Arduino with NRF24L01. Getting correct data from unkown transmitter

I want to use my Arduino with this: VAC8010F measure unit. It communicates with NRF24L01. The problem is I simply don't know which band or information it is receiving. Can somebody help me with this?

Thanks for any suggestions!

body:
Don't have full details yet. But the VAC8010F uses modbus RS485 protocol.
My research shows that the NRF24 just transmitts and receives the MODBUS protocol to and from master/slave. I have found modbus libs and samples of code on the net. There is a command driven program to communicate with MODBUS free for linux, which is the o/s I use. I don't know about win. Anyway, once I receive the MAX485TTL interface for my ARDUINO MEGA I will write code for data  logging to p.c. then modify to use the NRF24, as I should be able to extract the ADDRESS, and CHANNELS etc, and packet construct.

Hope this is of some help.

Patrick


body:
Nordic has an app to connect to nRF
[https://www.instructables.com/Send-Data-to-Mobile-Using-NRF24L01-Using-NRF-As-a-/][1]

The app is available for all platforms.
Did not try it myself. Hope this helps.
I going to do the same, but want receive it on Android.

If you got some news, please let me know.
Thanks

  [1]: https://www.instructables.com/Send-Data-to-Mobile-Using-NRF24L01-Using-NRF-As-a-/


message:
Streaming audio to ESP8266 over WiFi

I am thinking of making a wireless speaker using the ESP8266 chip. I have some questions regarding this.

1.  Which pin of the ESP8266 chip can be used as I²S output? I have an ESP chip of this type :
![enter image description here](https://i.stack.imgur.com/bVgel.jpg)

2. Which ESP chip would be the best choice for this purpose?

2. I know about the MAX98357A which is used to convert digital I²S data to analog. But, for stereo output I need to use 2 of those. Is there any alternative to this chip which supports stereo output by default?

3. I have found many tutorials which shows how to play audio from SD card of ESP8266. But, how can I stream audio over standard WiFi connection?

body:
> Which pin of the ESP8266 chip can be used as I²S output?

I uses GPIOs 2, 3, and 15. You only have GPIO2 available, and that's also one half of the UART interface.  Also you usually need to generate a "master" clock (usually something like 256x the bit clock) for oversampling. So you can't with that module.

> Which ESP chip would be the best choice for this purpose?

ESP32, without a shadow of a doubt.

> I know about the MAX98357A which is used to convert digital I²S data to analog. But, for stereo output I need to use 2 of those. Is there any alternative to this chip which supports stereo output by default?

Yes, there are plenty. The search term you want is "CODEC". Personally I use the TLV320DAC3101.

You never use two separate mono CODECs for stereo, since I²S is a (normally) stereo protocol for connecting to a stereo CODEC. Reliably splitting a stereo I²S stream into two mono ones is not easy.

> I have found many tutorials which shows how to play audio from SD card of ESP8266. But, how can I stream audio over standard WiFi connection?

By implementing a suitable protocol, and that depends entirely on what your audio is and how it is generated.


message:
Print 2 numbers stored in 24-bits in decimal format

An implementation function from the nice little Wiegand library [YetAnotherArduinoWiegandLibrary](https://github.com/paulo-raca/YetAnotherArduinoWiegandLibrary) prints a hexadecimal representation of a facility # & card # (8-bit facility #, 16-bit card #) — 24 bits of a 26-bit stream that comes across the wire.

Example encoded 24-bit number: 7111097 (decimal). Hex equivalent: 6C81B9. The 6C portion is the facility # (decimal: 108). 81B9 is card # (decimal 33209).

This function from the library's example usage serial prints the hexadecimal format of the number:

    void receivedData(uint8_t* data, uint8_t bits, const char* message) {
        Serial.print(message);
        Serial.print(bits);
        Serial.print("bits / ");
        //Print value in HEX
        uint8_t bytes = (bits+7)/8;
        for (int i=0; i<bytes; i++) {
            Serial.print(data[i] >> 4, 16);  //1st, 3rd, 5th hex digit
            Serial.print(data[i] & 0xF, 16); //2nd, 4th, 6th hex digit
        }
        Serial.println();
    }

What I've tried to do unsuccessfully so far is to loop over the bits to also serial print the two decimal formatted numbers (facility:card) in the final output form:  **108:33209**

body:
Your code loops from the high order byte to the low order byte, printing each byte as 2 hex digits.

If you want instead to print the first byte as a decimal value, and then the remaining bytes as another decimal value, then do this:

Print byte 0 in base 10:

        Serial.print(data[0]);  //first byte
        Serial.print(":");

Then loop through the remaining bytes, building a result as a decimal value, and print that:

    unsigned long total = 0;
    for (int i=1; i<bytes; i++) //Skip the first byte
    {
        total = total << 8;  //Shift the previous total by 8 bits.
                             //(The same as multiplying by 256, but faster)
        total += data[i];    //Add in the new value
    }
    Serial.println(total);

The sample code you posted is written to handle a variable number of bytes. The code above does the same thing with decimal results. It's much simpler if you know you will always have 3 bytes or 4 bytes:

For 3 bytes:

        Serial.print(data[0]);  //first byte
        Serial.print(":");
        long total = long(data[1])*256 + data[2]);
        Serial.println(long(total);


message:
How to set a not plugged in pin to ground or Low

I have digital pin 7 when set to High it does and when set to low it does not.

The only way I can get consistent High or Low is to use a 2 position 3 pin switch with my pin 7 in the middle and ground on one side and 5v on the other.

Is there a way I can use an simple Open/Close switch and still get the same function?

As of not if I dont "pull" pin 7 to ground I get both open and close randomly.

body:
Seems like you already found the solution. Without a pull-down of pull-up resistor, the voltage at pin 7 will float to some random voltage, when the switch is open.

Either add an (external) pull-down resistor. Or flip things around and use the **internal** pull-up resistor inside the ATMega328p. Then connect the other side of the switch to GND. Whenever the switch is pressed, your digitalWrite gives you a LOW.

To use the internal pull-up use `pinMode(7, INPUT_PULLUP);`


message:
when i compile my code i get th is error stating "checkbutton" not declared in this scope

// After 2 seconds have passed, stop ignoring the button.
      // If the button is pressed, call the checkbutton function.
      if (millis() > ignore && digitalRead(0) == LOW)
      {
        checkbutton();
      }
    }
    // This function waits for the button to be released,
    // then waits for it to be pressed to start the next run.
    void checkbutton(){
      delay (50);  // Button pressed, debounce.
      while (digitalRead(0) == LOW) // While button is pressed,
      {}                            // do nothing while waiting.
      delay (50);                   // Button pressed, debounce.
      while (digitalRead(0) == HIGH)// While button is released,
      {}                            // do nothing while waiting.

      ignore = 2000 + millis();     // Set the now ignore time,
    }                              // and return to the main loop.

body:
You are using `checkbutton()` before you have told the program what `checkbutton()` is.

You need to move the whole method definition `void checkbutton(){ ... }` more to the top, i.e. in front of any call to it (`checkbutton();`).

Another option would be a [forward declaration](https://en.wikipedia.org/wiki/Forward_declaration), but I doubt it's widely used in Arduino projects.


message:
Arduino Nano 33 IOT issue

Nano 33 IOT is not detecting by windows . When i plug the usb cable only green light on the board.
Board is installed from the board manager. the cable is usb DATA cable and not charging cable. I tried the double press on the reset button but nothing happen. The L light is Off and the green light isnt flashing.
I plugged the board into another usb port, the same issue. I tried the board on my friend computer also but no luck. I dont have ATmel ICE or any other debugger like j-link.
https://www.youtube.com/watch?v=C0tXa0uxv5c

I hope someone can explain what is the issue, is it hardware or software.

body:
If you upload to a SAMD board like the MKR boards or the Nano 33 IoT **with Nano 33 BLE selected in Tools menu** of Arduino IDE, **the upload** is executed and **deletes the bootloader of the SAMD** MCU.

The problem is that bossac uploader doesn't check the chip, because it was developed only for the SAMD chips, but Arduino created a bootloader for the Nano 33 BLE nRF52 MCU to use the SAMD bossac uploader.

The SAMD boards use the native USB support of the MCU, so without a bootloader or good sketch running the USB doesn't work.

You have to restore the bootloader on Nano 33 IoT. It is done over the SWD pads on the bottom side of the board. You can use a SWD programmer or other Arduino board with the Adafruit DAP library.

You can use your Nano 33 BLE or some other board and a SD card with Adafruit DAP library as programmer.

I had this problem with MKR Zero and I used a LPC-Link2 programmer to burn the bootloader. Once before I lost the bootloader for other reason and back then I didn't have the programmer so I used the Adafruit DAP library with an Arduino M0.

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

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

  [1]: https://microchipdeveloper.com/atmelice:connecting-atmel-ice-to-a-swd-target
  [2]: https://i.stack.imgur.com/x4cTO.png
  [3]: https://i.stack.imgur.com/dEzWF.jpg


body:
After I waited to get my order on ebay. I managed to restore the bricked board.
The issue was related to bootloader fail. either the producer shipped it without a bootloader or some kind of static discharge caused to erase or stop the booloader from working and that why windowws didnt detect the board.
I used a converted cortex m3 to swd programmer debugger and one line cmd command.

Thank for all who contributed  solutions.
If anyone experience the same hardware failure, it is due to missing or corrupted bootloader.


message:
Millis () funtion fails to perform for extended period of time

I'm using millis () function to control the timer of my LED. It is a very basic code that I used from the example libraries. The code worked well for 6 hours (On for 6 h, Off for the following 6 h and continues), however, when I set it up for 12 hours, the light failed to turn off when I checked on it. The designed time should have fit into the 2^32 bits for unsigned long which I have defined beforehand.
Can someone please help on this issue? Thank you!

    /*
      Blink without Delay

      Turns on and off a light emitting diode (LED) connected to a digital pin,
      without using the delay() function. This means that other code can run at the
      same time without being interrupted by the LED code.

      The circuit:
      - Use the onboard LED.
      - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
        and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
        is set to the correct LED pin independent of which board is used.
        If you want to know what pin the on-board LED is connected to on your
        Arduino model, check the Technical Specs of your board at:
        https://www.arduino.cc/en/Main/Products

      created 2005
      by David A. Mellis
      modified 8 Feb 2010
      by Paul Stoffregen
      modified 11 Nov 2013
      by Scott Fitzgerald
      modified 9 Jan 2017
      by Arturo Guadalupi

      This example code is in the public domain.

      http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
    */

    // constants won't change. Used here to set a pin number:
    const int ledPin =  7;// the number of the LED pin

    // Variables will change:
    int ledState = LOW;             // ledState used to set the LED

    // Generally, you should use "unsigned long" for variables that hold time
    // The value will quickly become too large for an int to store
    unsigned long previousMillis = 0;        // will store last time LED was updated

    // constants won't change:
    unsigned long interval = 12*60*60*1000UL;           // interval at which to blink (milliseconds)

    void setup() {
      // set the digital pin as output:
      pinMode(ledPin, OUTPUT);
    }

    void loop() {
      // here is where you'd put code that needs to be running all the time.

      // check to see if it's time to blink the LED; that is, if the difference
      // between the current time and last time you blinked the LED is bigger than
      // the interval at which you want to blink the LED.
      unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the LED with the ledState of the variable:
        digitalWrite(ledPin, ledState);
      }
    }

body:
Did you try to change your variables so that the calculations would be in seconds instead of milliseconds ? IOW add "/1000" after millis() and reduce your constants accordingly.

millis() is overflowing periodically, but it only happens every 49 days or so, and that even shouldn't play a role in the way you use it (the difference will also kind of overflow in the other direction).


body:
In C++, the multiplication operator is “left-associative”. This means
that the expression

```c++
12*60*60*1000UL
```

is interpreted as

```c++
((12*60)*60)*1000UL
```

The left factor, namely `(12*60)*60`, is computed using the `int` data
type, but the result overflows that format, resulting in the problem you
see.

The simple solution is to make one of the factors of the _first_ product
be an `unsigned long`. For example

```c++
1000UL*60*60*12
```

Then, `1000UL*60` is computed with the `unsigned long` data type. Since
the result is itself an `unsigned long`, the next multiplication is also
done as `unsigned long`, and likewise for the last one.

If you find this technique somewhat obscure, you can also add the `UL`
suffix to every single factor. This would avoid implicit conversions by
the compiler, making all the types explicit.


message:
Can I use 1-byte datatypes to store digital input?

I am reading the docs on [DigitalRead()](https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/) and wondering why it stores seemingly boolean `HIGH` and `LOW` inputs in `int` data type variable.

I have two issues with that:

1. `int` is 2-byte, while `bool` and `uint8_t` are 1-byte so it seems like a waste of memory for no benefit whatsoever.
2. It gets me confused when reading the code about whether the input came from digital or analog since `int` can have a wide range.

Is there any particular reason for storing digital inputs as `int`?

EDIT: `bool` and `uint8_t` are out of the question as per the answer below. **`int8_t`** still looks suitable for the purpose though.

body:
You receive the data as `int`, but you store it as `byte`.

For example, when you call the serial library function to receive a data byte, the library will return either the data or a -1 if a problem has occurred.

The binary value of -1 is a byte 11111111 or int 1111111111111111.

The binary value of 255 is a byte 11111111 or int 0000000011111111.

I think that you can see the problem if you use `byte` data and the data is 255.

So, if you receive an `int` -1, then you do not process the data.  Otherwise you `cast` the `int` to `uint8_t`.

You could receive `byte` data, but then the value of 255 would be undefined.


body:
I did not check the internals a while, but in early days there was a

     #define HIGH 1
meaning that HIGH is a `const int`.

Perhaps someone did not want to disable some TRI-STATE digital logic in the beginning, and since then nobody wanted to change the basics.

But of course `bool` is a more appropriate data type for HIGH/LOW and of course you can always treat them this way, for example like

    if (! digitalRead(pin) ) { // pin is LOW
       ...
    }

----------
jsotola's answer why Serial.read() returns  an `int` is a different issue. And correct of course.


body:
The smallest unit in most languages is a byte (8 bits), whether signed or unsigned.
So returning a byte, even if it only returns three different values, is the smallest and most efficient unit available, that I'm aware of.

If you want to store later, you can assign each bit of a byte as a high or low, thus giving you 8 storage spots.


body:
One could always store the value of digitalRead() as a bit in a variable, compacting the data from say 8 pins down into 1 byte

    // read an input and store it, say the reads of D2 thru D9 are stored in byte bits9to2
    // 9,8,7,6,5,4,3,2
    // first clear the state for 2
    bits9to2 = bits9to2 && 0b11111110; // two && for bit manipulation? Or just 1?
    // then map in the new value
    if (digitalRead(D2) == HIGH){
    bits9to2 = bits9to2 || 0b00000001;// two || for bit manipulation? Or just 1?
    }
    else{
    // leave it as 0
    }

Then to use it later on:

    if ((bits9to2 && 0b00000001) != 0){
    // bit is set (HIGH), do whatever
    }
    else {
    // bit is clear (LOW), do whatever, or maybe do nothing
    }

Can use an unsigned int and store 16 bits compacted that way, or unsigned long for 32 bits.


message:
ADXL355 accelerometer code

I am doing a project which monitors vibrations using an ADXL355 sensor and an Arduino. I have used the MPU-9250 sensor before.

I am not able to find a library or tutorials for calibrating, filtering, and reading accurate data from the sensor. Can anyone who has worked previously with the sensor help me? I am mechanical engineer new to the field of electronics.

If library files are not available, how can I use the datasheet to write the entire code myself? Is there any tutorial available for this?

Sorry if the post seems confusing..

body:
I had a similar learning path  as yours and I also tried to use ADXL345 and ADXL355. The latter was a pain for the issues described in many posts like [this](https://ez.analog.com/mems/f/q-a/109925/adxl355-latch-up-condition).

I couldn't find any good tutorial on this topic and had to learn all by myself.

I also use a different approach because I program ESP32-wrover devices with MicroPython. Nevertheless the logic is the same for translating DataSheets -> code.

1. You have to decide which serial interface to use
   * I2C if you are constrained to limited wires
   * SPI for high frequency measures

1. in both cases you write/read to/from registers of the device which are identified by an address, indicated in the datasheet (look for the registers map section). In each address you read/write a byte, that is 8 bits (0 or 1), that are packed into an hexadecimal format (e.g. you can set power mode to 'measure' writing 0x01 in register with address 0x2d)

1. with both you normally have a library that implement 3 main methods:
    1. init() for initializing the interface with the parameters you find in the datasheet:
       * SPI: polarity, phase, max_clock_frequency, first bit MSB or LSB
       * I2C: max_clock_frequency
    1. read(register_address, nbytes) -> bytearray
    1. write(register_address, bytearray)
1. before reading accelerations you must set range (e.g. ±2g), output data rate (e.g. 1000Hz), power mode (e.g. measure mode)
1. then you read acceleration data from corresponding registers. Consider that you can read multiple registers in one transaction reading multiple bytes starting from an address (e.g. you can read x,y,z measure in one transaction by starting from the first byte of x data and then reading 9 bytes = 3 axes * 3 bytes)
1. Then you have to convert from bytes to g units: in this accelerometer the value of one axis consist of 20 bits that are split in 3 bytes. You have to join the 3 bytes, shift away the trailing 4 bits, then apply two's components (that is for allowing negative numbers, look at [this guide](https://www.youtube.com/watch?v=4qH4unVtJkE)), then multiply by the scale factor indicated in the datasheet.


message:
Using DHT11 and EMF - Lag issue

The code is working but there is a delay when the LED turns on and off (physically). Is there a more efficient way I could write this code? I assume it is the delay in reading the DHT11 causing it.

~Issue resolved

body:
Your question is a bit unclear (A delay is defined by two points in time or one point and a duration -- you only tell us one point).

Reading your code, I can only assume that you mean that an external event on `inPin` is delayed in showing up on the LED on `pin11`. This should come up when that external event is emitted just at the beginning of your `delay(1000)` (and is therefore randomly delayed between 0 and 1000ms).

You could get rid of the delay in your loop using a bit of timer math around the DHT11 reading code:

```
#define DHT11_SAMPLE_DELAY = 1000
uint32_t last_dht11_reading_ms = 0;

void loop() {
  uint32_t current_ms = millis();

  if( current_ms - last_dht11_reading_ms > DHT11_SAMPLE_DELAY ) {

    DHT.read11(dht_apin);
    Serial.println("....your output....");

    last_dht11_reading_ms = current_ms;
  }
  // also, remove the delay(1000) in your loop()
}

```
You get the current time (`millis()` gives you the uptime since boot in milliseconds) and subtract the time of last reading. If the result is bigger than a threshold (in this case: 1000 ms), you do a new reading of the DHT11 while setting the variable containing the time of last reading to the current time. When the `loop()` comes around again, the threshold will not be reached, so reading the DHT11 value is skipped until `millis()` returns a sufficiently big number again.


message:
Issue with incrementing PWM over time

First post here. So I have an issue, which I have identified, but I'm not quite sure how to fix it.
I'd really appreciate some input and suggestions.
I realize that my "_pwmDelta_" is the problem, but I am not sure what to do to fix it.

I am trying to write a program that will increment the value of the pin 3 a set amount of time, in a somewhat linear fashion, _starting_ at my low point, and _finishing_ at my high point.

The issue is that my equation is incorrect and I can't output a partial bit value. Huge oversight on my part. If you read the data from the serial monitor with the code written as I have it, you'll see that it isn't coming even close to reaching my max value.

I need suggestions on how I can have the program figure out the delta in a way that I can send an integer value to the PWM output pin, yet still keep a somewhat linear increase over time. Would this even be possible?

    int motor1 = 3;         //pin for PWM output to motor
    float t = 0;            //Variable to keep Track of time
    int tLim = 30;          //Time Limit for Ramp
    float lowLim = 21;      //Low Limit, in Duty Cycle %
    float highLim = 65;     //High Limit, in Duty Cycle %
    float motorPWM = 53.55; //Starting Value of PWM, in Bits
    float pwmDelta = ((255/100)*(highLim-lowLim))/(tLim); //Delta equation, to calculate how much to change PWM value each time it is incremented
    float motorDelta;       //Variable to write value to Motor Output

    void setup() {
      pinMode(motor1, OUTPUT);
      analogWrite(motor1, 53.55); //run motor at initial value for 20 seconds before beginnning ramp
      delay(20000);
      Serial.begin(9600);
    }

    void loop() {
      motorDelta = motorPWM + pwmDelta; //incrementing output value based on Delta Equation
      motorPWM = motorDelta; //Setting new incremented value equal to old value, so incrementing can continue

      if (t <= tLim) {  //Check if time is <= time limit
        analogWrite(motor1, (motorDelta)); //write incremented value to output pin
        delay(1000);  //wait 1 second, increment t, to keep track of time
        t++;
      }
      else {
        analogWrite(motor1, motorPWM = 165.75); //set pin to high value for 60 seconds, then set to 0
        delay(60000);
        analogWrite(motor1, motorPWM = 0);
      }
      Serial.print(motorDelta);
      Serial.println();
      Serial.print(t);
      Serial.println();
    }

body:
    float pwmDelta=((255/100)*(highLim-lowLim))/(tLim);

That line should be:

    float pwmDelta=((255.0/100)*(highLim-lowLim))/(tLim);

Adding the .0 tells the compiler to do that math using floats and you get 2.55.  Without it the math is done with int and the result is 1 which isn't what you want.

    analogWrite(motor1, 53.55);

Just write 54.  analogWrite only accepts integer values.

    analogWrite(motor1, motorPWM=165.75);

You should really do that as two lines, an assgnment and then an analogWrite.  This way leads to confusing code.  Also, analogWrite only accepts integer values so your decimals are useless there as well.


body:
You are trying to smoothly ramp up the PWM value from 21% to 65% over a period of 30 seconds at 1 second intervals, which does not work very well because the PWM value has to be a byte.

That means that the value written into the PWM register changes from  21*255/100  to 65*255/100, which is 53.55 to 165.75.

Use values of 53 and 166, which gives a difference of 113.

Your code is written to update the PWM value every 1000 ms, which produces 30 steps, most of which are not integers.

Instead, ramp up the PWM value in 113 steps. Each step will be an integer and each step will be 265486 μs in length.


body:
The previous responses already showed the main issue with the program.
Here I am providing a few suggestions that hopefully could still improve
it:

 - Instead of using `delay()`, you could manage the time with
   `millis()`. This will make the ramp smoother, and you will be able to
   add code to the loop if needed that will not be blocked by the
   delays.
 - Storing the times in milliseconds and the PWM value in its natural
   unit (rather than percent) makes the code simpler.
 - Remove redundant variables, such as `motorDelta`, which is the same
   as `motorPWM`.
 - Consistent indentation and removal of superfluous parentheses help
   the readability.

Here is my attempt at implementing those suggestions:

```c++
const int motor1 = 3;  // pin for PWM output to motor
const unsigned long tLim = 30000;  // duration of the PWM ramp
const float PWM_unit = 255.0/100;  // convert percent to PWM scale
const float lowLim = PWM_unit * 21;
const float highLim = PWM_unit * 65;
const float PWM_rate = (highLim-lowLim) / tLim;

unsigned long start_time;  // start of the ramp
int previousPWM = 0;

void setup() {
    pinMode(motor1, OUTPUT);
    analogWrite(motor1, round(lowLim));
    delay(20000);
    Serial.begin(9600);
    Serial.println(" t   PWM");
    Serial.println("--------");
    start_time = millis();
}

void loop() {
    unsigned long t = millis() - start_time;

    if (t >= tLim) {  // we are done
        analogWrite(motor1, round(highLim));
        delay(60000);  // keep at highLim for 60 s
        analogWrite(motor1, 0);  // then stop
        exit(0);
    }

    int motorPWM = round(lowLim + t * PWM_rate);
    if (motorPWM != previousPWM) {
        analogWrite(motor1, motorPWM);
        Serial.print(t / 1000.0);
        Serial.print("  ");
        Serial.println(motorPWM);
        previousPWM = motorPWM;
    }
}
```


body:
What's happening is that you've written a fraction in a way that the compiler treats it as integer math. C/C++ truncate fractions, so 255/100 is just 2 (and if any of the rest of those are integers, they cause truncation too). What you want to do is make some number in that calculation a decimal--it doesn't matter which one--or cast an input to a float with `(float) somevariable`.

As long as that's all on one line, all of the calculations involved (*excepting order of operations, so cast to float one of the variables being divided* if you have them in separate parenthesized terms) will be in floating point. Do note that if you set the value of an integer with this, it will only truncate **after** doing the math accurately, too, so it's more correct.

`float pwmDelta = ((255/100)*(highLim-lowLim))/(tLim);`

Should be:

`float pwmDelta = 2.55*(highLim-lowLim)/(float)tLim;`
(This also makes it all one term.)