body:
I've got a microSD module adapter from the far east, and so far so good, and although it can create files using `writeFile`, it does not append messages. It returns `true`, i.e: message appended successfully but when you read the file on the computer or when ESP32 reads on reboot, it's blank.

This is how I call the function:
```
char* sdFileName = "/v.ea";
if (appendFile(SD, sdFileName, "Heyy")) {
//success
} else {
//failed
}
```
This is the modified, `appendFile` function:
```
bool appendFile(fs::FS &fs, const char * path, const char * message) {
  bool appendSuccess = false;
  if (DEBUG == 1) {
    Serial.print("Appending to the file: ");
    Serial.println(path);
  }
  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    appendSuccess = false;
    if (DEBUG == 1) {
      Serial.println("Failed opening the file.");
    }
  }
  if (file.print(message)) {
    appendSuccess = true;
    if (DEBUG == 1) {
      Serial.println("Appended succesfully.");
    }
  } else {
    appendSuccess = false;
    if (DEBUG == 1) {
      Serial.println("Appending failed.");
    }
  }
  file.close();
  if (appendSuccess) {
    return true;
  } else {
    return false;
  }
}
```
I've even tried the `writeFile` function with `file.seek(EOF)` but no luck.
When calling `appendFile` for the first time, this appears:
```
[W][sd_diskio.cpp:149] sdCommand(): token error [17] 0x17
Appending succesfully.
```

When the `appendFile` is called for the second time, this appears in serial monitor:
```
[W][sd_diskio.cpp:149] sdCommand(): token error [17] 0x17
[W][sd_diskio.cpp:149] sdCommand(): token error [17] 0x5
[W][sd_diskio.cpp:149] sdCommand(): token error [17] 0x5
[E][vfs_api.cpp:265] VFSFileImpl(): fopen(/sd/v.ea) failed
Appending failed.
```

I am using two SPI devices: MFRC522, and before calling SD's functions, I do a `digitalWrite(SD_SS, LOW)` to "enable" the SD functions till it completes its operations and returns back to `HIGH` to disable it.

The example in `SD(esp32)` works fine - writing, appending, deleting, renaming, etc. all work well.

title: ESP32 SD writes but doesn't append

Answers: 0


body:
What I'm trying to achieve **==>** ***Connect to my WIFI hotspot by AT commands via code then connect to my local node server by using REST API.***

Currently, I am able to send AT commands and receive responses via serial monitor when I upload an empty sketch. But when I try it via code. It's falling.
One more thing I flash my ESP8266 01 by [esp8266_flasher.exe][1]. Baud rate is 9600(AT commands are working).

This is how I wired the Arduino Uno and ESP8266 01

    Vcc -> 3,3V of Arduino
    Gnd -> Gnd of Arduino
    Rx  -> Rx of Arduino
    Tx  -> Tx of Arduino
    CH_PD -> 3.3V of Arduino

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

**CODE run on Arduino Uno to connect to WIFI**

    #define SSID "MY-WIFI" //"SSID-WiFiname"
    #define PASS "MY_WIFI_PASSWORD"  //"password"

    void setup() {
      Serial.begin(9600);               //Initialise Serial communication at 9600 bps
      Serial.println("AT");              //When baud rate matches, Print AT on Serial Monitor
      delay(5000);

      //Condition to check Whether Serial finds Ok response from ESP8266 or not
      //If It finds Ok response the call the connectWifi() Function
      if (Serial.find("OK"))
      {
        connectWiFi();

      }else {
        Serial.println("NOT Find OK");
      }
    }

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

    boolean connectWiFi()

    {
      //Enable the module to act as both Station and an access point
      Serial.println("AT+CWMODE=1");
      delay(2000);
      //Join the WIFI access point
      String cmd = "AT+CWJAP=";
      cmd += SSID;
      cmd += "", "";
      cmd += PASS;
      cmd += "";

      //Print the Wifi SSID and Password on Serial monitor
      Serial.println(cmd);
      delay(5000);

      if (Serial.find("OK"))
      {
        Serial.println("Connect to WIFI");
        return true;
      }
      else
      {
        return false;
      }
    }

My code is falling in `Serial.find("OK")` this line.

**OUTPUT when I run code on Arduino Uno with connecting ESP8266 01**
[![enter image description here][3]][3]

I couldn't figure out What I did wrong. If anyone can help me to achieve my goal with any good resources or tutorials, please let me know.

*I went through the previously asked questions, But they didn't help me.*

  [1]: https://drive.google.com/drive/folders/1xI1X0fyGxykSG61mLlZjmeo3R_Kxa2kf
  [2]: https://i.stack.imgur.com/bBAx9.png
  [3]: https://i.stack.imgur.com/eSm02.png

title: How to send AT Commands by code using Arduino uno, ESP 8266 01

Answers: 0


body:
So I have a stepper motor that's rated for 2.9V and 0.8A and I connected it to a L9110 Driver and I wanted to drive it with my arduino. But I don't know how to drive it safely without damaging the motor. I am using the stepper.h library and thought of connecting it to 3.3V pin on the Arduino but I am a bit concerned.. is it Ok to power it with 3.3V if no then What can I do?

Edit: the L9110 module I am using is a dual H Bridge.

Edit2: I was Indead Powering the Stepper and the Module directly from the arduino.. luckily the arduino survived.

Edit3: So I didn't have a 3V power supply so I used a Voltage Divider with a 9V battery and connected the L9110s module with the battery (after its voltage divided) and the module powers on.. but when the arduino starts driving the stepper the module's led starts Flickering instead of staying on and the stepper doesn't turn... I don't know what is the problem.

title: Ok to Connect 2.9V Stepper to 3.3V pin?

Answers: 1

body:
Motors draw a LOT of current compared to CMOS circuits.

The 3.3V output on most Arduinos can only provide a very small amount of current. The Arduino Uno, for example, says it only provides a max of 50mA from its 3.3V regulator. Your motor driver probably needs >10X more than that.

The overload protection on the Arduino's voltage regulator will probably kick in and cause it to shut off. It might take a while to cool down before 3.3V output comes back. I've heard that the protection on Arduino knockoffs doesn't always work, so you could also fry the voltage regulator if you try to draw too much from it.

Bottom line: **Don't do that.**

Get a high current supply for your motor driver.


body:
I tried the example  File > Examples > ESP8266WiFi > NTPClient which requests the current time and it worked fine.  Then I tried to modify it so that the ESP8266 would have a static IP address on my home network.  I added the following lines before  **void setup()**

    IPAddress staticIP(192, 168,   0, 159);
    IPAddress  gateway(192, 168,   0,   1);
    IPAddress   subnet(255, 255, 255,   0);

Then, in  **void setup()**     I added a line and commented out the original line like this

    //  WiFi.mode(WIFI_STA);
    WiFi.config(staticIP, gateway, subnet);

After running the sketch after I did this, it connected to my home network without any problems (as it did before).  But this time, after it prints the message **sending NTP packet...** to the serial monitor, it just says **no packet yet**.  This process is repeated every 10 seconds, but it never comes back with the time.

My troubleshooting efforts have been to uncomment the original line and comment out the line I added above.  This restores the sketch to its working condition.  I have done this several times over the past three days and the same thing always happens.

If I subscribed to conspiracy theories, I might think that some DHCP zealots are behind this.  Unfortunately, I can't come up with a better explanation.  So to ask just one question, "How can I get my ESP8266-01, flashed with Arduino 1.8.10, running on a Windows 8.1 laptop, to have a static IP on my home network and fetch current NTP timestamps from the internet?

(for reference, this is the sketch in question)

    /*

      Udp NTP Client

      Get the time from a Network Time Protocol (NTP) time server
      Demonstrates use of UDP sendPacket and ReceivePacket
      For more on NTP time servers and the messages needed to communicate with them,
      see http://en.wikipedia.org/wiki/Network_Time_Protocol

      created 4 Sep 2010
      by Michael Margolis
      modified 9 Apr 2012
      by Tom Igoe
      updated for the ESP8266 12 Apr 2015
      by Ivan Grokhotkov

      This code is in the public domain.

    */

    #include <ESP8266WiFi.h>
    #include <WiFiUdp.h>

    #ifndef STASSID
    #define STASSID "peopleMightFreakIfIuseMyRealInfo"
    #define STAPSK  "dontHaveAsecurityPanicAttack"
    #endif

    const char * ssid = STASSID; // your network SSID (name)
    const char * pass = STAPSK;  // your network password

    IPAddress staticIP(192, 168,   0, 159);
    IPAddress  gateway(192, 168,   0,   1);
    IPAddress   subnet(255, 255, 255,   0);

    unsigned int localPort = 2390;      // local port to listen for UDP packets

    /* Don't hardwire the IP address or we won't get the benefits of the pool.
        Lookup the IP address for the host name instead */
    //IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
    IPAddress timeServerIP; // time.nist.gov NTP server address
    const char* ntpServerName = "time.nist.gov";

    const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

    byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

    // A UDP instance to let us send and receive packets over UDP
    WiFiUDP udp;

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

      // We start by connecting to a WiFi network
      Serial.print("Connecting to ");
      Serial.println(ssid);
    //  WiFi.mode(WIFI_STA);
      WiFi.config(staticIP, gateway, subnet);
      WiFi.begin(ssid, pass);

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

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

      Serial.println("Starting UDP");
      udp.begin(localPort);
      Serial.print("Local port: ");
      Serial.println(udp.localPort());
    }

    void loop() {
      //get a random server from the pool
      WiFi.hostByName(ntpServerName, timeServerIP);

      sendNTPpacket(timeServerIP); // send an NTP packet to a time server
      // wait to see if a reply is available
      delay(1000);

      int cb = udp.parsePacket();
      if (!cb) {
        Serial.println("no packet yet");
      } else {
        Serial.print("packet received, length=");
        Serial.println(cb);
        // We've received a packet, read the data from it
        udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

        //the timestamp starts at byte 40 of the received packet and is four bytes,
        // or two words, long. First, esxtract the two words:

        unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
        unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
        // combine the four bytes (two words) into a long integer
        // this is NTP time (seconds since Jan 1 1900):
        unsigned long secsSince1900 = highWord << 16 | lowWord;
        Serial.print("Seconds since Jan 1 1900 = ");
        Serial.println(secsSince1900);

        // now convert NTP time into everyday time:
        Serial.print("Unix time = ");
        // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
        const unsigned long seventyYears = 2208988800UL;
        // subtract seventy years:
        unsigned long epoch = secsSince1900 - seventyYears;
        // print Unix time:
        Serial.println(epoch);

        // print the hour, minute and second:
        Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
        Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
        Serial.print(':');
        if (((epoch % 3600) / 60) < 10) {
          // In the first 10 minutes of each hour, we'll want a leading '0'
          Serial.print('0');
        }
        Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
        Serial.print(':');
        if ((epoch % 60) < 10) {
          // In the first 10 seconds of each minute, we'll want a leading '0'
          Serial.print('0');
        }
        Serial.println(epoch % 60); // print the second
      }
      // wait ten seconds before asking for the time again
      delay(10000);
    }

    // send an NTP request to the time server at the given address
    void sendNTPpacket(IPAddress& address) {
      Serial.println("sending NTP packet...");
      // set all bytes in the buffer to 0
      memset(packetBuffer, 0, NTP_PACKET_SIZE);
      // Initialize values needed to form NTP request
      // (see URL above for details on the packets)
      packetBuffer[0] = 0b11100011;   // LI, Version, Mode
      packetBuffer[1] = 0;     // Stratum, or type of clock
      packetBuffer[2] = 6;     // Polling Interval
      packetBuffer[3] = 0xEC;  // Peer Clock Precision
      // 8 bytes of zero for Root Delay & Root Dispersion
      packetBuffer[12]  = 49;
      packetBuffer[13]  = 0x4E;
      packetBuffer[14]  = 49;
      packetBuffer[15]  = 52;

      // all NTP fields have been given values, now
      // you can send a packet requesting a timestamp:
      udp.beginPacket(address, 123); //NTP requests are to port 123
      udp.write(packetBuffer, NTP_PACKET_SIZE);
      udp.endPacket();
    }

title: unable to modify NTPClient to use static IP address

Answers: 2

body:
As well as specifying your IP address and gateway you also have to provide DNS server addresses. These are normally provided by DHCP, and the ESP8266 *doesn't* assume that it's the same as your gateway address when using a static IP address.

Normally you would use your router's IP address as your DNS server address, but you can also use the Google public DNS servers on `8.8.8.8` and `8.8.4.4`.

The full format of the `config` function is:

```c++
  WiFi.config(staticIP, gateway, subnet, dns);
```

where `dns` is, like the other parameters, an `IPAddress`.

body:
If you use Arduino IDE with <ESP8266WiFi.h> there is a different order for the arguments in the config-statement See the comment in the source code: //ESP argument order is: ip, gateway, subnet, dns1
//Arduino arg order is: ip, dns, gateway, subnet.

So after lots of trouble i changed my config in WiFi.config(STATICIP, DNS1, GATEWAY, SUBNET) and everything works smooth now. The comment means that if you use ESP-IDE (?) the argument order is: ip, gateway, subnet, dns1. When you use Aduino IDE (for ESP8266) the argument order is: ip, dns, gateway, subnet._


body:
I have this code that takes temperature and humidity values from a DHT11 sensor and number of faces from an external python code and prints them on an OLED screen but instead of values of variables it keeps printing 0, how can I solve it? (Sorry some parts are not in English but just consider them as random variable names.)

    //dht11 kodu için ayarlamalar
    #include <dht.h>
    dht DHT;
    #define DHT11_PIN 7

    //ekran için ayarlamalar
    #include "U8glib.h"
    U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
    char bufferX [20];
    char bufferY [20];
    char bufferZ [20];

    //fan kodu için ayarlamalar
    int mot1 = 8;
    int mot2 = 9;
    int en1 = 10;
    int dir = 6;
    bool state = true;
    int nob = A0;
    int val = 0;
    int fan_hizi = 0;
    String faces_str;
    int faces;
    float sicaklik;
    float nem;

    void draw(void)
    {
      u8g.setFont(u8g_font_unifont);
      u8g.drawStr( 0, 15, bufferX);
      u8g.drawStr( 0, 30, bufferX);
      u8g.drawStr( 0, 45, bufferY);
      u8g.drawStr( 0, 60, bufferZ);
    }

    void setup() {
      Serial.begin(9600); //iletişim ve dht11 verisi

      // pin ayarları
      pinMode(mot1,OUTPUT);
      pinMode(mot2,OUTPUT);
      pinMode(en1,OUTPUT);
      pinMode(dir,INPUT_PULLUP);
    }

    void loop() {
      //dht11 kodu
      sicaklik = DHT.temperature;
      nem = DHT.humidity;
      delay(1000);

      //iletişim kodu
      if(Serial.available() > 0) {
        faces_str = Serial.readString();
        faces = faces_str.toInt();
      }

      Serial.print(faces);

      //sınırlar
      if(faces == 0 && sicaklik < 25 && nem < 65) {
        fan_hizi = 50;
        digitalWrite(13, HIGH);
        digitalWrite(12, LOW);
      }
      if(faces >= 1 || sicaklik >= 25 || nem >= 65) {
        fan_hizi = 250;
        digitalWrite(13, LOW);
        digitalWrite(12, HIGH);
      }

      //ekran
      sprintf(bufferX, "Yuzler: %d", faces);
      sprintf(bufferY, "Sicaklik: %d", sicaklik);
      sprintf(bufferZ, "Nem: %d", nem);
       u8g.firstPage();
      do {
      draw();
        }
      while ( u8g.nextPage() );
      delay(10);

      //fan kodu
      analogWrite(en1, fan_hizi);
      digitalWrite(mot1, HIGH);
      digitalWrite(mot2, LOW);
      delay(1000);
      digitalWrite(mot1, LOW);
      }

title: Printing vairable with U8GLib

Answers: 1

body:
I do not understand, how you initialize the DHT sensor object.
(I wonder why this compiles at all.)

Your way:

    //dht11 kodu için ayarlamalar
    #include <dht.h>
    dht DHT;
    #define DHT11_PIN 7

I would use:

    //dht11 kodu için ayarlamalar
    #include <DHT.h>
    #define DHT11_PIN 7

    DHT dht( DHT11_PIN, DHT11 );

Don't forget to start the DHT object with:

    void setup() {
      // ... code removed for brevity
      dht.begin();
    }

Now use the `dht` object instad of the DHT class.

    sicaklik = dht.readTemperature();
    nem = dht.readHumidity();

You did not specify what libraries you have used. But I tried all DHT libs I could find and none of them compiled with your code without errors.

The following code compiles on my IDE for an arduino UNO having olivers ug8lib and adafruits DHT sensor library installed. BTW: You even did not mention the Arduino/ESP you used. So I guess it is an UNO.

    //dht11 kodu için ayarlamalar
    #include "DHT.h"
    #define DHT11_PIN 7
    DHT dht( DHT11_PIN, DHT11 );

    //ekran için ayarlamalar
    #include "U8glib.h"
    U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
    char bufferX [20];
    char bufferY [20];
    char bufferZ [20];

    //fan kodu için ayarlamalar
    int mot1 = 8;
    int m ot2 = 9;
    int en1 = 10;
    int dir = 6;
    bool state = true;
    int nob = A0;
    int val = 0;
    int fan_hizi = 0;
    String faces_str;
    int faces;
    float sicaklik;
    float nem;

    void draw(void)
    {
      u8g.setFont(u8g_font_unifont);
      u8g.drawStr( 0, 15, bufferX);
      u8g.drawStr( 0, 30, bufferX);
      u8g.drawStr( 0, 45, bufferY);
      u8g.drawStr( 0, 60, bufferZ);
    }

    void setup()
    {
      Serial.begin(9600); //iletişim ve dht11 verisi

      // pin ayarları
      pinMode(mot1,OUTPUT);
      pinMode(mot2,OUTPUT);
      pinMode(en1,OUTPUT);
      pinMode(dir,INPUT_PULLUP);
    }

    void loop()
    {
      //dht11 kodu
      sicaklik = dht.readTemperature();
      nem = dht.readHumidity();
      delay(1000);

      //iletişim kodu
      if(Serial.available() > 0)
      {
        faces_str = Serial.readString();
        faces = faces_str.toInt();
      }

      Serial.print(faces);

      //sınırlar
      if(faces == 0 && sicaklik < 25 && nem < 65)
      {
        fan_hizi = 50;
        digitalWrite(13, HIGH);
        digitalWrite(12, LOW);
      }

      if(faces >= 1 || sicaklik >= 25 || nem >= 65)
      {
        fan_hizi = 250;
        digitalWrite(13, LOW);
        digitalWrite(12, HIGH);
      }

      //ekran
      sprintf(bufferX, "Yuzler: %d", faces);
      sprintf(bufferY, "Sicaklik: %d", sicaklik);
      sprintf(bufferZ, "Nem: %d", nem);
      u8g.firstPage();

      do
      {
        draw();
      }  while ( u8g.nextPage() );

      delay(10);

      //fan kodu
      analogWrite(en1, fan_hizi);
      digitalWrite(mot1, HIGH);
      digitalWrite(mot2, LOW);
      delay(1000);
      digitalWrite(mot1, LOW);
    }

I do not have the time to assemble the hardware to try it.
So I can say it compiles, but I can not say it works.

**EDIT:**

Now I found adidax "DHT11 lib". your code compiles with this library. But you forgott to read the values from the sensor, before you read them from the variables.

The following line is missing:

    void loop() {
      //dht11 kodu
      DHT.read( DHT11_PIN ); // <-- this line is missing
      sicaklik = DHT.temperature;
      nem = DHT.humidity;
    ...


body:
I am working on a personal project in which I need to collect accurate data from the **MPU6050** using an **Arduino Due**.

I can interface and read data from the MPU using the **SLC and SDA pins** and the "Adafruit Library" or the "MPU6050_Light" library. However I have been told that the [Jeff Rowberg library][1] combines both accelerometer data and gyroscope data to get a more accurate measurement of roll, yaw, and pitch. Every time I've tried using the library I get the error below:

Arduino: 1.8.13 (Windows 10), Board: "Arduino Due (Programming Port)"

...

exit status 1

Is there anything I can do to get this to work on the Due's processor (which I know has a different architecture). If not what can I do to get accurate reading on the Due. I should note that the code works perfectly fine on the Uno.

  [1]: https://github.com/jrowberg/i2cdevlib

title: Connecting MPU6050 to Arduino Due but using Jeff Rowbergs Library

Answers: 0


body:
Good day. Tell me an excellent library for working with a 4-digit 7-segment indicator.
I am currently using `#include <fDigitsSegtPin.h>`

But it does not allow you to display letters, does not allow you to put dots in the right place.
I think it is not flexible.
I want it to be easy enough to control the indicator and have sufficient freedom to choose segments (numbers, letters, dots, dashes). I tend to use the library: "`SevenSeg` library".

Tell me a really good option for my goal, and so that, as always, this library does not slow down all the code

I am using an indicator of the form:
[![enter image description here][1]][1]

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

title: Library for working with a 4-digit 7-segment indicator SH5461AS

Answers: 1

body:
This one  [tm1637][1] sounds good. I was thinking to use it next time.
**Edit 1:**
Lately posted image suggests that it is without a separate display controller chip, then this [library][2] should work.
**Edit 2:**
This library specific to the SH5461AS display: [Library][3]
 Include these three libraries:

    #include "Segment.h"
    #include "Digit.h"
    #include "Display.h"

Print needs to be in the loop:

    void loop() {
      d.print("1.234"); // Must be looped!
    }

  For disabling decimal points:

    #define DISABLE_DP
The library's Github has very good documentation too

  [1]: https://github.com/bremme/arduino-tm1637/blob/master/README.md
  [2]: https://github.com/DeanIsMe/SevSeg/blob/master/SevSeg.h
  [3]: https://github.com/UniQHW/SH5461AS


body:
i am using NodeMCU (ESP8266) to communicate with another NodeMCU (ESP8266) using Serial Communication. Because i am using ESP-NOW to communicate and ESP-NOW and WiFi can not work together very well so trying with this serial communication option.

Here is how i connected the pins:

       Slave ->   Master
        D1    ->   D2
        D2    ->   D1
        GND   ->   GND

Here is how my sketch looks like:

**Sender.ino**

    #include <Wire.h>

    void setup() {
      Serial.begin(115200);
      Wire.begin(D1, D2); /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
    }

    void loop() {
      // put your main code here, to run repeatedly:
       Wire.beginTransmission(5); /* begin with device address 8 */
       Wire.write("Hello ESP 2");  /* sends hello string */
       Wire.endTransmission();    /* stop transmitting */

       Wire.requestFrom(5, 4); /* request & read data of size 13 from slave */
       while(Wire.available()){
          char c = Wire.read();
        Serial.print(c);
       }
       Serial.println();
       delay(1000);
    }

**Receiver.ino**

    #include <Wire.h>

    void setup() {
     Wire.begin(5);
     Wire.onReceive(receiveEvent); /* register receive event */
     Serial.begin(115200);           /* start serial for debug */
    }

    void loop() {
     delay(100);
    }

    // function that executes whenever data is received from master
    void receiveEvent(int howMany) {
     while (0 <Wire.available()) {
        char c = Wire.read();      /* receive byte as a character */
        Serial.print(c);           /* print the character */
      }
     Serial.println();             /* to newline */
    }

But the communication is not working at all, not sure where i am wrong. It can code wise or may be via connection wise or it might be possible that NodeMCU to NodeMCU connection is not possible at all!

Thank you!

title: Send data from one NodeMCU to another NodeMCU using Serial Communication

Answers: 1

body:
As already stated, your code uses the I2C interface (via the `Wire` library) and not the Serial interface (which is an Arduino term for UART). They work fundamentally different.

As you only communicate between 2 devices, which you both can program yourself. I would ditch the I2C interface. It doesn't give you any advantage here, but some disadvantages (for example, that you can't have real bidirectional communication, as the slave cannot do anything by its own, only, if the master asks for it).

Instead you should use a Serial (UART) interface. As the NodeMCU only has 1 full hardware Serial interface, which you already use for debugging, you could use the `ESPSoftwareSerial` library to create an extra Serial interface via software. It has limitations (in how many interfaces can listen at a time and how fast the communication can go), but most likely this will solve your problem. Also Serial is easier for beginners, than I2C.


body:
Using the [Ticker](https://github.com/bertmelis/Ticker-esp32/blob/master/src/ESP32Ticker.h) library for the ESP32, how can I use a lambda as an argument to the _attach_ method?

    tickerSystemManager.attach(1000, [&](){
      systemManager->sync();
    });

Attempting to use the above, I get the following error:

    Matrx.cpp:11:4: error: no matching function for call to 'Ticker::attach(int, Matrx::setup()::<lambda()>)'
    ...
    Ticker.h:40:8: note: candidate: void Ticker::attach(float, Ticker::callback_t)

How can I capp a lambda into this method?

title: Using lambdas as callback functions

Answers: 1

body:
As @timemage explains in a comment, you cannot pass a capturing lambda
to a function that expects a plain pointer to function. There is,
however, a way out of this: the `Ticker` class provides an overload of
the `attach()` method that allows you to provide a parameter of any type
to tour callback:

```c++
template<typename TArg>
void attach(float seconds, void (*callback)(TArg), TArg arg)
```

You can use this version of `attach()` and provide it both

* a non-capturing lambda that gets a pointer to `systemManager`
* that pointer as a third argument.

**Edit**: I did a few tests, and it seems my compiler cannot properly
perform template argument deduction in this case, but the approach works
if you explicitly specialize the template. Namely:

```c++
tickerSystemManager.attach<typeof systemManager>(
    1000,
    [](typeof systemManager p){ p->sync(); },
    systemManager);
```


body:
I want to make an 8*8 led matrix. I found this code on the web:

[![i ][1]][1]

```c++
    int latchPin = 12;  //Pin connected to ST_CP of 1st 74595
    int clockPin = 13;  //Pin connected to SH_CP of 1st 74595
    int dataPin = 11;   //Pin connected to DS of 1st 74595

    int latchPin2 = 6;  //Pin connected to ST_CP of 2nd 74595
    int clockPin2 = 7;  //Pin connected to SH_CP of 2nd 74595
    int dataPin2 = 5;   //Pin connected to DS of 2nd 74595

    void setup() {
      //set pins to output so you can control the shift register
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);

      pinMode(latchPin2, OUTPUT);
      pinMode(clockPin2, OUTPUT);
      pinMode(dataPin2, OUTPUT);
    }

    void loop() {
      /************** Send HIGH to first Anode pin (16th pin) and LOW to all
      other anode pins (15, 11, 3, 10, 5, 6, 13) of LED matrix *************/

      // take the latchPin low so the LEDs don't change while you're sending in bits:
      digitalWrite(latchPin, LOW);
      //Send 0 0 0 0 0 0 0 1 (1) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
      shiftOut(dataPin, clockPin, MSBFIRST, 1);
      // shift out the bits:
      digitalWrite(latchPin, HIGH);

      /**************** Send LOW to the first cathode pin (4th pin) and HIGH to all
        other cathode pins (7, 2, 8, 12, 1, 14 and 9) of LED matrix *****************/

      // take the latchPin low so the LEDs don't change while you're sending in bits:
      digitalWrite(latchPin2, LOW);
      // Send 1 1 1 1 1 1 1 0 (254) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
      shiftOut(dataPin2, clockPin2, MSBFIRST, 254);
      // shift out the bits:
      digitalWrite(latchPin2, HIGH);
    }
```

I expected this code to turn on the first LED, but when I uploaded this code nothing lights up. I checked my rows and colum connections.

Also, I want to ask if a 74hc595 can output sink current?

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

title: What's wrong with this code..?

Answers: 1

body:
I can't add comment to your question so I post as an answer even though this is not much an answer. This is just a hint to solve your problem.

8x8 led matrix and 595s are pretty *low-level* stuff, so I assume you have some knowledge about electronics and programming in general.

I think your wiring is OK but I also think you misunderstand how 595 works.

Here is the flow taken from a library (ESP32) for 64x64 RBG LED panel using bunch of 595s:

    uint8_t data[8]; // data for one row

    digitalWrite(OE_PIN, HIGH); // disable output, 595 outputs go into high impedance state

    for (int i=0; i<8; i++)
      shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, data[i]);  // dump data out

    digitalWrite(LATCH_PIN, LOW);  // pulse 1 clock
    delayMicroseconds(1); // note 2*
    digitalWrite(LATCH_PIN, HIGH); // latch is active high

    digitalWrite(OE_PIN, LOW); // Enable output

I think now you know how to fix your code.

Note 1: I find those names ***SER, SRCLK, RCLK*** (on TI's datasheet) are confusing. I prefer the names ***SERIAL DATA INPUT, SHIFT CLOCK, LATCH CLOCK*** (on ONSEMI MC74HC595 datasheet) or better ***DATA, CLK, LATCH, OE, RESET***.

Note 2: Check 74HC595 datasheet to see clock pulse width limit and speed limit. And if you are using UNO or MEGA (@16MHz), you are good without stretching the clock (data clock and latch clock). If you use higher speed MCU, e.g: ESP32@240MHz or STM32@72MHz, you have to consider clock stretching there and also inside shiftOut() function.

To improve your circuit, you should wire both OE of 595s to a Digital pin. You can also connect both latch pin into one digital pin. Every time you latch, botch 595 latch, and every time you enable output, both enable output.

So with your configuration, just shiftOut data normally for the 595 on the left and invert data for the 595 on the right, like this

    #define DATA_COL_PIN 11
    #define DATA_ROW_PIN 5
    #define CLOCK_COL_PIN 13
    #define CLOCK_ROW_PIN 7

    #define OE_PIN 4 //use digital pin 4 to enable output on both 595s
    #define LATCH_PIN 6 // or 12, but you must connect both latch inputs of both 595s together

    uint8_t col = 0b00000001; // for the left 595
    uint8_t row = 0b00000001; // for the right 595

    digitalWrite(OE_PIN, HIGH);
    shiftOut(DATA_COL_PIN, CLOCK_COL_PIN, MSBFIRST, col);
    shiftOut(DATA_ROW_PIN, CLOCK_ROW_PIN, MSBFIRST, ~row); // ~row = 0b11111110 = invert_bits(row)
    digitalWrite(LATCH_PIN, LOW);
    digitalWrite(LATCH_PIN, HIGH);
    digitalWrite(OE_PIN, LOW);

The code above is just for you to understand how it works. Normally, they would work on a buffer such as

    uint8_t row[8]; // each byte is one row

And they do row scanning, turn one row ON at a time and just flip each column ON and OFF following the byte data of that row.

I stop here as this is going off-topic. You just ask what is wrong with your code right?

BTW, 595 can sink/source 35mA on each pin (70mA in total). So if you want to light up one row at a time with your setup, you should choose each current limiter carefully so that not to exceed 70mA in total.

> 70mA / 8xLED = 8.75mA for each LED (assume red LED)
>
> (5v - 1v7) / 8.75mA = 377R

It's likely the resistors should be at least 377 ohm or 470 ohm for safety.


body:
I am trying to control a continuous servo (MG996R) with an RF remote, but it's not working; the servo just spins in one direction.

I am new to Arduino so I don't really know if the code is correct.

This is my code:

```c++
#include <Servo.h>

Servo servothumb;
Servo servoindex;
Servo servomiddle;
Servo servoring;
Servo servopinky;

void setup() {
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  pinMode(5,INPUT);
  Serial.begin(9600); // setting baud rate
  Serial.println(" Data 4 Ch Remote Control");
  servothumb.attach(9);
  servoindex.attach(10);
  servopinky.attach(11);
  servoring.attach(12);
  servomiddle.attach(13);
}

void loop() {
  if (digitalRead(2) == HIGH) { // Button B pressed
    Serial.println("B");
    servothumb.write(90);
    servoindex.write(90);
    servopinky.write(90);
    servoring.write(90);
    servomiddle.write(90);
  } else {
    servothumb.write(90);
    servoindex.write(90);
    servopinky.write(90);
    servoring.write(90);
    servomiddle.write(90);
  }

  if (digitalRead(3) == HIGH) { // Button D pressed
    Serial.println("D");
  }
  if (digitalRead(4) == HIGH) { // Button A pressed
    Serial.println("A");
    servothumb.write(0);
    servoindex.write(0);
    servopinky.write(0);
    servoring.write(0);
    servomiddle.write(0);
  } else {
    servothumb.write(90);
    servoindex.write(90);
    servopinky.write(90);
    servoring.write(90);
    servomiddle.write(90);
  }
  if (digitalRead(5)== HIGH) { // Button C pressed
    Serial.println("C");
    servothumb.write(180);
    servoindex.write(180);
    servopinky.write(180);
    servoring.write(180);
    servomiddle.write(180);
  } else {
    servothumb.write(90);
    servoindex.write(90);
    servopinky.write(90);
    servoring.write(90);
    servomiddle.write(90);
  }
}
```

title: I am trying to control a continuous servo (MG996R) with an RF remote but it's not working

Answers: 0


body:
I have a code that spit out random number when the ISR register is ready:

    #define TRNG_KEY  0x524E47
    uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
    uint32_t msk = 0x1FE;

    void setup()
    {
      Serial.begin(9600);
      PIOC->PIO_PER = msk;
      PIOC->PIO_OER = msk;
      PIOC->PIO_OWDR = ~msk;

      PMC->PMC_PCER1 = PMC_PCER1_PID41;
      TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY);
      TRNG->TRNG_IER = 1 << 0;
    }

    void loop()
    {
      if (TRNG->TRNG_ISR == 1) {
      PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10];
      }
      delay(500);
    }

The code above works. However, when I tried to switch to internal interrupt:

    #define TRNG_KEY  0x524E47
    uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
    uint32_t msk = 0x1FE;

    void setup()
    {
      Serial.begin(9600);
      PIOC->PIO_PER = msk;
      PIOC->PIO_OER = msk;
      PIOC->PIO_OWDR = ~msk;

      PMC->PMC_PCER1 = PMC_PCER1_PID41;
      TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY);
      TRNG->TRNG_IER = 1 << 0;

      NVIC_EnableIRQ(TRNG_IRQn);
    }

    void loop()
    {

    }

    void TRNG_Handler(void) {
      PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10];
    }

The code only spit out one random number and then freezes, indicating TRNG_Handler(void) was only executed once. I cannot figure out why.

Thanks in Advance !

title: Why NVIC_EnableIRQ handler function only run once?

Answers: 1

body:
Two things:

1. Never use `delay()` inside an ISR. On *some* systems it may work, but on most it will just block. It's bad practice to have your ISRs run for more time that absolutely needed anyway.
2. You need to read the status register for the TRNG to clear the interrupt flag. You're doing that in your first code sample with `if (TRNG->TRNG_ISR == 1) {`.


body:
I want to create something similar to an article I read a few months ago about the effects of Dopamine. Dopamine is known as the feel-good neurotransmitter; the brain releases it when we eat food that we crave, contributing to pleasure and satisfaction as part of the reward system. I want to use this reward method for breaking habits and creating new ones. I saw someone on youtube make a Dopamine box, very similar to what I was thinking (I left it down below), but I think it had a few design flaws.

So how it works, the lights will be dimmed (so it’s not annoying) and default red, the screen in the center will read the list of activities you have set for yourself that you want to be completed. When you complete a task, you will flip a switch on the housing side; this will toggle some lights to go from red to green and give you the reward system. Along with the lights turning green, the box will play a sound, similar to when you win a game or get a kill, again triggering the dopamine release.

The LCD will display a message, something like "keep going"  or "Don't quit."
The LED is for the green and red lights mentioned above, and the piezo is for a buzzer to play a sound to congratulate you for finishing a task.

Down below, I left a circuit I [made in TinkerCad][1]. I am very new to this, and I would like if someone could look at my connections and tell me if I have connected them correctly.

TinkerCad Link- https://www.tinkercad.com/things/9EYfcPv1XsX

[![Capture from Tinkercad showing circuit.][2]][2]

  [1]: https://www.tinkercad.com/embed/9EYfcPv1XsX?editbtn=1
  [2]: https://i.stack.imgur.com/5hYKv.png

title: Is this circuit connected right?

Answers: 0


body:
I'm working on a project and using a nema 23 stepper motor and driver.

* Need to be able to move the stepper 1/32 rotation when I press a button.

* I need a small delay so I have time to release the button and not move the 1/32 rotation twice or more (its in a loop) before I can release the button.

* I also want to the stepper to continue to move in 1/32 rotation increments as long as the button is held down.

I can get this to work with the move() and runToPosition() commands, but it accelerates and decelerates each time making the movement much slower then I need.   I would just use the runSpeed() command inside a while loop setting move() each time, but I need the acceleration as the pull in torque of the stepper is not great enough to start at the full speed needed.

Any ideas or suggestions would be greatly appreciated.

title: Using AccelStepper to move a set distance while a button is held down

Answers: 0


body:
I have a function for HTTP_POST responses but it is never called when I post to it. I get the webpage instead.

I call on it with

    server.on("/",HTTP_POST,response);

But I only get the url in response.

    void setup() {
        pinMode(led_pin, OUTPUT);

        Serial.begin(115200);
    #if defined(__AVR_ATmega32U4__) || defined(SERIAL_USB) || defined(SERIAL_PORT_USBVIRTUAL)
        delay(2000); // To be able to connect Serial monitor after reset and before first printout
    #endif
        // Just to know which program is running on my Arduino
        Serial.println(F("START " __FILE__ " from " __DATE__));
        Serial.print(F("Ready to send IR signals at pin "));
        Serial.println(IR_SEND_PIN);

        pinMode(led_pin, OUTPUT);
        digitalWrite(led_pin, 0);
        Serial.begin(115200);
        WiFi.mode(WIFI_STA);
        WiFi.begin(ssid, password);
        Serial.println("");

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

        Serial.println("");
        Serial.print("Connected to ");
        Serial.println(ssid);
        Serial.print("IP address: ");
        Serial.println(WiFi.localIP());

        if (MDNS.begin("esp32")) {
          Serial.println("MDNS responder started");
        }

        server.on("/", handleRoot);
        server.on("/test.svg", drawGraph);
        server.on("/",HTTP_POST,response);
        server.on("/inline", []() {
        server.send(200, "text/plain", "this works as well");
        });
        server.onNotFound(handleNotFound);
        server.begin();
        Serial.println("HTTP server started");

    }

    void response(){
      //int khz = 38; // 38kHz carrier frequency for the NEC protocol

      if(server.hasArg("on") && (server.arg("on").length()>0)){ // TODO check that it's not longer than 31 characters
          Serial.print("Server was turned on:\t");
          Serial.println(server.arg("on"));

          ++CYCLE0;
          server.sendHeader("Location", String("/"), true); //how to do a redirect, next two lines
          server.send ( 302, "text/plain", "");
      } else if (server.hasArg("off") && (server.arg("off").length()>0)){
          Serial.print("Server was turned off:\t");
          Serial.println(server.arg("off"));

          ++CYCLE1;
          server.sendHeader("Location", String("/"), true);
          server.send ( 302, "text/plain", "");

       } else if (server.hasArg("up") && (server.arg("up").length()>0)){
          Serial.print("Server temp was turned up:\t");
          Serial.println(server.arg("up"));

          ++CYCLE2;
          server.sendHeader("Location", String("/"), true);
          server.send ( 302, "text/plain", "");

      } else if (server.hasArg("down") && (server.arg("down").length()>0)){
          Serial.print("Server temp was turned down:\t");
          Serial.println(server.arg("down"));

          ++CYCLE3;
          server.sendHeader("Location", String("/"), true);
          server.send ( 302, "text/plain", "");

      } else {
        server.send(400, "text/html", "
HTTP Error 400

Bad request. Please enter a value.
");
      }
    }

How do you get an http post response back instead of a webpage?

POST response:

     <meta http-equiv='refresh' content='5' />
     <title>ESP32 Demo</title>

Hello from ESP32!

Uptime: 00:05:32

Turn air condistioner on

AC has been cycled 0 times

     <form name='frm0' method='post'> <input type='text' name='on' value=8000>
      <input type='submit' value='Submit'>     </form>

Turn air conditioner off 0 times

      <form name='frm1' method='post'> <input type='text' name='off' value=8000>
       <input type='submit' value='Submit'>     </form>

Turn temperature up 0 times

       <form name='frm2' method='post'> <input type='text' name='up' value=8000>
        <input type='submit' value='Submit'>     </form>

Turn temperature down 0 times

        <form name='frm3' method='post'> <input type='text' name='down' value=8000>
         <input type='submit' value='Submit'>     </form>

Complete code

[long version][1]

  [1]: https://bpa.st/HSTQO

title: How do I get an HTTP_POST response?

Answers: 1

body:
You have:

```c++
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
server.on("/",HTTP_POST,response);
```

The first call using `handleRoot` species no particular method, and in this case it seems [any method is acceptable][1].  You later specify `server.on("/",HTTP_POST,response);` specifically for POST requests.  These are [added to a request handler list][2] in the order given.  And apparently [consulted][3] in the order given.

In short, you need to specify `HTTP_GET` for `handleRoot` or just specify your `HTTP_POST` for `response` first and let `handleRoot` catch non-`HTTP_POST` requests afterwards:

```c++
server.on("/",HTTP_POST,response);
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
```

  [1]: https://github.com/espressif/arduino-esp32/blob/1.0.5-rc6/libraries/WebServer/src/WebServer.cpp#L250
  [2]: https://github.com/espressif/arduino-esp32/blob/1.0.5-rc6/libraries/WebServer/src/WebServer.cpp#L266
  [3]: https://github.com/espressif/arduino-esp32/blob/1.0.5-rc6/libraries/WebServer/src/Parsing.cpp#L116


body:
I have been stuck for a long time on a piece of Arduino code that performs an FFT on a Photoplethysmogram signal and decides signal quality after that.

```
#include <math.h>
#include "arduinoFFT.h"
#include <EEPROM.h>

//N=10 pt moving average
//For bidmc data of first 10 patients, MA = 0.4613849
double baseline=0.4613849;
float lm=1.0; //amplitude threshold
float ref_voltage=1.0; //saturation reference voltage
float cutoff=4.0;
float fs=0.02;
float zero_amp=0.015;

float pi=3.14159265;  //Universal Constants
float e=2.71828;
const int flen=61;

#define SAMPLES 128           //Must be a power of 2
#define SAMPLING_FREQUENCY 50 //Hz, must be less than 10000 due to ADC

arduinoFFT FFT = arduinoFFT();
unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
  Serial.begin(9600);
  sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}

void loop() {
  //float arr[]={0.43597,0.43206,0.42815,0.42424,0.42131,0.41838,0.4174,0.41642,0.41544,0.41447,0.41251,0.41153,0.40958,0.40762,0.40665,0.40665,0.40665,0.40762,0.4086,0.4086,0.41056,0.41153,0.41153,0.41056,0.4086,0.40665,0.40469,0.40469,0.40567,0.4086,0.41251,0.42033,0.43206,0.45259,0.4741,0.4956,0.51808,0.5347,0.55034,0.56403,0.57576,0.58456,0.59238,0.59629,0.59922,0.60117,0.60215,0.60313,0.60313,0.60117,0.59824,0.59335,0.58553,0.57771,0.57185,0.56207,0.54741,0.53372,0.52102,0.50929,0.50244,0.49756,0.4956,0.49462,0.49365,0.49365,0.49365,0.49169,0.48876,0.4868,0.48387,0.48094,0.47801,0.47507,0.47116,0.46823,0.46334,0.45846,0.45357,0.44868,0.44379,0.43891,0.435,0.43109,0.4262,0.42326,0.42033,0.41838,0.41642,0.41447,0.41447,0.41349,0.41251,0.41251,0.41251,0.41251,0.41251,0.41349,0.41544,0.4174,0.41935,0.42033,0.42131,0.42131,0.42033,0.41935,0.41642,0.41447,0.41349,0.41349,0.41642,0.42131,0.42815,0.43695,0.45064,0.46823,0.4868,0.50538,0.52395,0.54154,0.55816,0.57185,0.58162,0.58749,0.59042,0.59042,0.5914,0.59042,0.58944,0.58651,0.5826,0.57771,0.57087,0.56305,0.5523,0.54057,0.52884,0.51711,0.50733,0.49756,0.48778,0.47996,0.4741,0.47019,0.46823,0.46725,0.46628,0.46432,0.46041,0.4565};
  float arr[]={0.30303,0.29814,0.29326,0.28837,0.28446,0.28152,0.27859,0.27468,0.26979,0.26393,0.25806,0.25611,0.25904,0.27175,0.29521,0.32942,0.37341,0.42522,0.47116,0.51417,0.55914,0.6002,0.63539,0.66373,0.68622,0.70381,0.71652,0.72532,0.73118,0.73314,0.73314,0.73021,0.7263,0.72043,0.71359,0.70479,0.69501,0.68524,0.67351,0.6608,0.64614,0.6305,0.61388,0.59726,0.58065,0.56207,0.54252,0.52395,0.50538,0.48778,0.47312,0.46041,0.44868,0.43988,0.43304,0.42815,0.42522,0.42229,0.41935,0.4174,0.41544,0.41349,0.41056,0.40762,0.40469,0.40176,0.39785,0.39394,0.39003,0.38612,0.38221,0.37634,0.37146,0.36559,0.35973,0.35386,0.348,0.34213,0.33627,0.3304,0.32551,0.32258,0.31769,0.31281,0.30792,0.30303,0.29814,0.29423,0.28935,0.28446,0.27957,0.2737,0.26784,0.26393,0.261,0.26197,0.26882,0.28446,0.31183,0.34897,0.39589,0.44868,0.50147,0.55132,0.59629,0.6305,0.65591,0.67937,0.69795,0.71261,0.72434,0.73216,0.73607,0.73803,0.73803,0.73509,0.73021,0.72434,0.7175,0.70968,0.6999,0.69013,0.6784,0.66569,0.65103,0.63441,0.61681,0.59824,0.57771,0.55718,0.53959,0.52297,0.50635,0.48974,0.47507,0.46334,0.45259,0.44379,0.43695,0.43206,0.42815,0.42522,0.42229,0.42033,0.41838,0.41642,0.41447,0.41153,0.4086,0.40469,0.40078,0.39687,0.39198,0.3871,0.38221,0.3783,0.37439,0.3695,0.36364,0.35875,0.35288,0.348,0.34213,0.33724,0.33236,0.32747,0.32258,0.31769,0.31378,0.31085,0.30792,0.30401,0.3001,0.29619,0.29032,0.28446,0.27859,0.2737,0.2737,0.28055,0.29423,0.31672,0.35191,0.39785,0.45161,0.50733,0.56109,0.60899,0.65005,0.68328,0.7087,0.72727,0.74096,0.74878,0.75367,0.75562,0.7566,0.75464,0.75171,0.74585};
  //float arr[]={0.30303,0.28446,0.26979,0.25904,0.37341,0.55914,0.68622,0.73118};
  int len=sizeof(arr)/sizeof(arr[0]);

  /*for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)  //ppg data Array display
  {
    Serial.println(arr[i]);
    delay(50);
  }*/

  //SAMPLES=len;
  for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!
        vReal[i] = arr[SAMPLES];
        vImag[i] = 0;

        while(micros() < (microseconds + sampling_period_us)){
        }
    }

  /*FFT*/
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

  /*PRINT RESULTS*/
  //Serial.println(peak);     //Print out what frequency is the most dominant.

  for(int i=0; i<(SAMPLES/2); i++)
  {
       /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
       Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 2);
       Serial.print(" ");
       Serial.println(vReal[i], 1);  //View only this line in serial plotter to visualize the bins
       delay(50);
  }

  //delay(1000);  //Repeat the process every second OR:
  //while(1);       //Run code once
  Serial.println("Hello");
  //int freq_N=61;
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
  }

  /*double D[3][freq_N]; //1st row for frequencies, 2nd row for magnitude, 3rd row for phase
  for(int i=0;i<freq_N;i++)
  {
    D[0][i]=-(pi/2)+i*0.1;
    double *d=fourier_tran(arr,len,D[0][i]);
    D[1][i]=*(d+0);
    D[2][i]=*(d+1);
    Serial.println(i);
    delay(300);
  }*/

  int z_crsg=zero_cross(arr,len);
  //Serial.println(z_crsg);
  //delay(1000);
  float diff_arr[len-1];   //Differenced PPG signal
  for(int i=1;i<=len-1;i++)
  {
    diff_arr[i-1]=arr[i]-arr[i-1];
  }

  int rise=rise_count(arr,len);
  int fall=fall_count(arr,len);
  float fr=(float)fall/rise;      //fall/rise count ratio
  uint16_t m=max_amplitude(arr,len);   //maximum amplitude detection
  int sc[]={0,0,0};  //sensor connectivity vector
  if(fr>1.65 && fr<2.35)
  {
    sc[0]=1;
  }
  if(m<lm)
  {
    sc[1]=1;
  }
  if(m>zero_amp)
  {
    sc[2]=1;;
  }
  int sd=sig_saturation(arr,len);
  //Serial.println(sd);
  //Serial.print(sc[0]);
  //Serial.print(sc[1]);
  //Serial.print(sc[2]);

  if(sum(sc,3)>=2)
  {
    Serial.println("Sensor well connected");
  }
  else
  {
    Serial.println("Sensor not connected properly");
  }
  delay(500);
  if(base_drift(arr,len)>=0.4612 && base_drift(arr,len)<=0.4614)
  {
    Serial.println("Motion detected");
  }
  else
  {
    Serial.println("No motion artefacts problems");
  }
  delay(500);
  if(sd==0)
  {
    Serial.println("Saturated signal");
  }
  else
  {
    Serial.println("Non-saturated signal");
  }
  delay(500);

  int d_z_crsg=zero_cross(diff_arr,len-1);

}

//Sensor connectivity detection
int fall_count(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]>arr[i+1])
    {
      c=c+1;
    }
  }
  return c;
}
int rise_count(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]<arr[i+1])
    {
      c=c+1;
    }
  }
  return c;
}
int max_amplitude(float arr[],int l)
{
  float h=arr[0];
  for(int i=1;i<l;i=i+1)
  {
    if(arr[i]>h)
    {
      h=arr[i];
    }
  }
  if(h>lm)
  {
    return 0;
  }
  return 1;

}

//Noise segment detection
int zero_cross(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if((arr[i]==0.0) && arr[i+1]!=0.0)
    {
      c=c+1;
    }
  }
  return c;
}
int local_maxima(float arr[], int l)
{
  int frame_len=15;
  int a=0;
  int frames=l/frame_len;
  int maxima[frames];
  for(int k=0;k<frames;k++)
  {
    uint16_t h=0;
    for(int i=a;i<a+frame_len;i++)
    {
      if(arr[i]>h)
      {
        h=arr[i];
      }
    }
    maxima[k]=h;
    a=a+frame_len;
  }
  for(int i=0;i<frames-1;i++)
  {
    if(maxima[i]>lm && maxima[i+1]>lm)
    {
      return 1;
    }
    if(i<=frames-4)
    {
      if(maxima[i]<lm && maxima[i+1]<lm && maxima[i+2]<lm && maxima[i+3]<lm)
      {
        return 1;
      }
    }
    if(i<=frames-3)
    {
      if(maxima[i]<lm && maxima[i+2]<lm)
      {
        return 1;
      }
    }
  }
  return 0;
}

//Saturation detection
int sig_saturation(float arr[],int l)
{
  int c=0;
  //uint16_t lev=200000;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]<10 && arr[i+1]<10)
    {
      c++;
    }

    if(arr[i]>lm && arr[i+1]>lm)
    {
      c++;
    }
  }
  if(c>=20)
  {
    return 0;
  }
  return 1;
}

//motion detection module
double base_drift(float arr[],int l)
{
  int N=10; //N pt moving average
  int frame=l-N+1; //number of frames
  float s=0;
  double sum=0;
  for(int i=0;i<frame;i++)
  {
   s=0;
   for(int j=i;j<N+i;i++)
   {
      s=s+arr[j];
   }
   sum=sum+(s/N);
  }
  double avg=sum/frame;
  return avg;
}

int sum(int n[],int l)
{
  float s=0;
  for(int i=0;i<l;i++)
  {
    s=s+n[i];
  }
  return s;
}

float butterworth(float f, float fc,int n)
{
  float h;
  h=1/sqrt(1+pow((fc/f),2*n));
  return h;
}

double *fourier_tran(float arr[],int n,float omega)
{
   double Xr=0.00;
   double Xi=0.00;
   double DTFT[2];
   for(int j=0;j<n;j++)
   {
     Xr=Xr+arr[j]*cos(omega*j);
     Xi=Xi+arr[j]*sin(omega*j);
   }
   float X=sqrt(pow(Xr,2)+pow(Xi,2));  //Fourier transform magnitude
   float ph=-atan(Xi/Xr);  //Fourier transform phase

   DTFT[0]=X;
   DTFT[1]=ph;
   double *p=DTFT;
   Serial.println(*p);
   delay(100);
   Serial.println(*(p+1));
   delay(100);
   return p;
}
float *inv_fourier(float DTFT[][flen],int l,int flen,int n) //n is the length of the time array
{
  float arr[n];
  for(int i=0;i<n;i++)
  {
    float X=0.000;
    for(int j=0;j<l;j++)
    {
      X=X+DTFT[1][j]*cos(DTFT[2][j]+DTFT[0][j]*n);
    }
    arr[i]=1/(2*pi) * X;
  }
  float *p=arr;
  return p;
}
```
When I upload the code, Right after performing the FFT, the code does not display anything more, implying it ceases to execute and shows an error message - ```Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.
data section exceeds available space in board```

I cannot remove either section of the code, so what do I need to change with this?

title: Code exceeds Uno board memory

Answers: 2

body:
Probably you use too much SRAM memory:

`float arr[]` seems to take 4 bytes (for float) * 128 = 512 bytes.

Then you have `vReal` and `vImage which takes 4 (double, float/doubles are the same in Arduino) * 128 * 2 (vReal/vImage) = 1024 bytes.

    double vReal[SAMPLES];
    double vImag[SAMPLES];

This already is 1536 bytes. The Arduino only has 2048 bytes so high likely you exceed it (including arguments passed and other globals).

`arr` seems to be a readonly array, so check into the use of F/PROGMEM to store them in Flash instead of SRAM (see StarCat's comment). This might get you well under the 2 KB Arduino Uno memory. Other possibilities are using a Mega which has 8 KB or use external SRAM memory but this decreases performance and takes more programming effort.

See also my anser at https://arduino.stackexchange.com/questions/67306/optimizing-code-to-use-less-flash-memory-and-sram

body:
Consider using one of the Teensy family.  The latest [Teensy 4.0][1] has an onboard FPU and lots of other goodies, and runs at 600MHz. Why drive a VW when you can jump into a Ferrari for very little money?

I've been using the Teensy 3.2/3.5 modules for years, and have found them to be very stable and easy to use.

  [1]: https://www.pjrc.com/store/teensy40.html


body:
Hi i just wanna ask if its possible to do this on HC05. So i can send some keyboard function?

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

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

and if yes can you tell me how. Thanks

title: Use HC05 and FTDI as Slave to Connect to control PC using HC05

Answers: 0


body:
**UPDATE**
Clock speed code has been tweaked as per the suggestion from @timemage due to inability for Wire library to reduce to below 30304Hz. Unfortunately problems still persist:
Nothing printed out to serial and LED working only after disconnecting and reconnecting the circuit(stops updating after reseting arduino)..

****UPDATE****
Thanks for all replys. I have left the circuit the same and have used the following code where i have tried to reduce the i2c clock speed to 1khz but unfortunately having no luck.The EEPROM returns nothing and the pixel fails to work initially, only when i disconnect the circuit(this is simple because i am using a magnetic USB connector) it seems to work fine(until i restart the arduino).
If the consensus is that i may have more luck if I alter the library then i may look into it although it sounds a bit out of my depth...

    #include <Wire.h>

    #define disk1 0x50    //Address of eeprom chip
    unsigned int address0 = 0; //address to store the data

    #include <Adafruit_NeoPixel.h>

    //pixels pin
    #define sda_pin A4
    #define scl_pin A5

    Adafruit_NeoPixel strip(1, sda_pin, NEO_GRB + NEO_KHZ800);

    void setup() {

      Serial.begin(9600);

      Wire.begin();

      ////UPDATED CODE TO REDUCE I2C CLOCK SPEED TO 1KHZ////
      TWSR |= 0x03; // chose divide-by-64 prescaler
      TWBR  = 0x80; // closest to 1 kHz from below at 16 MHz with /64 prescaler.

      Serial.println(readEEPROM(disk1, address0), DEC);
      Wire.end();
      pinMode(scl_pin, INPUT);

      strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
      strip.show();            // Turn OFF all pixels ASAP
      strip.setBrightness(100); // Set BRIGHTNESS to about 1/5 (max = 255)

    }

    void loop() {
      rainbow(10);
    }

    void rainbow(int wait) {

      static unsigned long timer = 0;
      static long firstPixelHue = 0;

      if (millis() - timer > wait) {
        timer = millis();

        for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...

          int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());

          strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
        }
        strip.show(); // Update strip with new contents

        if (firstPixelHue < 5 * 65536) { //incrememnt
          firstPixelHue += 256;
        } else firstPixelHue = 0; //reset

      }
    }

    byte readEEPROM(int deviceaddress, unsigned int eeaddress )
    {
      byte rdata = 0xFF;

      const uint8_t i2c_base_address = 0x50;
      const uint8_t upper_three_eeprom_adress_bits = (eeaddress >> 8) & 0x7;
      const uint8_t i2c_address = i2c_base_address | upper_three_eeprom_adress_bits;
      Wire.beginTransmission(i2c_address);
      Wire.write(eeaddress & 0xFF); // address LSB

      Wire.endTransmission();

      Wire.requestFrom(deviceaddress, 1);

      if (Wire.available()) rdata = Wire.read();

      return rdata;
    }

**ORIGINAL POST:**

I have created a circuit which includes an AT24C16 EEPROM which I only need to read from and an addressable LED (WS2812 IC), which I will be talking to (Using an Arduino Nano).

My original intention was to attach the LED's DIN pin to either SCL or SDA. I thought that since I only needed to read the EEPROM once (and then control the LED), I would be able to share the connection. After creating the circuit, it proved an incorrect assumption.

I am limited to 4 (nets?) total due to the adapter I am using between the Arduino Nano and the rest of the circuit (repurposed magnetic 4 wire USB cable). **Could anyone propose a setup which would allow me with only these 4 connections, to read from the EEPROM and write to the LED?** As I mentioned, I only need a single read from the EEPROM to identify it and then I will only be writing to the pixel. Many thanks!

Attached is the schematic.

[![circuit][1]][1]

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

title: Reading from EEPROM and writing to addressable LED with limited connections

Answers: 5

body:
The AT24C16 is an I2C bus device but the WS2812 is not.  If you can tolerate spurious outputs on the WS2812 LEDs, you can read the AT24C16 using I2C by addressing the device properly.  The WS2812 will "listen" and may display things as that traffic is flowing past it.

When you are finished with the AT24C16 you will probably need to disable the I2C controller (assuming you are using that) and then hold the SCL line HIGH and then communicate with the WS2812 using the SDA line only.  The AT24C16 will ignore this non-I2C traffic because the SCL line is static a this point.

body:
This is just a hacky idea how you could solve this.

Decrease the I2C frequency below 10kHz or - as you only want to read the eeprom once at start - even down to 1kHz. This way the WS2812 will see a series of low pulses with a duration >50us which it should take as a reset signal. Practically, the WS2812 will ignore such a signal.

But there's a different problem: the EEPROM will write to the bus occasionally whenever it receives something that looks like its address. This in turn can
  - interfere with WS2812 communication.
  - damage the EEPROM's I2C interface if you control the WS2812 with push/pull signal (by setting gpios HIGH/LOW).

It would be safe to drive the WS2812s with an open drain signal (switching between LOW and INPUT), but that might require modifications to the WS2812 library.
In any case you should use the SDA line to control the WS2812 and there must be no signal on SCL while controlling the light (the EEPROM won't communicate if it receives no clock signal). The easiest might be to deactivate I2C entirely once you don't need it anymore and explicitly set the SCL pin to input mode. You then should be fine using SDA in normal push/pull mode and the library should work just as normal.

body:
This won't work with 24Cxx EEPROMS.
The I2C bus works this way:
* Master writes out an address.
* Slave takes over the SDA line and pulls it high or low to indicate an ACK or NAK.
* Master writes out a command for reading from an address.
* Again Slave takes over SDA and ACKs the command.
* Master is continuing to pulse SCL while Slave puts out data to SDA.
* After every byte (or word) Master has to take over SDA to confirm the data has been received.

So there is no way to tell the EEPROM to just vomit all its data to a bus without someone actively listening and ACK-ing. Which in turn changes the data on the bus.

---

It might work with 25Cxx EEPROMS.

You would need something different which has a much simpler communication scheme.
An 25Cxx which uses SPI for example, supports reading in a sequence, without constant ACK-ing. You will have to just initialize the read and keep clocking on SCK. No back and forth.
The data will be output to MISO in sequence.

But then still you will have to get the timings right. WS2812 are not very forgiving in that regard. That is why most people use libraries that have handcrafted Assembler code in them to get the timinigs right.

And I know what I am talking about as I wrote some myself (not suitable for anyone but me).
https://kwasi-ich.de/blog/2019/11/15/pwm_rider/

body:
setClock(1000) Problem
----------------------

This is *sort of* answer material, but it's meant to be supplementary to the other answers that more directly address your question and quite well, I think, though I'm unable to test right now.  So if you find this helpful, vote it up, but mark **one of the others** accepted if this tweak makes it work.

Specifically to address this content in your update:

> I have tried to reduce the I2C clock speed to 1khz but unfortunately
> having no luck.

And your line:

```c++
Wire.setClock(1000);
```

I was curious to know exactly how `setClock` maps its argument onto the values of  clock rate generating parameters in the hardware registers and whether or not 1 kHz might not be too slow for an AVR running at 16 MHz.  That is, perhaps the lower bound might be say 50 kHz, at which I'd've suggested a bit-banging I2C library in a comment to your question; however that's not the case.

In investigating this, I found that `setClock` **fails spectacularly** to do anything sensible in the AVR Arduino core library if given an argument of below `30304`.  Requested rates below this figure wind up yielding rates much higher than this owing to how they're calculating the clock rate with the TWI/I2C/"Wire" prescaler (`TWPS1` and `TWPS0` in `TWSR`) and the bit-rate register (`TWBR`).

I dug in to see what causes `setClock` to behave poorly for low rates, and there's not a lot to it.  The I2C/Wire [prescaler is set][1] to divide-by-1 and left that way.  `setClock` calls [`twi_setFrequency`][2], which calculates `TWBR` using this expression:
```c++
TWBR = ((F_CPU / frequency) - 16) / 2;
```

At 30304 Hz and above, this generates something within 1% of the desired frequency.  Along the x-axis is the requested rate.  The y-axis shows the effective rate.  Unsurprisingly, roughly linear.
[![30304 Hz and above][3]][3]

But below 30304 Hz, things go sideways. Values of 30303 or less when fed into that expression try to calculate a TWBR of 256 or greater.  But, it's an 8-bit register, so it rolls over. To prevent that a different prescaler would need to be selected.  But, it isn't and the following craziness results:
[![Below 30304 Hz][4]][4]

What `setClock(1000)` is *actually* doing in your code is setting a **rate of 125 kHz**; I have verified this on a scope.

Suggestion
----------

You can get an approximation of a 1 kHz clock rate by manually setting the hardware registers yourself, replacing your `setClock` line with the following:

```c++
TWSR |= 0x03; // chose divide-by-64 prescaler
TWBR  = 0x80; // closest to 1 kHz from below at 16 MHz with /64 prescaler.
```

**This should give you a TWI/I2C rate of about 975.61 Hz.**  In the datasheet for the ATMega328P you'll see this is selecting the divide-by-64 prescaler, and taking 128 ticks of that. You can find the equation in the datasheet, that if you fill these values and your UNO clock rate into, gives the expression 16e6 / (16 + 2 * 0x80 * 64), which gives you the 975.61 figure above.  I've verified that it is approximately that on a scope.

**Give that a try.  See if when you do, whether or not one of the answers doesn't work for you.**  I expect one will.

  [1]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/libraries/Wire/src/utility/twi.c#L91
  [2]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/libraries/Wire/src/utility/twi.c#L139
  [3]: https://i.stack.imgur.com/cBCvS.png
  [4]: https://i.stack.imgur.com/12Sr2.png

body:
My working details, per-request
===============================

Setup
-----
So, the setup is the same as you what you have in its essentials:

* The code is your code with the near-1 kHz tweak.  That said, I believe I also tested it at the default rate and that worked as well.  In any case, the images that show the LED changing were taken while that 1 kHz adjustment was made.

* The UNO and Nano are functionally identical for this.  They use different serial transceivers which has nothing to do with anything.   The Nano will typically have a lower "5V" than the UNO when USB powered owing to the Nano using a diode where the UNO has a FET.  Which is unlikely to matter either.  They're otherwise the same device so far as the setup goes.

* The [24LC02B][1] uses the same pinout and I2C address and command-sequences as your [AT24C16][2].  It is a smaller memory, not that it makes a difference; we're reading from address 0.  I did not find I necessary to add external pull-up resistors and it worked, so it seemed unnecessary to add them to demonstrate that it can work since adding them should only improve it's chances for working correctly.

* The LEDs are the [Adafruit ADA1643 12 Neopixel Ring][3]. We're both using the first LED of a string, doesn't really matter how long the are.   We're only lighting one "pixel" so I just powered it from USB.  Have no idea what you're doing there.  But for one LED lit, I doubt a difference there would matter much.

* You'll see a resistor connecting SDA at the EEPROM to IN on the addressable LED(s).  I put that there in case by some chance the EEPROM could drive SDA low while the addressable LED code was driving the LED data line high. while.  I doubt that can happen, but it was a small thing to do.  For what it's worth, I did run it briefly without it in series, and it also worked fine that way as well.  I'm only telling you this so you have all the information and not because *I* think it matters; I don't.

Running
-------
It prints out 72.  This *is* the first value in my EEPROM. The 'H' of "Hello world" basically.  And then it goes on to cycle the first addressable LED of the set through all of the colors.

Configuration Pictures
----------------------

[![Overall setup][4]][4]
[![Top-down view of breadboard][5]][5]
[![Breadboard close-ups][6]][6]
[![Colors][7]][7]

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/24AA02-24LC02B-24FC02-Data-Sheet-20001709L.pdf
  [2]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8719-SEEPROM-AT24C16C-Datasheet.pdf
  [3]: https://www.adafruit.com/product/1643
  [4]: https://i.stack.imgur.com/PQ2yA.jpg
  [5]: https://i.stack.imgur.com/zzCSp.jpg
  [6]: https://i.stack.imgur.com/lJ0U8.jpg
  [7]: https://i.stack.imgur.com/QK5di.jpg


body:
I am trying to figure out how `ArduinoJson` capacity can be calculated, therefore I came by the Assistant web application developed by the developer of the library https://arduinojson.org/v6/assistant/

Here what I do not understand is, why when I use either of the following two JSON strings, the helper shows me the same capacity? I would expect that the longer JSON values will result in a bigger capacity, but this does not seem to be the case.

    {
      "wifi": {
        "ssid": "S",
        "password": "P",
        "hostname": "H"
      },
      "administration": {
        "username": "U",
        "password": "P"
      }
    }

    {
      "wifi": {
        "ssid": "SSSSSSSSSSSSSSSSSSSSSSSSSSS",
        "password": "PPPPPPPPPPPPPPPPPPPPPPPPPP",
        "hostname": "HHHHHHHHHHHHHHHHHHHHHHHHHHHH"
      },
      "administration": {
        "username": "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
        "password": "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"
      }
    }

I am trying to calculate the capacity using the assistant using the following configuration:

*ESP8266 / **Deserialize** / char**

Could you anyone explain this to me? Apparently I understand the "reason" behind the capacity wrong?

title: Understanding ArduinoJson capacity calculation assistant

Answers: 2

body:
If you look at the details of the numbers reported, you should see:

    Data structures     112
    Strings             0
    Total (minimum)     112
    Total (recommended) 128

As you see, there are exactly zero bytes allocated for the strings. This
means that the library does not copy the strings, and instead references
them from the character array you provide as an input.

If you instead configure the library for `Stream` input, it will have to
store the strings, and the capacity is then very different for these two
documents.

body:
I found what the real problem is. In the assistant tool, when choosing `const char *` as the input type, it shows that the size of the string is 0, which is **wrong** according to the documentation of the library.

https://arduinojson.org/v6/api/json/deserializejson/

> // writable input => zero-copy
> DeserializationError deserializeJson(JsonDocument& doc, char* input);
> // read-only input => duplication
> DeserializationError deserializeJson(JsonDocument& doc, const char* input);

The assistant, if I see correctly, does **not** distinguish between these two cases, and thus gives the wrong capacity for this `const` case.

Accordingly, **in `const char *` it is not enough to only take the size of the structure, but also we need to consider the data stored in it.**

According to [the documentation][1], the reason why `const char *` cannot be a zero-copy is:

> 3.9.2 Duplication is required
As we saw in the previous section, in the zero-copy mode, ArduinoJson stores pointers
pointing inside the input buffer. We saw that it has to replace some characters of the
input with null-terminators.
With a read-only input, ArduinoJson cannot do that anymore, so it needs to make copies
of "hip" and "hop". Where do you think the copies would go? In the JsonDocument, of
course!

### UPDATE

After reporting this bug (see the link below), it has been quickly fixed!

https://github.com/bblanchon/ArduinoJson/issues/1488

  [1]: https://arduinojson.org/v6/doc/deserialization/


body:
I've been working on a cipher based project, and I wanted to prep the encrypted string for use with the RF24 library. Since the payload size for the RF24 module is 32 bytes, I wanted to stick with that size permanently. The key number (against which the encryption keys are stored) has to be embedded at the end of the char array, and I was converting it to a char to embed. To make the message up to 31 bytes if it was smaller than 31 bytes, I am padding with zeroes.

The cipher functions themselves (namely `loadInput()`, `cipherText()` and `originalText()`), work perfectly; I have tested these by themselves numerous times.

However, the other two functions I wrote for padding and de-padding are behaving erratically.

My code:

```c++
const String keys[] = {
"TTZUZRZJHP",
"SUENIFKGAT",
"CEXGWKMCVQ",
"SIACAKRFM",
"CSMKSWSNLH",
"IPIJWROJBB",
"SZSGAMYJGJ",
"BIHLBNUIJS",
"UTFGSQAISS",
"SSPXJXURJV",
"XPDRYPOFAC",
"DROIFANPZE",
"DKTZXUQLAM",
"UDHAWMAJTG",
"HKTQMEPWXS",
"IRUQAHZSBP",
"ZHZAAGTMTN",
"EHORTISSLQ",
"NYZZQALWTP",
"PEEGDJLQLQ",
"UNQGHTXFSG",
"NOBSTVFLAX",
"GQJYEVUNCX",
"UTJDNOCLSP",
"XQNGBDOBEN",
"FURHLIZSIN",
"AAAPEIGRHI",
"QWQFCCVFPV",
"KZEFJHUJWB",
"NDJNLHURJO"
};

char readyToSend[32]; //global array, which is to be transmitted via RF24
char recieved[32]; // global array, which is to be recieved via RF24
int keyRecieved; //global key number, which is to be embedded as the last char recieved[]

String loadInput() { //this functions takes the input string and checks it's validity
  bool isValid = true;
  String(inputStr);
  do {
    Serial.println("Enter valid input. Only enter ALPHABETIC characters. ONLY 31 CHARS MAX.");
    Serial.println("Whitespaces are valid but commas and fullstops are not");
    while (Serial.available () == 0) {}
    inputStr = Serial.readString();
    int inputLength = inputStr.length();

    for (int i=0; i<inputLength; i++) {
      if (inputLength>31) {
        Serial.println("Input longer than 31 chars.");
        isValid = false;
        break;
      } else if (inputStr[i] > 95 && inputStr[i] < 123) {
        inputStr[i] -= 32;
      } else if (isWhitespace(inputStr[i])) {
      } else if (!isAlpha(inputStr[i])) {
        isValid = false;
        break;
      }
    }
  } while (isValid == true);

  inputStr.remove((inputStr.length()-2), 2);
  return inputStr;
}

String cipherText(String str,const String key) { //this function encrypts the message, and returns the encrypted version
  String cipher_text;
  for (int i=0; i<str.length(); i++) {
    if (isWhitespace(str[i])) {
      cipher_text += ' ';
    } else {
      char x = (str[i] + key[i%key.length()]) &;
      x += 'A';
      cipher_text += x;
    }
  }
  Serial.println(cipher_text);
  return cipher_text;
}

String originalText( String cipher_text,const String key) { //this function decrypts the message, and returns the decrypted version
  String orig_text;

  for (int i=0 ; i<cipher_text.length(); i++) {
    if (isWhitespace(cipher_text[i])) {
      orig_text += ' ';
    } else {
      // converting in range 0-25
      char x = (cipher_text[i] - key[i%key.length()] + 26) &;
      // convert into alphabets(ASCII)
      x += 'A';
      orig_text += x;
    }
  }
  return orig_text;
}

void prepForTransmit(String input, int keyNumber) { //this function makes pads the string upto 31 with '0', then embeds key
  input.toCharArray(readyToSend, 32);
  int zeroesStart = input.length();

  for (int i=zeroesStart; i<32; i++) {
    readyToSend[i] = '0';
  }

  char keyNumberAsChar = (char)(keyNumber + 65);
  readyToSend[31] = keyNumberAsChar;
  return;
}

String PrepForDecode() { //this function makes exctracts key, then removes padding
  keyRecieved = (recieved[31] - 65);
  String toEdit = String(recieved);
  toEdit.remove(31, 1);

  if (toEdit.indexOf('0') != -1) {
    toEdit.remove(toEdit.indexOf('0'), (31-toEdit.indexOf('0')));
  } else {
  }
  return toEdit;
}

void setup() { // TEST CODE
  Serial.begin(9600);
  randomSeed(analogRead(A0)); //SEED RANDOM FUNCTION
  String(text) = loadInput(); //GET INPUT
  Serial.println(text); //PRINT INPUT      <--------------------------------------
  int keynumber = random(25); //              |
  String encrypted_message = cipherText( text, keys[keynumber]);  //ENCRYPT THIs _|
  Serial.println("Using key number ");
  Serial.println(keynumber);

  prepForTransmit(encrypted_message, keynumber); // PADDING AND ADD KEYNUMBER
  Serial.println("Message to trasmit through radio is: ");
  Serial.println(readyToSend);  // PRINT PREPPED CHAR ARRAY
  for (int i=0; i<32; i++) {
    recieved[i] = readyToSend[i]; // COPY PREPPED ARRAY TO EMULATE RECEPTION FROM RADIO
  }
  String toDecode = PrepForDecode(); // PREP RECIEVED STRING FOR DECODING (REMOVE PADDING, EXTRACT KEY)

  Serial.println(originalText( toDecode , keys[keyRecieved])); // PRINT DECODED STRING
}

void loop() { //main program
```

My serial output:
```22:18:59.527 -> Enter valid input. Only enter ALPHABETIC characters. ONLY 31 CHARS MAX.
22:18:59.596 -> Whitespaces are valid but commas and fullstops are not
22:19:08.255 -> THIS PROJECT IS A MESS
22:19:08.290 -> LPIU ZITVWKT IC F EMSU
22:19:08.325 -> Using key number
22:19:08.325 -> 3
22:19:08.325 -> Message to trasmit through radio is:
22:19:08.393 -> LPIU ZITVWKT IC F EMSU000000000D⸮!
22:19:08.428 -> THIS PROJECT IS A MESSLFRP HATTWAC WK F ECBP>8BJHJ@9ER:3
```

"LPIU ZITVWKT IC F EMSU000000000D⸮!" is very unexpected, since there should only be 32 chars, and here there are 34.

Furthermore, the behavior here: "THIS PROJECT IS A MESSLFRP HATTWAC WK F ECBP>8BJHJ@9ER:3" is something I absolutely cannot understand.

I am baffled, and I would really appreciate help. I apologize in advance if the error is something small or stupid, but I *cannot* understand what's going on here.

title: Erratic behavior in String based functions

Answers: 0


body:
I am at my wit's end with these Nrf24l01s. A bit of history: I have ordered about 25 of these, tried the adapter board, read every article, tried every sketch (including Robin's tutorial), powered the modules with a separate power supply.

Has anyone else had these issues? Is there anything anyone has discovered on getting these to work? I am 12 years old and am trying to use these for a science project. Any help is greatly appreciated!!

Tnx,
Ricky

**edit:**
I went back to just the simplest "hello world" sketch and I can't even get this to work: nothing received in serial monitor (I did notice the Tx LED is lit in the receiver, is this correct?) Sorry if I posted this wrong.

```c++
//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//create an RF24 object
RF24 radio(9, 8);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";

void setup()
{
  radio.begin();

  //set the address
  radio.openWritingPipe(address);

  //Set module as transmitter
  radio.stopListening();
}

void loop()
{
  //Send message to receiver
  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));

  delay(1000);
}
```

Receiver:

```c++
//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//create an RF24 object
RF24 radio(9, 8);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";

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

  radio.begin();

  //set the address
  radio.openReadingPipe(0, address);

  //Set module as receiver
  radio.startListening();
}

void loop()
{
  //Read the data if available in buffer
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.println(text);
  }
}
```

title: Getting Nrf24l01 modules to work!

Answers: 0


body:
I'm working on alarm clock project using Arduino Nano (v 3.0, clone) and RTC module ZS-042 (containing DS3231 and EEPROM AT24C32).

The intention is to load the hours and minutes from EEPROM on start-up, use current date (to avoid zero-date problems) and compose DateTime object in order to utilize the TimeSpan object, making time calculations easier than using plain integer math. The issue is, the value in DateTime object seems not constructed correctly, although all the components used for its construction seem OK.

With the following code
```
/* Hardware definitions */
//RTC using I2C, pins 4,5
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;

#include <extEEPROM.h>
extEEPROM e2p(kbits_32, 1, 32, 0x57);

DateTime  alarm1Time;

void setup(){
  Wire.begin();
  rtc.begin();
  Serial.begin(115200);
  uint8_t e2pStatus = e2p.begin(extEEPROM::twiClock400kHz);      //go fast!
  DateTime t = rtc.now(); //get current time from RTC
  Serial.print("t.year: ");  Serial.print(t.year());
  Serial.print(" t.month: ");  Serial.print(t.month());
  Serial.print(" t.day: ");  Serial.println(t.day());
  alarm1Time = (t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
  Serial.print("E2P : ");
  Serial.print(e2p.read(1));
  Serial.print(":");
  Serial.println(e2p.read(2));
  char buf1[] = "YYMMDD-hh:mm:ss";
  Serial.println(alarm1Time.toString(buf1));
}
```
I get on the serial monitor the following:
```
t.year: 2021 t.month: 1 t.day: 31
E2P : 7:15
060206-06:28:16
```
The date components (year, month, date) correspond to current date. As the bytes on address 1 and 2 in EEPROM read 7 and 15, I'd expect the Alarm1Time be 2021-01-31, 07:15, which isn't.
The output is constant, whatever the current date and the EEPROM stored time. Later in my code the alarm1Time parses into 6 hours and 28 minutes, in accordance with last line of the serial monitor output.

What could be (or better - where I'm) wrong? Thanks.

Libraries used:

**RTClib** (https://github.com/adafruit/RTClib)

**extEEPROM** (https://github.com/JChristensen/extEEPROM/blob/master/extEEPROM.h)

title: Incorrect DateTime value constructed

Answers: 1

body:
Here:

```c++
alarm1Time = (t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
```

you are repeatedly using the comma operator, which essentially means
“discard all the values but the last one”. If you want to invoke the
`DateTime` constructor that takes these arguments, you should call it
explicitly:

```c++
alarm1Time = DateTime(t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
```

or, better yet, you can declare and initialize `alarm1Time` at the same
time:

```c++
DateTime alarm1Time(t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
```


body:
```none
    Arduino: 1.8.13 (Linux), Board: "Arduino Uno"

Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
```

 - I selected the right board (Arduino Uno)
 - I selected the right port
 - I selected "USBasp" as programmer
 - I reset the board multiple times
 - I have uploaded to the same port multiple times before without getting an Error
 - I disconnected the USB-cable multiple times and used a different one
 - I don't get the Error Message on a different board (also Arduino Uno)
 - When I'm trying to upload with the serial Monitor open i see an orange lamp (RX lamp) blinking in the same speed the Errors are given
 - When I'm trying to "Burn Bootloader" I get following Error:

```none
Arduino: 1.8.13 (Linux), Board: "Arduino Uno"

avrdude: error: could not find USB device with vid=0x16c0 pid=0x5dc vendor='www.fischl.de' product='USBasp'
Error while burning bootloader.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
```

title: I'm trying to upload a sketch to my arduino uno, but I get the Error-Message "avrdude: stk500_recv(): programmer is not responding"

Answers: 1

body: The problem was an Bluetooth extension I connected to the board. I removed it, uploaded the program, reconnected it, and that worked!


body:
I am trying to convert a floating point number to an integer, but it seems like the conversion is not working properly.

I am using the math library to calculate the power of 10 based on the number of varargs, where the first argument is the number of arguments followed by the varargs.

```
int charsToIntValue(int argc, ...) {
  int multiplier = (int) pow(10, argc - 1);
  va_list argp;
  va_start(argp, argc);
  Serial.println(multiplier);
  ...
  va_end(argp);
}
```
For some reason, `multiplier` is always stored as 1 less than the actual result.
e.g. If `charsToIntValue(4, 1, 2, 3, 4)` is executed, the multiplier is stored as 999 rather than 1000. However, when it is printed as a float, it does show 1000.00. And whenever I change it to a constant (`(int) pow(10, 3)`) it works fine, returning 1000.

I've tired storing the value of argc into a local variable but that didn't seem to change anything.

Full project is here for context: https://github.com/Pyrodron/charger-destination-board

File in question is charger-destination-board.ino; lines 32 to 51

title: Float to int conversion not working right in method using varargs

Answers: 2

body:
With some inspiration from timemage's comment, I decided in the long run to implement my own power function that takes two `int` arguments and returns an `int`. Rather than use the `pow` function in the `<math.h>` library which returns a `double` when I only need an `int`.
```
int power(int x, int y) {
  return y == 0 ? 1 : x * power(x, y - 1);
}
```
Now the program works as intended!

body:
As explained by @chrisl in a comment, the issue is that `pow()` does not
return an exact result, only an approximation. It works fine with
compile-time constants because in this case it is evaluated at compile
time, by the compiler, on you PC.

Simple solution: replace the cast to int with `round()`:

```c++
int multiplier = round(pow(10, argc - 1));
```

This works, but is awfully inefficient, as `pow()` involves the
computation of both an exponential and a logarithm, both very expensive
on an AVR-based Arduino. The int-only function in your own answer is
certainly better. However, it is generally advised to avoid recursion on
low-memory Arduinos like the Uno. Prefer an iterative algorithm if you
can.

Also, the complexity of you int-only function is O(y). There is a
well-known algorithm for integer powers that goes like O(log(y)):

```c++
int power(int x, int y)
{
    int z = 1;  // Invariant: result = x^y * z
    while (y) {
        if (y & 1) z *= x;
        y >>= 1;
        x *= x;
    }
    return z;
}
```

Maybe I am nitpicking, as your `y` cannot go beyond 5 without
overflowing the result...


body:
Hello:) I'm working on a lil project with some NeoPixels being controlled by an IR remote, and with there being multiple strips, I felt it would be best to first select the desired strip, and then the colour. The code is getting there, albiet with a few bugs. I've set the serial monitor up for debugging.

When a strip is selected (I call them 'shift buttons', like on a keyboard), the program and serial monitor detect it flawlessly, every time. However, when I press ONLY a colour button to test the input, a seemingly random, HEX code pops up on the serial monitor which changes with each press. This seems to cause the whole code not to function past selecting a strip.

Would anyone be able to give me a hand as to why this incorrect code might be popping up please? I've tested the function of the buttons on a IR remote testing script and the buttons correlate to the HEX displayed everytime so I know the physical route to the Arduino isn't flawed

TL:DR:

One function with IR information works flawlessly, other function using the same info returns random(?) HEX codes

Below is the code:

    #include <IRremote.h> //include IR library
    #include <Arduino.h>
    #include <FastLED.h> //include LED library
    #define NUM_LEDS1 18 //say how many leds is in row 1
    #define NUM_LEDS2 17 //say how many leds is in row 2
    #define NUM_LEDS3 20 //say how many leds is in row 3
    const int RECV_PIN = 8; //say what pin IR sensor is plugged into
    const int LEDPIN = 13;//say what pin blue STATUS led is plugged into

    IRrecv irrecv(RECV_PIN);
    decode_results results;
    unsigned long key_value = 0;
    int shiftbutton = 0;

    CRGB leds1[NUM_LEDS1]; //link leds1 with how many leds are in it
    CRGB leds2[NUM_LEDS2]; //link leds2 with how many leds are in it
    CRGB leds3[NUM_LEDS3]; //link leds3 with how many leds are in it
    size_t NumLeds[3] = { NUM_LEDS1, NUM_LEDS2, NUM_LEDS3 };
    CRGB* strips[3] = { leds1, leds2, leds3 };

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

      irrecv.enableIRIn(); //Enables IR
      irrecv.blink13(true); //Flashes onboard LED when IR input detected
      pinMode(LEDPIN, OUTPUT); //set signal led as an ourput
      FastLED.addLeds<NEOPIXEL, 5>(leds1, NUM_LEDS1); //setup for row 1
      FastLED.addLeds<NEOPIXEL, 3>(leds2, NUM_LEDS2); //setup for row 2
      FastLED.addLeds<NEOPIXEL, 6>(leds3, NUM_LEDS3); //setup for row 3
    }

    void loop()
    {
      readIR();
      ShiftButtons();
      LEDStrip();
    }

    void readIR()
    {
      if (irrecv.decode(&results))
      {
        // debug
        Serial.println("processing received IR");
        // if not repeat key
        if (results.value != 0XFFFFFFFF)
        {
          key_value = results.value;

          // debug
          Serial.print("using new value ");
          Serial.println(key_value, HEX);
        }
        else
        {
          // nothing to do
          // key_value still contains the result of the previous read

          // debug
          Serial.print("using old value ");
          Serial.println(key_value, HEX);
        }
        irrecv.resume();
      }
    }

    void ShiftButtons()
    {
      switch (key_value)
      {
        case 0xFF30CF:
          shiftbutton = 1;
          break;
        case 0xFFB04F:
          shiftbutton = 2;
          break;
        case 0xFF708F:
          shiftbutton = 3;
          break;
      }

      // debug
      Serial.print("shiftbutton set to ");
      Serial.println(shiftbutton);
    }

    void setStrip (size_t index, CRGB color)
    {
      fill_solid(strips[index], NumLeds[index], color);
      FastLED.show();
    }

    void LEDStrip()
    {
      if (shiftbutton == 0) return; // no strip selected

      // debug
      Serial.print("LEDStrip: using key value ");
      Serial.println(key_value, HEX);

      CRGB color = CRGB::Black;
      switch (key_value)
      {
        case 0xFF1AE5:
          color = CRGB::Red;
          // debug
          Serial.println("color set to red");
          break;
        case 0xFF9A65:
          color = CRGB::Green;
          // debug
          Serial.println("color set to green");
          break;
        case 0xFFA25D:
          color = CRGB::Blue;
          // debug
          Serial.println("color set to blue");
          break;
      }

      setStrip(shiftbutton - 1, color);
      shiftbutton = 0;  // reset the flag
    }

  Hopefully I’ve attached that code right!
Thanks

title: Unexpected and incorrect HEX codes coming from IR remote, but only in second function..?

Answers: 0


body:
My project is of non contact temperature sensor.I am using RG1602A lcd display and mlx90164 temperature sensor.
But the problem is, there's no sdl , sca pins in my lcd display.

Is there any way, to overcome?

title: Cant find Sdl and Sca pins in lcd display

Answers: 1

body:
You will need an [I2C adapter board][1] like this to interface your LCD 1602 via I2C.

  [1]: https://www.aliexpress.com/item/1005002070253348.html


body:
I have a pulse going into A0 on a Nano, and want to detect the peak voltage.  With low-pass filtering to slow down the input pulse I'm still reading marginally too slow.

The code overall inhibits a laser except for 50ms after a button is pressed.  During that 50ms I read A0 to look for the peak voltage/laser pulse energy.  The pulse is negative, several volts, and is AC-coupled into A0, pulled up to a 5V baseline.

The monitoring loop is simple:

```c++
while (millis() < (PulseStart + LaserPulseWidth)) { // monitor ADC (PbSe amplified photodiode with negative output, AC coupled and pulled up
  if (V_in <= V_old) {
    V_old = V_in;
  } // this will report the minimum voltage seen on the monitor pin.  Should be near enough proportional to the pulse energy.
  V_in = analogRead(MonitorPin);
}
```
Outside the monitoring loop, but in the main loop, I toggle various status LEDs etc.  The resulting laser pulse energy is sent using `softwareSerial` to (a Raspberry Pi in) the box with the trigger button, about 12m away. `softwareSerial` requires interrupts, but anyway so does `millis()`

[![Oscilloscope image of input pulse][1]][1]

Channel 1 (yellow) is measured at A0.  Channel 2 is the unfiltered output from the PbSe amplified IR photodiode, and is used to trigger the scope.  Note the timebase is 100us, close to the nominal readout time of A0; I thought this would effectively average over approximately 1 division, which might be OK, but taking some rough calibration data suggests otherwise.

Here's my circuit:
[![partial circuit/block diagram][2]][2]

A simplified version of the whole code follows. I've removed some status outputs (LEDs, beeps, USB serial transmssion) from the main loop and the code to set them up; the ADC read-in loop is unmodified from my running code.

```c++
#include <SoftwareSerial.h>

int MonitorPin = A0;
int FireButton;
int stopbutton;
int lastFireButton = LOW;
int V_in;
int V_old;
char message[8];
int V_base;
int LaserPulseWidth = 50; //in ms.  50 ms should be right for 20 Hz laser

SoftwareSerial mySerial = SoftwareSerial(2, 3); // RX, TX

void setup() {
  pinMode(pin7, INPUT_PULLUP);  // fire laser
  pinMode(pin8, INPUT_PULLUP);  // disable
  stopbutton = digitalRead(8);
  FireButton = digitalRead(7);
  pinMode(LaserPin, OUTPUT); // Laser trigger pin
  Serial.begin(9600); // for comms to a host PC (includes debug info)
  mySerial.begin(9600); // for comms to RPi
  mySerial.println("Second serial port");
  interrupts();
}

void loop() {
  stopbutton = digitalRead(8);
  FireButton = digitalRead(7);
  while (stopbutton == HIGH) { // not actually used, but implemented in case we want to suppress firing (pin internally pulled up so just ground to suppress)
    lastFireButton = FireButton;
    stopbutton = digitalRead(8);
    FireButton = digitalRead(7);
    V_old = 1024; // initialise to max so anything we read is less

    if (FireButton != lastFireButton && FireButton == LOW) { // detect negative edge
      digitalWrite(13, true); // flash the onboard status LED on
      V_old = 1024;
      for (int i = 0; i < 10; i++) {
        V_in += analogRead(MonitorPin); // read ADC before firing to provide a baseline
      }
      V_base = V_in / 10;
      digitalWrite(LaserPin, true); // laser trigger on
      PulseStart = millis();
      while (millis() < (PulseStart + LaserPulseWidth)) { //monitor ADC (PbSe amplified photodiode with negative output, AC coupled and pulled up
        if (V_in <= V_old) {
          V_old = V_in;
        } // this will report the minimum voltage seen on the monitor pin.  Should be near enough proportional to the pulse energy.
        V_in = analogRead(MonitorPin);
      }
      digitalWrite(LaserPin, false); // laser trigger on

      int V_peak = V_base - V_old;
      sprintf(message, "ADC=%d", V_peak);
      mySerial.println(message);
    }
  }
}
```

  [1]: https://i.stack.imgur.com/1oLBi.png
  [2]: https://i.stack.imgur.com/ugyCy.png

title: Am I maximising my A0 readout rate with this peak-detection code?

Answers: 0