message:
Custom 328P-AU board not responding via ICSP

I created a custom PCB based on a 328P. The design is mainly based on the Arduino Nano schematic (3.0). The boards have arrived some days ago, and I can't get avrdude to recognize them via USBASP (or any other mean for that matter). When trying to program the board is powered via the ICSP connector. What I have tried so far:
- only soldering the essential components: CAPs for 5V rail
- soldering the Oscillator or leaving it off
- on one board I even cut all lines except 5V, GND, RST and SPI.

Still the 328p won't respond, all I get is :

    #avrdude -u -c usbasp -P COM1 -b 57600 -B 0.5 -p m8

     WARNING: Unable to detect MCU
     avrdude.exe: set SCK frequency to 1500000 Hz
     avrdude.exe: error: program enable: target doesn't answer. 1
     avrdude.exe: initialization failed, rc=-1
             Double check connections and try again, or use -F to override
             this check.
     avrdude.exe done.  Thank you.

I will attach my schematics and my board design, I know it is not the cleanest for now... It is my first one and I am currently trying to clean it up/make it better. I also added 1k resistors in line to RX and TX, but they are not present in the board design for now.

I am thankful for any help and/or advice

I can provide the board design if needed:)

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

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

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

  [1]: https://i.stack.imgur.com/jYDHg.png
  [2]: https://i.stack.imgur.com/k8ant.png
  [3]: https://i.stack.imgur.com/zGEuM.png

body:
So you had:

> SCK frequency to 1500000

And I suggested lowering to the point where you:

> set it to 8k solved it:)

Good deal.  The thing that you were likely running afoul of is the maximum ISP clock rate, which according to the [datasheet for the ATMega328P][1] (or practically any other AVR for that matter) is determined by some rules:

> Low:> 2 CPU clock cycles for fck < 12MHz, 3 CPU clock cycles for fck ≥ 12MHz
> High:> 2 CPU clock cycles for fck < 12MHz, 3 CPU clock cycles for fck ≥ 12MHz

So your maximum ISP clock rate is dependent on the chip's clock rate.  And is either at most a quarter of a sixth of that, depending on whether or not the chip operating below or above 12MHz.

Most ordering codes of AVRs of the type that do this kind of ISP programming ship from the factory at on the internal 8 MHz oscillator with the divide-by-8 fuse enabled; So they're at 1 MHz with a maximum ISP clock rate of 250 kHz.  Had you been working with a the typical Arduino arrangement when it had already been set up for and running with a 16 MHz clock, the 1.5 MHz ISP clock rate *might* have worked.  I'd have still slowed it down, since it will only be more likely to work when doing that.

Most programmers default to a low clock rate, closer to your 8k figure.  Usually, if people have a problem with hitting the maximum ISP clock rate, it's because they have a very low system clock, either using a watch crystal or fusing for the internal 128 kHz, or either in combination with the divide-by-8-fuse.  Often when trying to go too-fast, what's holding them up is crappy wiring.

When you're programming there's a limit to how useful it is to crank the clock rate up anyway, because eventually there's going to be a lot of hurry-up-and-wait while the chip flashes sectors and the timing of that isn't dependent on the clock rate.

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf


sender: user

message:
avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied Upload error:

I am using ``arduino-ide``2.0.0-beta.7(CLI Version:0.18.3 alpha) on Manjaro Linux and I get this error when uploading sketch to my Arduino Micro:
>avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
Upload error: Error: 2 UNKNOWN: uploading error: uploading error: exit status 1

I checked other questions and tried:
```
sudo groupadd dialout
sudo gpasswd -a $USER dialout
sudo chmod a+rw /dev/ttyACM0
sudo usermod -a -G dialout $USER
sudo chown root:dialout -R /dev/
ls -l /dev/ttyACM0 #can see the root:dialout
```
But when I logout and get again after ``ls -l /dev/ttyACM0``:
>crw-rw-rw- 1 root uucp 166, 0  6月 13 17:06 /dev/ttyACM0

So I cannot upload the sketch. Note: I can upload sketches using ``sudo arduino-ide --no-sandbox ``, but I want to upload them from the ``user`` account.

What else can I try?

Thank you.

sender: assistant

body:
Instead of:
```
sudo usermod -a -G dialout $USER
```
I had to run:

```
sudo usermod -a -G uucp $USER
```

Thanks to @Juraj I realized that. Thanks @Juraj.


message:
invalid conversion from 'char' to 'const char*' [-fpermissive] on a string

I am compiling some code I didn't write, and it bombs out with the error message

    invalid conversion from 'char' to 'const char*' [-fpermissive]

on the line

    if (loginPassword == '\0') loginPassword = "";

I don't see why that line is any different than the previous strings, and the answers I can find all have to do with variables that start as char.

What is wrong with this code, and how do I fix it?

```cpp
    void saveUnit(String tempUnit, String supportMode, String loginPassword, String minTemp, String maxTemp, String tempStep) {
      const size_t capacity = JSON_OBJECT_SIZE(6) + 200;
      DynamicJsonDocument doc(capacity);

      // if temp unit is empty, we use default celcius
      if (tempUnit == '\0') tempUnit = "cel";
      doc["unit_tempUnit"]   = tempUnit;

      // if minTemp is empty, we use default 16
      if (minTemp == '\0') minTemp = 16;
      doc["min_temp"]   = minTemp;

      // if maxTemp is empty, we use default 31
      if (maxTemp == '\0') maxTemp = 31;
      doc["max_temp"]   = maxTemp;

      // if tempStep is empty, we use default 1
      if (tempStep == '\0') tempStep = 1;
      doc["temp_step"] = tempStep;

      // if support mode is empty, we use default all mode
      if (supportMode == '\0') supportMode = "all";
      doc["support_mode"]   = supportMode;

      // if login password is empty, we use empty
      if (loginPassword == '\0') loginPassword = "";
      doc["login_password"]   = loginPassword;

      File configFile = SPIFFS.open(unit_conf, "w");
      if (!configFile) {
        // Serial.println(F("Failed to open config file for writing"));
      }

      serializeJson(doc, Serial);
      serializeJson(doc, configFile);

      configFile.close();
    }
```

body:
Regardless of the findings below, you don't really want to compare a string object with a null-character this way (more on that below).  Really something like:  `if (someArduinoStringObj.isEmpty()) {` is a better idea, no matter what core you're on.

So for anyone that has landed here with this problem with code that had worked and no longer works, the answer is basically don't do that; probably shouldn't have been doing that in the first place.

If you're curious on what I found, there's material on that below.

---

So, I don't have a complete handle on this, but I do have something to report.   When we started going through this I didn't think there would be anything going on in the Arduino board support packages that would have any effect on this, but it turns out that's not the case.

We worked out that under ESP8266 Arduino core 3.0.0 the lines of the following form fail to compile and under version 2.7.4 the compile without error.  Here under 3.0.0 it was not picky about specifically `loginPassword`.

```c++
if (someArduinoStringObj == '\0') someArduinoStringObj = "some literal";
```
This can be abstracted to the somewhat nonsensical:

```c++
someArduinoStringObj == '\0';
```

Since that's the part makes the difference.  I *really* thought there was something more clever going on in the WString.h/WString.cpp code, an extra constructor or implicit conversion operator call prior to the code for the == operator.  There is an explicit constructor for `String` that takes a single char, but it's just that, it's explicit; it doesn't take part in evaluating the `==` expression above.  And there's no automatic conversion from `String` to `const char *`. It turns out that isn't anything clever going on in String class when it comes to this problem.  In fact you can boil this down to something similar so that the String class itself isn't actually involved at all, into:

```c++
void func(const char *) {}

void setup() {
  func('\0');
}

// ...
```

This will likewise pass compilation under 2.7.4 and fail with a similar error message under 3.0.0.  So, with String it is just trying to call the `operator==(const char *)`, even though it's being given a `char` type.  Before getting into that, I tested a theory, which was to find out what happens if given `== '\1';` or `== 'X')` etc, any non-zero value, because 0 has had an interesting relationship with pointers in C++ and C.  It makes more sense once you realize there's special going on in String.h.  We're basically talking about `func('\0')` vs `func('\1')` or `func('X')`  Well, under 2.7.4 these values fail where '\0' does not, but under 3.0.0 both fail.  So I got looking into the platform.txt file on both core versions, thinking maybe I'll spot a difference in compiler options.  E.g. it would make "sense" if 2.7.4 had `-fpermissive` where 3.0.0. didn't, but that's not the case.  The major difference is that 3.0.0 has -std=g++17 and 2.7.4 has -std=g++11.  Just for the hell of it I stole the command-line out of the verbose output compiling for the .ino.cpp file and replaced -std=g++17 with -std=g++11 and applied it to a cut-down file; didn't make any difference.  So, as far I tell there's some difference in default options specified between the two compiler versions in use in the two esp8266 package versions.

Constant expressions that evaluate to zero of `int` type (at least), will convert to null pointer constants.  I haven't been in the habit of using character-typed (`'\0'`) zero valued constant expressions for null pointers, and I haven't dug through the various editions of the C++ standard to see what each one has to say about them; color me unsurprised either way.  But in any case, that's is basically what's happening here: The string object is being compared to a null pointer constant, at least when it compiles.  And if that makes you go WTF, well, me too.  If you follow this out, you ultimately you [end up here][1]:

```c++
unsigned char String::equals(const char *cstr) const {
    if (len() == 0)
        return (cstr == NULL || *cstr == 0);
    if (cstr == NULL)
        return buffer()[0] == 0;
    return strcmp(buffer(), cstr) == 0;
}
```

So, roughly speaking `someArduinoString == '\0'`, *where it will compile*, is equivalent to `someArduinoString == nullptr` which is sort of the same effect as `someArduinoString == ""`.  So, what you're seeing is not exactly an implicit form of `someArduinoString == String('\0')`.

I can't picture wanting to say `someArduinoString == '\0'` over `someArduinoString.isEmpty()`, but in terms of why it doesn't work on 3.0.0, I'm still unsure.  I can tell you that it will if you plant `-fpermissive` into platform.txt, but that doesn't really explain it.  Sometime when I'm really bored I'll see what the language standard actually says and what versions of g++ did what under what options.

Even I worked that out my answer would still be: don't do that.

  [1]: https://github.com/esp8266/Arduino/blob/2.7.4/cores/esp8266/WString.cpp#L509


message:
Arduino Nano: MAX30102 and memory problems

We are making a simple pulse oximeter device with an Arduino Nano and a [MAX30102][1] sensor.

The problem is the SpO2 reading and processing algorithm of the MAX30102 library literally does signal processing on the Arduino with large arrays of data and because of that, when you do BPM and SpO2, the 2kb memory of the Arduino is already full.

Can you guys give me some advice to overcome this problem?

  [1]: https://datasheets.maximintegrated.com/en/ds/MAX30102.pdf

body: Arduino UNO is not recommended for MAX30102 as it requires a lot of processing and RAM. Consider shifting to Arduino Mega or the ESP32.


message:
Encrypting the code using AES . ESP32

I am trying to figure it out. Why are my encryption and decryption not correct?

The used library for AES:

[https://github.com/DanielVukelich/Arduino-AES][3]

This is for testing encrypt and decrypt.
 [//https://www.hanewin.net/encrypt/aes/aes-test.htm][2]

    #include "Rij_Consts.h"
    #include "Rijndael.h"

        void setup() {

          Serial.begin(115200);

          //mbedtls_aes_context aes;

          unsigned char iv[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

          //char * key = "abcdefghijklmnop";
          //const unsigned char key[16];
          const unsigned char key[16] = {0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA};
          //unsigned char key[16] = {0xFA,0xF9,0xF8,0xF7,0xF5,0xF4,0xF3,0xF2,0xF0,0xEF,0xEE,0xED,0xEB,0xEA,0xE9,0xE8};//กลับ

          //char *input = "Tech tutorials x";
         const unsigned char input[16] ={0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33,0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A};
          //unsigned char input[16] ={0x9A,0xE9,0x43,0x36,0x10,0x80,0x51,0x1D,0x33,0x9D,0xA6,0x78,0x22,0xAF,0x4B,0x01};//กลับ

          unsigned char output[16]; //6743C3D1519AB4F2CD9A78AB09A511BD ต้องได้ตามนี้

          printf("Testing ECB mode:\n");

          printf("Original Plaintext:\n");
          for(int i = 0; i < 16; i++){
            printf("%2.2X ", input[i]);
          }

          unsigned char keys[176];//for 128

          Schedule_Keys(AES_128, key, 16, keys);
          printf("\n\nKEYs:\n");
          for(int i = 0; i < 16; i++){
            printf("%2.2X ", keys[i]);
          }

          Encrypt(AES_128, input, 16, keys, output);

          printf("\n\nCiphertext:\n");
         for(int i = 0; i < 16; i++){
            char str[16];
            sprintf(str, "%2.2X ", output[i]);
            Serial.print(str);
         }

        Decrypt(AES_128, input, 16, keys, output);
        printf("\n\nCiphertext:\n");
        for(int i = 0; i < 16; i++){
            char str[16];
            sprintf(str, "%2.2X ", output[i]);
            Serial.print(str);
        }
        }

        void loop() {}

My output :
[![enter image description here][1]][1]

You can see my encryption and decryption not correct.

  [1]: https://i.stack.imgur.com/6MyVP.png
  [2]: https://www.hanewin.net/encrypt/aes/aes-test.htm
  [3]: https://github.com/DanielVukelich/Arduino-AES

I tried to reconstruct the full code.

    #include "Rij_Consts.h"
    #include "Rijndael.h"

    //https://www.hanewin.net/encrypt/aes/aes-test.htm   สำหรับเทสเทียบ

    void setup() {
       Serial.begin(115200);
        unsigned char iv[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        const unsigned char key[16] = {0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA};
        const unsigned char plainText[16] ={0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33,0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A};
        unsigned char cipherText[16]; //6743C3D1519AB4F2CD9A78AB09A511BD Answer
        printf("Testing ECB mode:\n");

          printf("Original Plaintext:\n");
                for(int i = 0; i < 16; i++){
                      Serial.printf("%2.2X ", plainText[i]);
          }
            unsigned char keys[176];//for 128

            Schedule_Keys(AES_128, key, 16, keys);
                printf("\n\nKEYs:\n");
                    for(int i = 0; i < 16; i++){
                        Serial.printf("%2.2X ", keys[i]);
          }

          Encrypt(AES_128, plainText, 16, keys,cipherText );
              Serial.printf("\n\nCiphertext:\n");
                  for (int i = 0; i < 16; i++) {
                        Serial.printf("%2.2X ", cipherText[i]);
          }
          unsigned char decryptedText[16];

            Decrypt(AES_128,cipherText , 16, keys, decryptedText);

              Serial.printf("\n\ndecryptedText:\n");
                  for (int i = 0; i < 16; i++) {
                        Serial.printf("%2.2X ", decryptedText[i]);
    }
    }

    void loop() {}

body:
There are some issues with your code.

As mentioned in my comment, `Decrypt ()` expects the Cipher Text as input and generates the Decrypted text as an output. However, in your code you're using the Plain text (which you confusingly named "input") as an input. The correct input should be your Cipher Text (which is the output from the `Encrypt ()` function and which you called "output"). Please read the documentation of the AES library.

I suggest the following changes to your code to get it working:

Replace the part of your code, following `Decrypt (...)` until the end of `setup()` with the following code:

    unsigned char decryptedText[16];
    Decrypt(AES_128, output, 16, keys, decryptedText);

    Serial.printf("\n\ndecryptedText:\n");
    for (int i = 0; i < 16; i++) {
        Serial.printf("%2.2X ", decryptedText[i]);
    }

I would also suggest you name your variables to avoid confusion, for example you could replace `input[]` with `plainText[]` and `output[]` with `cipherText[]`. Some of your Hex output code is also unnecessarily complex and could do with some restructuring.

I've compiled and run the above changes with your code on an ESP32 and it produces the expected Cipher text and correctly decrypts it. It produces the following output:

    00:21:01.583 -> Testing ECB mode:
    00:21:01.583 -> Original Plaintext:
    00:21:01.630 -> 01 4B AF 22 78 A6 9D 33 1D 51 80 10 36 43 E9 9A
    00:21:01.630 ->
    00:21:01.630 -> KEYs:
    00:21:01.630 -> E8 E9 EA EB ED EE EF F0 F2 F3 F4 F5 F7 F8 F9 FA
    00:21:01.630 ->
    00:21:01.630 -> Ciphertext:
    00:21:01.630 -> 67 43 C3 D1 51 9A B4 F2 CD 9A 78 AB 09 A5 11 BD
    00:21:01.630 ->
    00:21:01.630 -> decryptedText:
    00:21:01.630 -> 01 4B AF 22 78 A6 9D 33 1D 51 80 10 36 43 E9 9A

In your question you mention that the generated Cipher text is not as expected. I can't help you with that, as I can't reproduce it.


message:
nRF52 non-volatile storage/recall of a variable - is there a simple solution?

I have an Arduino program written for the nRF52 with which runs for a pre-set time-value (i.e. 2 minutes) before shuts off automatically.  The variable time-value can be changed via BLE-write by the user from an external device (i.e. from 2 mins to 5 mins). The problem that it defaults to the pre-set (2 mins) value once the program restarts.  **How can I have the program "save" the last used time-value variable (i.e. 5 mins) for the next boot up/restart?**

As I understand Nordic's nRF52 does NOT have an onboard EEPROM like AVRs.  I read about a Little File System by Adafruit that creates a sort of persistent storage space, but I hope there is something simpler.

body:
[The arduino-NVM library][1] for nRF51 and nRF52 MCU has EEPROM object which emulates EEPROM in the internal flash memory of MCU.

The EEPROM object in arduino-NVM has the same functions as the EEPROM object in the Arduino EEPROM library for classic ATmega.

  [1]: https://www.arduino.cc/reference/en/libraries/arduino-nvm/


message:
My Arduino don't show port but is working

I have some problem with **Arduino uno** and asked [here][1], so I have tried to work by my STM32F103C8 as alternative board, and solved my problem by this question:

[Arduino Port Not detected and can not run it as root][2]

But now I as seeing that the Arduino port again is not acceptable but I can upload the codes into the STM32F103C8 board, so I asked why this happen ?

[![enter image description here][3]][3]
Note : I have seen [this post][4] which the STm32F103C8 board have some port on Arduino IDE (as you can see below ):

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

**Update:**

I have seen The below post about the same problem as you can see below:

[Can't open serial monitor using ST Link and STM32F103C8][6]

But, based of the last part of above post,which is shown below,
I don't get have could i have enable the serial port connection for the STM32f103C8 Board:

> I did everything as it was described in tutorial, flashing bootloader
> was succes, everything went ok, but windows still can't recognize it.
> I am thinking that maybe it is problem with that resistor and maybe i
> have to mod it... I think I will be sticking to ST-Link for uploading
> codes and USB-UART for serial. But thanks for help
>
> And one more question, can you tell me how to reset my Blue Pill to
> factory bootloader (how to delete stm32 bootloader that I installed)

Thank.

  [1]: https://arduino.stackexchange.com/questions/84593/about-corrupted-lm35-ic-and-arduino-port-problem?noredirect=1#comment190078_84593
  [2]: https://askubuntu.com/questions/1345632/arduino-port-not-detected-and-can-not-run-it-as-root/1345851#1345851
  [3]: https://i.stack.imgur.com/nOhxB.png
  [4]: https://create.arduino.cc/projecthub/akarsh98/using-a-stm32-like-an-arduino-tutorial-stm32f103c8-1073cb
  [5]: https://i.stack.imgur.com/DmByw.png
  [6]: https://www.stm32duino.com/viewtopic.php?t=90

body:
The STM32F103C8 has a native USB interface. You will only ever see a CDC/ACM (USB UART emulation) interface if you actively run code that implements a CDC/ACM interface.

The bootloader is separate to your code. I don't know what protocol the bootloader for your board uses, but it may not even have a CDC/ACM interface to it.

**In short: it doesn't have a port because you haven't programmed it to have a port, and the code uploading doesn't use a port, so doesn't care.**


message:
Is it possible to read multiple buttons with the CD74HC4067?

[![This is the image of the schematic for the project I am working on][1]][1]I am working on a project with a claw machine. I am working on this chip (CD4067BE which is equivalent to the CD74HC4067) and I was wondering: can I read more than one button with the CD4067? I tried the following code, and it works great, but when I want to push two buttons, it will not read both of them as zero. Why am I using a chip with the buttons? It was to reduce I/O pins on my PCB for the claw machine. Yes, I could use a matrix, but I want control over my components, whether to turn it on or off. Also, the CD4067 includes all my buttons. I have thirteen buttons. (13 buttons). By the way, this chip is a multiplexer/demultiplexer. I am using this chip as a multiplexer. Oh, and also, I have an Arduino Mega 2560 rev3. I have followed the instructions of [this question][2], but this doesn't answer if the chip can read more than button at one time. Thanks,

Austin

    //Mux control pins
    int s0 = 5;
    int s1 = 4;
    int s2 = 3;
    int s3 = 2;

    //Mux in "SIG" pin
    int SIG_pin = 6;

    void setup() {

      pinMode(s0, OUTPUT);
      pinMode(s1, OUTPUT);
      pinMode(s2, OUTPUT);
      pinMode(s3, OUTPUT);

      pinMode(SIG_pin, INPUT_PULLUP);

      Serial.begin(9600);
    }

    void loop() {

      //Loop through and read all 16 values
      for (int i = 0; i < 16; i ++) {
        Serial.print("Value at channel ");
        Serial.print(i);
        Serial.print("is : ");
        Serial.println(readMux(i));
        delay(1000);
      }
    }

    int readMux(int channel) {
      int controlPin[] =       {s0, s1, s2, s3};
      int muxChannel[16][4] = { {0, 0, 0, 0},
                                {1, 0, 0, 0},
                                {0, 1, 0, 0},
                                {1, 1, 0, 0},
                                {0, 0, 1, 0},
                                {1, 0, 1, 0},
                                {0, 1, 1, 0},
                                {1, 1, 1, 0},
                                {0, 0, 0, 1},
                                {1, 0, 0, 1},
                                {0, 1, 0, 1},
                                {1, 1, 0, 1},
                                {0, 0, 1, 1},
                                {1, 0, 1, 1},
                                {0, 1, 1, 1},
                                {1, 1, 1, 1}
                              };
      //loop through the 4 sig
      for (int i = 0; i < 4; i ++) {
        digitalWrite(controlPin[i], muxChannel[channel][i]);
      }
      //read the value at the SIG pin
      int val = digitalRead(SIG_pin); //return the value
      return val;
    }

  [1]: https://i.stack.imgur.com/kg0C0.jpg
  [2]: https://electronics.stackexchange.com/questions/278321/reducing-the-number-of-pins-needed-to-read-a-12-key-keypad-where-the-buttons-are

body:
An alternative way to write to the 4-bit MUX select pins is to use shifting and masking, something like this:

```cpp
// MUX control pins
byte s0 = 2;
byte s1 = 3;
byte s2 = 4;
byte s3 = 5;
byte controlPin[] = { s0, s1, s2, s3 };

. . .

byte readMux(byte channel)
{
  // Loop through the 4 signals
  for (byte b = 0; b < 4; b++, channel >>= 1)
  {
    digitalWrite(controlPin[b], channel & 1);
  }
  // Read and return the value at the SIG pin
  return digitalRead(SIG_pin);
}
```


message:
Adafruit Featherwing Latching Relay lamp switch

I am brand new to Arduino. So I apologize in advance if I have missed the information I am looking for. I have looked for hours and cannot find any help with a Adafruit Featherwing Latching Relay(#2923 on Adafruit). This is the one that has 2 set pins "Set" & "Unset". I would love to use a Wemos d1 mini to trigger this relay. But I cannot find any sketchs or documentation on how to get started.

Ideally the setup would have a push button to toggle between states as well as the basic esp8266 web page to toggle state as well.

I am just trying to turn off/on some LEDs. And want to run the switch via this setup.

Thanks
E

Well I am further along. I was able to get most of this working but now the CSS i am using is causing headaches. The code below errors on "page =
Simple NodeMCU Web Server

    <button class="button">ON</button>         <button>OFF</button>
";`

I get the error 'inconsistent user-defined literal suffixes 'LEDOn' and 'button' in string literal'

Any help would most appreciated. This line is the only one failing in my sketch

body:
That board is specifically designed for the Feather ecosystem, so you'd need to provide the [relevant connections][1], looks like 3.3V and GND, and the two input signals (also 3.3V, I assume). Nutshell: you can ignore almost every single connector on the board except for 3.3V, GND, SET, and UNSET.

Any D1 (or Arduino in general) tutorial that discusses how to set an output pin value is fine--you'd need them to be `LOW` by default and bring the relevant one `HIGH` for 10ms (`delay` is fine here) to set the new state.

Any switch input tutorial should be fine for learning how to read a switch, and there are multiple tutorials regarding setting up a simple web app that interacts with 8266 IO. Note that you'll want to keep track of the current state, though, and probably update the web app with the current state if it's changed via the button.

All this said: "just trying to turn off/on some LEDs" is broad. A relay may not be necessary; is there an explicit need for a latching relay?

  [1]: https://learn.adafruit.com/mini-relay-featherwings?view=all#latching-schematic-1981636-4


body:
I will add the final code here. It took me weeks to find a starting place and many hours of trial and error to sort it all out. With help I was able to get a stable working switch.

This code was written for a Wemos D1 Mini coupled to a Adafruit Featherwing Latching relay. Since it has Set and Unset pins coding this was struggle for me. The Set/Unset pins only require a pulse to trigger them then they stay 'Latched' in state. even if power is lost. I found the [base code here][1] and it took a bit of tweaking to get it to work.

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

// Replace with your network credentials
const char* ssid = "SSID";
const char* password = "PASSWORD";

ESP8266WebServer server(80);   //instantiate server at port 80 (http port)

String page = "";
int LEDUnsetPin = D1;
int LEDSetPin = D2;
void setup(void){
 //the HTML of the web page
 //don’t forget you need estapes (") around the quotes
 page = "<style>  .button{    background-color:red;    color:blue;    border-radius: 8px;    padding: 12px 24px;  }</style><h1>Kitchen LEDs</h1><p>    <a href=\"LEDOn\"><button class=\"button\">ON</button></a>         <a href=\"LEDOff\"><button>OFF</button></a></p>";
 //make the LED pins output and initially turned off
 pinMode(LEDUnsetPin, OUTPUT);
 digitalWrite(LEDUnsetPin, LOW);
 pinMode(LEDSetPin, OUTPUT);
 digitalWrite(LEDSetPin, LOW);

 delay(1000);
 Serial.begin(115200);
 WiFi.begin(ssid, password); //begin WiFi connection
 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());

 server.on("/", [](){
   server.send(200, "text/html", page);
 });

 //turn on the on pin and turn off the off pin
 server.on("/LEDOn", [](){
   server.send(200, "text/html", page);
   digitalWrite(LEDSetPin, HIGH);
   delay(10);
   digitalWrite(LEDSetPin, LOW);
   delay(10);
 });

 //turn off the on pin and turn on the off pin
 server.on("/LEDOff", [](){
   server.send(200, "text/html", page);
   digitalWrite(LEDUnsetPin, HIGH);
   delay(10);
   digitalWrite(LEDUnsetPin, LOW);
   delay(10);
 });
 server.begin();
 Serial.println("Web server started!");
}

void loop(void){
 server.handleClient();
}
```

  [1]: https://michaelweinberg.org/post/170722380870/control-led-lights-with-a-webpage-esp8266-relay


message:
NodeMCU wont connect to Blynk

My NodeMCU wont connect to Blynk with my code but works fine with example code and same auth token and WiFi info. Cant figure out why its not working. Must be something in my code interfering with it (Or something stupid I'm missing). Any ideas? Thanks!

```
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "AUTH";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "SSID";
char pass[] = "PASSWD";

const int analogPin = A0;

const int muxA = 9;// MUX pin A
const int muxB = 10;//MUX pin B
const int muxC = 16;//MUX pin C

const int outputPin0 = 4;// output pin 0
const int outputPin1 = 5;// output pin 1
const int outputPin2 = 12;//Output pin 2
const int outputPin3 = 13;//output pin 3
const int outputPin4 = 14;//output pin 4

int startWatering0 = 1023;//start watering value 0
int startWatering1 = 1023;//start watering value 1
int startWatering2 = 1023;//start watering value 2
int startWatering3 = 1023;//start watering value 3
int startWatering4 = 1023;//start watering value 4

int currentMoisture0 = 0;//current moisture value 0
int currentMoisture1 = 0;//current moisture value 1
int currentMoisture2 = 0;//current moisture value 2
int currentMoisture3 = 0;//current mousture value 3
int currentMoisture4 = 0;//current moisture value 4

int wateringTime0 = 0;//watering time 0
int wateringTime1 = 0;//watering time 1
int wateringTime2 = 0;//watering time 2
int wateringTime3 = 0;//watering time 3
int wateringTime4 = 0;//watering time 4

bool isWatering0 = false;//is 0 currently watering
bool isWatering1 = false;//is 1 currently watering
bool isWatering2 = false;//is 2 currently watering
bool isWatering3 = false;//is 3 currently watering
bool isWatering4 = false;//is 4 currently watering

long wateringStart0 = 0;//watering 0 start value
long wateringStart1 = 0;//watering 1 start value
long wateringStart2 = 0;//watering 2 start value
long wateringStart3 = 0;//watering 3 start value
long wateringStart4 = 0;//watering 4 start value

BlynkTimer timer;

void setup()
{
  //initialize outputs
  pinMode(muxA, OUTPUT);
  pinMode(muxB, OUTPUT);
  pinMode(muxC, OUTPUT);

  pinMode(outputPin0, OUTPUT);
  pinMode(outputPin1, OUTPUT);
  pinMode(outputPin2, OUTPUT);
  pinMode(outputPin3, OUTPUT);
  pinMode(outputPin4, OUTPUT);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

  timer.setInterval(1000L, checkSensors);
}

void checkSensors()
{
  //check sensors here
  setMux0();
  currentMoisture0 = analogRead(analogPin);
  setMux1();
  currentMoisture1 = analogRead(analogPin);
  setMux2();
  currentMoisture2 = analogRead(analogPin);
  setMux3();
  currentMoisture3 = analogRead(analogPin);
  setMux4();
  currentMoisture4 = analogRead(analogPin);
  setMux5();
  setMux6();
  setMux7();

  Blynk.virtualWrite(V11, currentMoisture0);
  Blynk.virtualWrite(V12, currentMoisture1);
  Blynk.virtualWrite(V13, currentMoisture2);
  Blynk.virtualWrite(V14, currentMoisture3);
  Blynk.virtualWrite(V15, currentMoisture4);

  //starts watering if soil is drier than set value, and if it is not already watering
  if(currentMoisture0 >= startWatering0 && isWatering0 == false)
  {
    isWatering0 = true;
    digitalWrite(outputPin0, HIGH);
    wateringStart0 = millis();
  }

  if(currentMoisture1 >= startWatering1 && isWatering1 == false)
  {
    isWatering1 = true;
    digitalWrite(outputPin1, HIGH);
    wateringStart1 = millis();
  }

  if(currentMoisture2 >= startWatering2 && isWatering3 == false)
  {
    isWatering2 = true;
    digitalWrite(outputPin2, HIGH);
    wateringStart2 = millis();
  }

  if(currentMoisture3 >= startWatering3 && isWatering3 == false)
  {
    isWatering3 = true;
    digitalWrite(outputPin3, HIGH);
    wateringStart3 = millis();
  }

  if(currentMoisture4 >= startWatering4 && isWatering4 == false)
  {
    isWatering4 = true;
    digitalWrite(outputPin4, HIGH);
    wateringStart4 = millis();
  }

///////////////////////////////////////////////////////////////////////////////////
  //stops watering if it is currently watering, and it has been watering for longer than the set time
  if(millis() >= wateringStart0 + (wateringTime0 * 60000 ) && isWatering0 == true)
  {
    isWatering0 = false;
    digitalWrite(outputPin0, LOW);
  }

  if(millis() >= wateringStart1 + (wateringTime1 * 60000 ) && isWatering1 == true)
  {
    isWatering1 = false;
    digitalWrite(outputPin1, LOW);
  }

  if(millis() >= wateringStart2 + (wateringTime2 * 60000 ) && isWatering2 == true)
  {
    isWatering2 = false;
    digitalWrite(outputPin2, LOW);
  }

  if(millis() >= wateringStart3 + (wateringTime3 * 60000 ) && isWatering3 == true)
  {
    isWatering3 = false;
    digitalWrite(outputPin3, LOW);
  }

  if(millis() >= wateringStart4 + (wateringTime4 * 60000 ) && isWatering4 == true)
  {
    isWatering4 = false;
    digitalWrite(outputPin4, LOW);
  }
}

void setMux0()//sets mux to pin 0
{
  digitalWrite(muxA, LOW);
  digitalWrite(muxB, LOW);
  digitalWrite(muxC, LOW);
}

void setMux1()//sets mux to pin 1
{
  digitalWrite(muxA, HIGH);
  digitalWrite(muxB, LOW);
  digitalWrite(muxC, LOW);
}

void setMux2()//sets mux to pin 2
{
  digitalWrite(muxA, LOW);
  digitalWrite(muxB, HIGH);
  digitalWrite(muxC, LOW);
}

void setMux3()//sets mux to pin 3
{
  digitalWrite(muxA, HIGH);
  digitalWrite(muxB, HIGH);
  digitalWrite(muxC, LOW);
}

void setMux4()//sets mux to pin 4
{
  digitalWrite(muxA, LOW);
  digitalWrite(muxB, LOW);
  digitalWrite(muxC, HIGH);
}

void setMux5()//sets mux to pin 5
{
  digitalWrite(muxA, HIGH);
  digitalWrite(muxB, LOW);
  digitalWrite(muxC, HIGH);
}

void setMux6()//sets mux to pin 6
{
  digitalWrite(muxA, LOW);
  digitalWrite(muxB, HIGH);
  digitalWrite(muxC, HIGH);
}

void setMux7()//sets mux to pin 7
{
  digitalWrite(muxA, HIGH);
  digitalWrite(muxB, HIGH);
  digitalWrite(muxC, HIGH);
}

//sets values when they are changed in app

//start watering values

BLYNK_WRITE(V1)
{
  int startWatering0 = param.asInt();
}

BLYNK_WRITE(V2)
{
  int startWatering1 = param.asInt();
}

BLYNK_WRITE(V3)
{
  int startWatering2 = param.asInt();
}

BLYNK_WRITE(V4)
{
  int startWatering3 = param.asInt();
}

BLYNK_WRITE(V5)
{
  int startWatering4 = param.asInt();
}

//watering time values

BLYNK_WRITE(V6)
{
  int wateringTime0 = param.asInt();
}

BLYNK_WRITE(V7)
{
  int wateringTime1 = param.asInt();
}

BLYNK_WRITE(V8)
{
  int wateringTime2 = param.asInt();
}

BLYNK_WRITE(V9)
{
  int wateringTime3 = param.asInt();
}

BLYNK_WRITE(V10)
{
  int wateringTime4 = param.asInt();
}

void loop()
{
  Blynk.run();
  timer.run();
}
```

body:
I'd start by cutting it down to just the setup() and loop() functions (without the timer call) and establish whether it connects, and if not, why not.

Then add back the timer call and a very short version of checkSensors(), and try again.

Continue adding back sections of code until it fails.


body: Ok I got it figured out, it was because I was using pin 9 and 10, I didnt know they couldn't be used. Thanks @Juraj!


message:
ATmega328p bootloader issue : [avrdude: stk500_recv(): programmer is not responding]

I am using an arduino uno board and have placed the new ATmega328chip in the socket as a simple setup as mentioned in [Minicore installation instructions][1]. However, I am unable to burn the bootloader. I am using your minicore and selected the ATmega328 chip. I have tried using 8MHz internal crystal as well as 16 MHz external crystal but get the same error. I even tried using a different ATmega328p but the result was same. Here is the output:

    avrdude: Version 6.3-20201216
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Users\Administrator\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.1.2/avrdude.conf"

             Using Port                    : COM4
             Using Programmer              : stk500v1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x03
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x03

    avrdude done.  Thank you.

    Error while burning bootloader.

Before trying this Minicore option I also tried different tutorials which ask for external crystal and extra capacitors. It's been two days I am trying to make it work but sadly haven't managed it yet. Initially I suspected a faulty ATmega but even three other chips result in the same error or device signature error.

Here are the other connections I have used:

[![Serial connection][2]][2]

[![FTDI/UART connection][3]][3]

Could you please help me fix it? Thanks

  [1]: https://github.com/MCUdude/MiniCore
  [2]: https://i.stack.imgur.com/aFkTg.png
  [3]: https://i.stack.imgur.com/HvKXn.png

body:
You have to install the bootloader using either an working Arduino or a hardware programmer.

There is one step that many many tutorials on this subject miss out (and both the circuits you show have missed it out), and that is to disable the automatic reset of the programming Arduino.  That can be done a number of ways:

* Add a low-value pullup resistor to RESET
* Add a high-value capacitor between RESET and GND
* Cut the "RESET-EN" trace on the underside of the board

Once the bootloader is installed in this way you can then put the chip into an Arduino and program it through USB, or connect it to a USB to UART adapter and program it through that.


message:
Do I use an LED or a pullup resistor for stopping "floating" or "ghosting" for a matrix keypad?

I know this sounds simple, but I have an Arduino Mega 2560 and I am making a matrix keypad for a claw machine. It's a 3*4 matrix keypad. Let's just say, I am making this keypad for the claw machine to reduce the number of I/O pins. I have tried to use a mux, but that has failed me because it has a single input/output pin and can only read ONE button at a time. So, I have come up with the solution to use a matrix keypad because: A. It is the most common method and B. It is smaller on a PCB design rather than that CD4067BE chip. The reason why I was trying to use that chip in the first place was because it included all my thirteen buttons. Basically, what I am wanting to know is if I should use a resistor or an LED to stop either "floating" or "ghosting." I still don't really know the difference between the two terms, but if somebody could clarify that, that would be great. And also when I should use an LED or a resistor. Or do they serve the same purpose? Tutorials: [LED "ghosting"][1] [Pullup Resistor "floating"][2] (I am not sure how to make a schematic of the "floating" pin). [![Schematic for the project][3]][3] (Credit to EasyEDA for the schematic). Thanks,

Austin

  [1]: https://www.baldengineer.com/arduino-keyboard-matrix-tutorial.html
  [2]: https://www.build-electronic-circuits.com/pull-up-resistor/
  [3]: https://i.stack.imgur.com/p6psk.jpg

body:
First some clarification:

* Floating is where an input isn't connected to a defined logic state. It's neither in one state or the other and is free to "float" between them at will. Basically a floating input is an antenna.
* Ghosting is where you press two buttons in a matrix together and it causes unwanted short or crossed circuits in the matrix making it appear that other keys are pressed when they aren't.

The Keypad.h library deals with any pullups that may be needed.  To prevent ghosting you need to use diodes (*not* LEDs) to separate the buttons from each other.

Nick Gammon has [a fantastic tutorial](https://www.gammon.com.au/forum/?id=14175) where he describes the problems and solutions to ghosting.


message:
Can I test if something is connected to analog pin?

In my sketch I have a potentiometer connected to A0.  The value of the pot is used to adjust the speed of a connected item.

I have set the speed to have a default value, but doing analogRead() on a pin with nothing attached gives random values rather than using the default value.  The docs state "*If the analog input pin is not connected to anything, the value returned by analogRead() will fluctuate based on a number of factors (e.g. the values of the other analog inputs, how close your hand is to the board, etc.).*"  https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

How can I test whether something is connected to A0 and if not, use the default value?

body:
Take some number of analog readings over some period of time and look at the variation among the samples. Do this both with, and without, a potentiometer connected. You should see very stable readings with it connected, ranging over a few counts or less. Without it connected, the readings are likely to cover nearly the entire range A/D range.

A simple way to detect the pot would be to look at the difference between the highest and lowest readings. Pick a range that covers the "pot is connected" case. If the difference falls within that range, assume the pot is connected. Otherwise, assume it is not.

You could improve on this a number of ways, but a simple way would be to take, say, 50 readings, sort them by value, average the lowest 5 or 10 of them, and average the highest 5 or 10. Subtract those averages, and proceed as above.


body:
The input stage of the analog-to-digital converter is a sample-and-hold
capacitor. When you take an analog reading, the capacitor is connected
to the input pin, it is charged to the voltage you want to measure, then
it is disconnected from the input and it “holds” the voltage while the
conversion is in progress.

You can leverage this capacitor to detect whether your input pin is
floating. If you try to take an analog reading from a floating pin, the
sample-and-hold capacitor will not be able to charge or discharge
through it. You should then get a reading that is close to the
_previous_ reading you took, although not exactly the same, as floating
pins a very prone to noise. Thus I suggest the following algorithm:

- take a reading from a pin tied to GND, and discard this reading
- take a reading from your input pin and record it
- take a reading from a pin tied to +5V and discard it
- take and record a second reading from your input pin

If the input pin is floating, the first recorded reading should be close
to zero, and the second one close to 1023.

Here is a test sketch demonstrating this approach. It uses
`digitalWrite()` to tie the required pins to GND and +5V, thus no
external connections are needed:

```c++
const uint8_t pin_input = A0;  // the one we are interested in
const uint8_t pin_low   = A1;  // will be tied to GND
const uint8_t pin_high  = A2;  // will be tied to +5V

void setup() {
    Serial.begin(9600);
    pinMode(pin_input, INPUT);
    pinMode(pin_low, OUTPUT);
    digitalWrite(pin_low, LOW);
    pinMode(pin_high, OUTPUT);
    digitalWrite(pin_high, HIGH);
}

void loop() {
    analogRead(pin_low);  // take a reading and discard it
    Serial.print(analogRead(pin_input));
    Serial.print(" ");
    analogRead(pin_high);  // take a reading and discard it
    Serial.println(analogRead(pin_input));
    delay(200);
}
```

And here is a sample output from an Arduino Uno:

```text
167 710
271 748
287 753
287 751
284 748
281 746
279 741
271 736
268 733
264 732
```

It looks like the capacitor does not hold its charge very well across
consecutive readings. This is presumably caused by the parasitic
capacitance of the input pin, which partially charges and discharges the
sample-and-hold. Yet, the difference between consecutive recorded
readings (about 460) is still very high, and this very clearly shows
that the input pin is not connected to a stable voltage.


body: The ADC input has a really high impedance (100 Meg).  All you need to do to get a consistent reading (of zero) is to connect it to ground through a suitable resistor.  100K will probably be fine, and you might be able to get away with 1 Meg.  It should be at least 10x bigger than your pot to avoid loading it when connected.


message:
SPI.begin doesn't work after tristate

I am working on a ultra-low power project using an ATMEGA328P, a nRF24L01 and a 0.47F super-capacitor to measure various sensors akin to [Gammon's solar power project][1]. I have been having problems with keeping the current consumption of the nRF24L01 low which appears to be a common problem as noted [here][2]. I only have been able to get the current down during sleep to 950uA as opposed to 7uA. Power for the nRF24L01 comes from an AMS1117 that is switched on and off from a digital pin. Thus, during sleep the nRF24L01 isn't drawing power directly so the current must be coming from the SPI. According to Gammon's code, after the radio message is sent he sets the SPI pins as OUTPUT and LOW following SPI.end(), like so:

    bool ok = radio.write (&reading, sizeof reading);
    radio.startListening ();
    radio.powerDown ();
    SPI.end ();
    // set pins to OUTPUT and LOW
    for (byte i = 9; i <= 13; i++)
        {
        pinMode (i, OUTPUT);
        digitalWrite (i, LOW);
        }  // end of for loop

Since the current consumption is coming from the SPI, I decided to reverse this by setting the SPI pins to INPUT assuming that SPI.begin() would automatically set them back appropriately. At this point current during sleep was the expected 7uA but no messages were being sent. I checked around and found that there was a problem where [SPI.end()  causes SPI.transfer() to hang even after a new SPI.begin()][3]. Unfortunately the solution there didn't work in my case.

I tried to change the pins to OUTPUT when coming out of sleep but that obviously didn't work. One of the posts pointed out that the pins shouldn't be configured as output before calling SPI.begin() because SPIClass::begin() does not have code in it to do so, and that this is probably done so for a reason. Indeed, in Gammon's code, where he sets all pins to OUTPUT and LOW during setup in order to minimize current consumption, he skips the SPI pins:

      // set pins to OUTPUT and LOW
      for (byte i = 0; i <= A5; i++)
        {
        // skip radio pins
        if (i >= 9 && i <= 13)
          continue;
        pinMode (i, OUTPUT);
        digitalWrite (i, LOW);
        }  // end of for loop

What I don't understand is why is it possible to set the SPI pins as OUTPUT after SPI.end() and not do the same after coming out of sleep and just before SPI.begin()? Also, why is it that if I tristate the pins after SPI.end() the SPI bus doesn't appear to work, that is, SPI.begin() appears to hang?

  [1]: http://www.gammon.com.au/forum/?id=12821
  [2]: https://forum.arduino.cc/t/actually-putting-nrf24l01-radio-into-power-down-mode/333207/8
  [3]: https://forum.arduino.cc/t/spi-end-causes-spi-transfer-to-hang-even-after-a-new-spi-begin/161700

body:
I finally found an answer [here][1]. The exact problem is close to what I had thought: the MOSI pin isn't set low after SPI.end(). The solution is not to set the pin as INPUT as I had first thought, but to set the MOSI pin low by first adding

    SPCR &= 0B10111111;

before putting the system to sleep (which disables the SPI) and then adding this line

    SPCR |= 0B01000000;

after coming out of the sleep in order to re-enable the SPI.

Although this problem was already noted years ago and a fix apparently made, it still exists because SPI.end() should have disabled the SPI bus and it didn't, so this workaround is still needed.

  [1]: https://arduino.stackexchange.com/questions/62466/cannot-set-mosi-pin-low-even-after-ending-spi


message:
How to use Serial2 on Raspberry Pi Pico

I want to use Serial1 and Serial2 in a sketch in Arduino IDE for a Raspberry pi pico.
My goal is to communicate from the pico with two other Arduino boards.

I use Arduino 1.8.9 and the official board for Raspberry Pi Pico:
"Arduino Mbed OS RP2040 Boards by Arduino version 2.1.0"

Serial2 does not seem to be configured. When I compile

```
    #include <Arduino.h>
    void setup() {
        Serial2.begin(9600);
    }

    void loop(){}
```

I get:
    `"undefined reference to '_UART2_'".`

I found some documents (not rpi pico specific) that state you can define a second UART like this:
```
    #include "wiring_private.h"
    Uart mySerial (&sercom3, 1, 0, SERCOM_RX_PAD_1, UART_TX_PAD_0); // Create the new UART instance assigning it to pin 1 and 0
```

But that throws
    `" 'Uart' does not name a type; did you mean 'sqrt'?"`

Does anyone have an example of how to use Serial1 and Serial2 (2 serial communications to two other boards) on a Raspberry Pi Pico using Arduino-IDE?

Thanks a lot!

body:
I found the solution after reading https://github.com/arduino/ArduinoCore-mbed/issues/210#issuecomment-849502556.

Although the proposed code did not compile as it was shown there.

    UART Serial2(8, 9);  // did not compile

What worked for me was:

    UART Serial2(8, 9, 0, 0);

Full code:

    #include <Arduino.h>

    UART Serial2(8, 9, 0, 0);

    void setup() {
      Serial2.begin(9600);
      // ...
      Serial2.write("hello world");
    }

    void loop {}


body:
I'm not using the "Mbed" board, I'm using the "Raspberry Pi Boards(1.9.7)" --> "Raspberry Pi Pico" board, and found that:

Serial1 uses hardware UART0

Serial2 uses hardware UART1

Serial1.begin(SOME_BAUDRATE); // defaults to TX on GP0 and RX on GP1

Serial2.begin(SOME_BAUDRATE); // defaults to TX on GP8 and RX on GP9

To change the default UART pins to other option, as long as it comply with the Raspberry Pi Pico pinout (look for UARTx_TX / UARTx_RX next to the pins), see the following example:

    #include <hardware/pio.h>

    gpio_set_function(12, GPIO_FUNC_UART); // change the TX default for Serial1 (UART0)
                                           // to be GP12

    gpio_set_function(13, GPIO_FUNC_UART); // change the RX default for Serial1 (UART0)
                                           // to be GP13


message:
How to get time from RTC after wake up from sleep?

I have a setup with an Arduino Pro Mini, a DS1307 RTC, a microSD shield and a microswitch. I've set an interrupt to the microswitch, so it'll wake up the Arduino when it changes status. Here is some relevant code:
```
void setup() {
  rtc.begin();
  pinMode(button, INPUT);
  SD.begin(chipSelect);

  /*Omitted the same write to file as in button_ISR()*/
}

void loop() {
  delay(5000);
  goToSleep();
}

void goToSleep() {
  sleep_enable();
  attachInterrupt(digitalPinToInterrupt(button), button_ISR, CHANGE);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  delay(500);
  sleep_cpu();
}

void button_ISR() {
    sleep_disable();
    detachInterrupt(0);
    rtc.begin();
    String data = (digitalRead(button))?"OPEN":"CLOSE";
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    if(dataFile) {
      DateTime now = rtc.now();
      dataFile.print(now.year(), DEC);
      dataFile.print('.');
      dataFile.print(now.month(), DEC);
      dataFile.print('.');
      dataFile.print(now.day(), DEC);
      dataFile.print(". (");
      dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
      dataFile.print(") ");
      dataFile.print(now.hour(), DEC);
      dataFile.print(":");
      dataFile.print(now.minute(), DEC);
      dataFile.print(":");
      dataFile.print(now.second(), DEC);
      dataFile.print(";");
      dataFile.println(data);
      dataFile.close();
    }
    delay(1000);
}
```
If I don't call rtc.now(), and omit the DateTime prints, the code perfectly writes "OPEN" and "CLOSE" in the txt. I have the same dateTime writing inside the setup(), with "START", and it perfectly writes the current date/time.

What am I missing? How could I get the time from RTC after wake up?

body:
You should not delay in an ISR, for two reasons:

1. Interrupts are disabled while the ISR runs, and `delay()` relies on
   interrupts.

2. Interrupts are used to handle time-critical tasks. The longer the
   interrupts are disabled, the larger the chances that one of those
   time-critical tasks is handled too late. Thus, ISRs should execute as
   fast as possible.

In this particular case, if we try to make the ISR as short as possible,
the optimal version is this:

```c++
void button_ISR() {}
```

Since the interrupt is meant to wake up the Arduino, and nothing more,
everything the ISR does can be done at wake-up, right after
`sleep_cpu();`.

A few more comments and suggestions:

- `set_sleep_mode(SLEEP_MODE_PWR_DOWN);` can be done once and for all in
  `setup()`

- instead combining `sleep_enable()`, `sleep_cpu()` and
  `sleep_disable()`, you can use a single call to `sleep_mode()`

- you most probably do not need to reinitialize the RTC and re-open the
  file at every loop iteration: do this only once, in `setup()`

- `String` objects are not friendly to a small Arduino's memory; in this
  case you can get rid of them by simply replacing the word `String`
  with `const char *`

- if you are using RTClib, you may want to use [the
  `DateTime::toString()` method][toString], which can make your code
  shorter and simpler.

[toString]: https://adafruit.github.io/RTClib/html/class_date_time.html#a3753bf2ae254315a56f7ee38ff0b188b


message:
How to deal with global variables in a program which has more than 5 functions and every function accesses them without any problem?

I know that using Global Variables in programming may create lots of problems in long term , like , Bugs , Lags and more . I am working on a program which has more than 5 functions which need to access global variables something like this.

    int Name;
    int Age;
    int Weight;
    String EyeColour;

    void AddValues(int N, int A , int W , String EC){
     Name = N;
     Age = A;
     Weight = W;
     EyeColour = EC;
    }

    // All the functions below use those Global Variables

    void function2(){
     ...
    }

    void function2(){
     ...
    }

    void function3(){
     ...
    }

    void function4(){
     ...
    }

     void function5(){
     ...
     }

But according to [this article][1]

I should avoid using global variables to avoid future problems so I wrapped them up inside a struct.
Like this.

    struct Person{

    int Name;
    int Age;
    int Weight;
    String EyeColour;

    }

Now my main question is, should I declare the structure variable globally? Will it avoid the problems which could be created by global variables ?

If I declare the struct variable globally will it be equivalent to declaring variables globally instead of the structure?

Or

Should I declare the structure variable inside all the functions instead of declaring globally?

So that all functions can work flawlessly without any global variable problems.

  [1]: https://www.tutorialspoint.com/Why-should-we-avoid-using-global-variables-in-C-Cplusplus#:~:text=Using global variables causes very,to decouple them when testing.

body:
Create a class from the 4 variables (I don't have a compiler at hand, so forgive any compiler errors):

    class Person
    {
    public:
        void Person(int N, int A , int W , String EC);

    private:
        int Name;
        int Age;
        int Weight;
        String EyeColour;
    }

Create the implementation of `Person` in the Person.cpp file.

About the functions, if they only relay (or mostly rely) on the 4 properties (Name, Age, Weight, EyeColor), make the a method (function) inside the class.

Decide if a function should be in a method depends upon  many thing, but the most important question is: does it belong (well enough) to the class or not?

Now in the Arduino.ino you can make one instance (or more if you need more).

    Person _person;

Preferably, I add an underscore for global variables (and instance variables).

Also, I would avoid using `String` as changing it will cause dynamic memory allocation changes, which can be very bad in a 2K SRAM system. Try to make constant string arrays (with a max length).


message:
Serial.print() Inferferes with my digitalRead()

I'm running into issue properly reading a button connected to a digital I/O pin on my Adafruit Feather HUZZAH ESP8266 device.

I've implemented the debouncing script exactly as the Arduino provided example shows, but if I add a print statement to my setup loop:

```
void setup() {
  Serial.begin(230400);
  Serial.println("Starting");
  pinMode(buttonPin, INPUT_PULLUP);
}
```

I trigger a reading of the switch on every reset cycle. Commenting out the print statement will avoid the problem so it doesn't appear to be related to the debouncing script.

In addition, I can replicate the problem on *any* digital I/O pin even when there is no pin connected. Once I get past the setup function, everything works as intended. Here's my whole setup code (again, copied from the example):

```
const int buttonPin = 13;
int buttonState;
int lastButtonState = LOW;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

void setup() {
  Serial.begin(230400);
  Serial.println("Starting");
  pinMode(buttonPin, INPUT_PULLUP);
  lastDebounceTime = millis();

}

void loop() {
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;

      Serial.println("A");
    }
  }

  lastButtonState = reading;
}

```

And here's the output of my serial monitor (with no delays on reset):

```
Starting
A
```

I can avoid this by just ignoring the first button switch but it seems odd that this is happening and I can't find any explanations for what's going on.

body:
Initializing my buttonState solved my problem:

```
int buttonState = LOW;
```


body:
You need to initialise `buttonState` to the current signal state and initialise `lastDebounceTime` to the current time, something like this:

```cpp
int buttonState = digitalRead(buttonPin);
unsigned long lastDebounceTime = millis();
```

Compare with this very simple [debouncer][1] I put on GitHub.

  [1]: http://github.com/TimMathias/Arduino-Debouncer


message:
Passing a two dimensional array to a function

I'm working on an led matrix project where I'm running a series of patterns made of bitmap frames.

Here's an example: https://vimeo.com/564184465

Right now I'm using a series of method calls named per pattern to run the animation:

```
void CSMatrix::runPattern(PATTERNS pattern, uint8_t totalRuns)
{
  for (uint8_t i = 0; i < totalRuns; i++)
  {
    switch (pattern)
    {
    case PATTERN_ZIG_ZAG:
      runPatternSpacedStripes();
      break;
    case PATTERN_ARROW_UP:
      runPatternArrowUp();
      break;
...
    }
  }
}

void CSMatrix::runPatternSpacedStripes()
{
  for (uint8_t i = 0; i < SPACED_STRIPES_LEN; i++)
  {
    renderFrame(SPACED_STRIPES[i]);
    FastLED.show();
    delay(100);
  }
}

void CSMatrix::runPatternArrowUp()
{
  for (uint8_t i = 0; i < ARROW_UP_LEN; i++)
  {
    renderFrame(ARROW_UP[i]);
    FastLED.show();
    delay(100);
  }
}

...
```

And the bitmaps used to control the matrix pixel states look like this (the functions beneath `renderFrame` basically say "if it's a 1, use this color, if it's a 0, use that color":

```
const byte SPACED_STRIPES[][8] = {
    {0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000},
    {0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100},
...
};
const int SPACED_STRIPES_LEN = sizeof(SPACED_STRIPES) / 8;
```

This is working fine, but having a bunch of identical methods to run each pattern is not great.

So, with this working I decided to refactor to make a common `runTwoColorPattern` method that could accept the pattern frames and the length to run the given pattern:

```
void CSMatrix::runTwoColorPattern(const byte *frames, const int length, int delayDuration)
{
  for (uint8_t i = 0; i < length; i++)
  {
    renderFrame(frames[i]);
    FastLED.show();
    delay(delayDuration);
  }
}
```

The problem I'm running into is figuring out how to properly pass the two dimensional array to the function.

I tried updating my switch statement by passing the pointer of `SPACED_STRIPES` into the `runTwoColorPattern`:

```
    switch (pattern)
    {
    case PATTERN_ZIG_ZAG:
      runTwoColorPattern(SPACED_STRIPES, SPACED_STRIPES_LEN, 100);
      //runPatternSpacedStripes();
      break;
```

But when I do I get the error
> argument of type "const byte (*)[8]" is incompatible with parameter of type "const byte *"C/C++(167)

 [![error][1]][1]

I've found that I can correct this by dereferencing the first item of the multidimensional array, (which would mean I'm passing the memory address to the first pointer element of the multi-dimensional array (I think)), but when I do this the pattern runs backwards and is jittery :|

https://vimeo.com/564184624

I'm not totally sure how to correct this. I'm still fairly new to pointers so I'm sure there's something I'm misunderstanding with passing a pointer for a multi-dimensional array, but I thought what I was passing was basically an address of where to start for the pointer, so I'm not sure why I'm hitting these snags or how to fix it.

Any suggestions?

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

body:
A 2D array would be passed as `const byte frames[][8]`. However you really don't need the complexity of a 2D array - you can do it with a 1D array.

Your array would look like:

```c++
const byte SPACED_STRIPES[] = {
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,

     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
...
};
```

And you reference frames within it as a multiple of 8 of the index.  Using your existing code it would look like:

```c++
void CSMatrix::runTwoColorPattern(const byte *frames, const int length, int delayDuration)
{
  for (uint8_t i = 0; i < length; i++)
  {
    renderFrame(&frames[i * 8]); // Take the address of the first value of the frame at a multiple of 8
    FastLED.show();
    delay(delayDuration);
  }
}
```


body:
The error message is quite explicit:
> argument of type "const byte (\*)[8]" is incompatible with parameter
> of type "const byte \*"

If you want to pass `SPACED_STRIPES` to the method, it is going to be
passed as `const byte (*)[8]`, i.e. pointer to arrays of 8 `byte`. You
can just set the parameter type accordingly:

```c++
void CSMatrix::runTwoColorPattern(
    const byte (*frames)[8], const int length, int delayDuration)
{
    // body unchanged
}
```


message:
Invalid use of void expression (how to use function pointer with input)

I'm defining an attachinterrupt and I'm running into an error. The line in question is:

    void setup() {
       attachInterrupt(digitalPinToInterrupt(stallsense1), changedirection(1), RISING);
       attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
    }

and the error I'm getting is:

    error: invalid use of void expression
    attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
                                                                                ^
    exit status 1
    invalid use of void expression

The idea is I have one function changedirection and two possible inputs, either 1 or 2.
I believe the issue is where I've called the function changedirection(1). I want to simply tell attachinterrupt to call the function changedirection with an input of either 1 or 2. How would I do this?

body:
`attachInterrupt` expects a simple pointer to function taking no arguments and returning nothing (void).

So, really there's no way to directly do what you're talking about.  There's no currying ability builtin.  You can define your own functions like

```c++
void proxy_changedirection_1() {
    changedirection(1);
}
```

And then `attachInterrupt` specifying `proxy_changedirection_1`, or you can use a lambda with no captures for the same purpose:

```c++
attachInterrupt(
    digitalPinToInterrupt(stallsense1),
    [] () {
        changedirection(1);
    },
    RISING
);
```


body:
What happened is you wrote a void expression where an expression of type 'pointer to function of void returning void' (i.e., no arguments and no return value), was expected. The name of a function with no parentheses for an argument list is an expression of type 'pointer to function' taking whatever arguments & types that named function was declared to expect, and returning whatever type that named function was declared to return.

But if you write the parentheses with it, now you've written an expression that 1) would (if it were valid) get evaluated during the call to attachInterrupt() - much earlier that you want it to be! - and return a value of that return type rather than the type you expected.

@timemage has offered two ways to solve this.


message:
Trying to use Serial to communicate between two D1 Mini's

I'm trying to connect two D1 Mini's together as a POC.
There is a switch on one and a 7 segment display on the other

I have the pins setup from TX>RX and RX>TX

First ESP8266:
```
int SWITCH_PIN = D5;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(SWITCH_PIN, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
}

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

  if(digitalRead(SWITCH_PIN) == HIGH)
  {
    Serial.println(1);
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else
  {
    Serial.println(0);
    digitalWrite(LED_BUILTIN, LOW);
  }
}
```

Second ESP8266:
```
#include "DigitLedDisplay.h"
DigitLedDisplay ld = DigitLedDisplay(D6, D5, D0);

void setup() {

  Serial.begin(115200);

  ld.setBright(10);
  ld.setDigitLimit(8);

  for (long i = 0; i < 100; i++) {
    ld.printDigit(i);
    delay(25);
  }

}

void loop() {
  delay(1000);
  if(Serial.read() == 1)
  {
    ld.printDigit(11111111);
  }
  else if (Serial.read() == 0)
  {
    ld.printDigit(22222222);
  }
  else
  {
    ld.printDigit(33333333);
  }
}
```

As far as I can tell the second ESP8266 isn't getting anything from the first. What am I doing wrong?

Thanks in advance for the help

body:
Thanks to [Juraj][1] it was an easy fix

Missing quotes around the text and changing some code

```
void loop() {
  if (Serial.available() > 0)
  {
    // read the incoming byte:
    incomingByte = Serial.read();
  }
  if(incomingByte == '1')
  {
    ld.printDigit(11111111);
  }
  else if (incomingByte == '0')
  {
    ld.printDigit(22222222);
  }
}
```

adding "if (Serial.available() > 0)" works to make it only update when the serial buffer is full

The delay was also causing issues with where it was located so just removed that

  [1]: https://arduino.stackexchange.com/users/37622/juraj


message:
A9G gsm module not displaying message body after receiving SMS

I am trying to receive an SMS on my arduino and print it out to the serial monitor. I am using the A9G gsm/gps module for doing that. Here is the code for it

    #include <SoftwareSerial.h>

    //Create software serial object to communicate with A6
    SoftwareSerial mySerial(10, 11); //A6 Tx & Rx is connected to Arduino #3 & #2

    void setup()
    {
      //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
      Serial.begin(115200);

      //Begin serial communication with Arduino and A6
      mySerial.begin(115200);

      Serial.println("Initializing...");
      delay(1000);

      mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
      updateSerial();

      mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
      updateSerial();
      mySerial.println("AT+CNMI=2,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
      updateSerial();
    }

    void loop()
    {
      updateSerial();
    }

    void updateSerial()
    {
      delay(500);
      while (Serial.available())
      {
        mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
      }
      while(mySerial.available())
      {
        Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
      }
    }

The code works and I get a response but the response does not include the body of the message. This is the response I got after sending "hello" to it;

    CIEV: "MESSAGE",1
    +CMT: "+233201729573",,"2021/06/18,12:20:03

As you can see it rightly sends me a notification but it does not include the "hello" which is the actual message I want to receive. Can anyone help me out?

body:
Your serial reception code is much much much too primitive to be of any use.

You're waiting for 0.5 seconds for data to come in, which gets stored in a 64 byte buffer. Then you read out the contents of that 64 byte buffer.

Anything more than 64 bytes gets discarded.

You need to read the data actively as it comes in (**NO** `delay()`!) looking for specific things in the data (OK, ERROR, your text message response, etc) until the whole response from the modem has been received.


body: I have sorted that out for sometime now. It turns out for some reason SerialSoftware was truncating my messages because the serial buffer size was too small. All I had to do was increase the buffer size to a higher number in the SoftwareSerial.h file and it worked.


message:
I develop an earthquake detector but when it detects a movement, the alarm doesn't stop from ringing

This is the code that I used. Actually, I use to code: for Arduino sofware and processing IDE software.

Arduino Source Code/Program:

```c++
#include<LiquidCrystal.h> // lcd Header
LiquidCrystal lcd(7,6,5,4,3,2); // pins for LCD Connection

#define buzzer 12 // buzzer pin
#define led 13 //led pin

#define x A0 // x_out pin of Accelerometer
#define y A1 // y_out pin of Accelerometer
#define z A2 // z_out pin of Accelerometer

/*variables*/
int xsample=0;
int ysample=0;
int zsample=0;
long start;
int buz=0;

/*Macros*/
#define samples 50
#define maxVal 20 // max change limit
#define minVal -20 // min change limit
#define buzTime 5000 // buzzer on time

void setup()
{
    lcd.begin(16,2); //initializing lcd
    Serial.begin(9600); // initializing serial
    delay(1000);
    lcd.print("EarthQuake ");
    lcd.setCursor(0,1);
    lcd.print("Detector ");
    delay(2000);
    lcd.clear();
    lcd.print("Calibrating.....");
    lcd.setCursor(0,1);
    lcd.print("Please wait...");
    pinMode(buzzer, OUTPUT);
    pinMode(led, OUTPUT);
    buz=0;
    digitalWrite(buzzer, buz);
    digitalWrite(led, buz);
    for(int i=0;i<samples;i++) // taking samples for calibration
    {
        xsample+=analogRead(x);
        ysample+=analogRead(y);
        zsample+=analogRead(z);
    }

    xsample/=samples; // taking avg for x
    ysample/=samples; // taking avg for y
    zsample/=samples; // taking avg for z

    delay(3000);
    lcd.clear();
    lcd.print("Calibrated");
    delay(1000);
    lcd.clear();
    lcd.print("Device Ready");
    delay(1000);
    lcd.clear();
    lcd.print(" X Y Z ");
}

void loop()
{
    int value1=analogRead(x); // reading x out
    int value2=analogRead(y); //reading y out
    int value3=analogRead(z); //reading z out

    int xValue=xsample-value1; // finding change in x
    int yValue=ysample-value2; // finding change in y
    int zValue=zsample-value3; // finding change in z

    /*displying change in x,y and z axis values over lcd*/
    lcd.setCursor(0,1);
    lcd.print(xValue);
    lcd.setCursor(6,1);
    lcd.print(yValue);
    lcd.setCursor(12,1);
    lcd.print(zValue);
    delay(100);

    /* comparing change with predefined limits*/
    if(xValue < minVal || xValue > maxVal || yValue < minVal
            || yValue > maxVal || zValue < minVal || zValue > maxVal)
    {
        if(buz == 0)
            start=millis(); // timer start
        buz=1; // buzzer / led flag activated
    }
    else if(buz == 1) // buzzer flag activated then alerting earthquake
    {
        lcd.setCursor(0,0);
        lcd.print("Earthquake Alert ");
        if(millis()>= start+buzTime)
            buz=0;
    }
    else
    {
        lcd.clear();
        lcd.print(" X Y Z ");
    }

    digitalWrite(buzzer, buz); // buzzer on and off command
    digitalWrite(led, buz); // led on and off command

    /*sending values to processing for plot over the graph*/
    Serial.print("x=");
    Serial.println(xValue);
    Serial.print("y=");
    Serial.println(yValue);
    Serial.print("z=");
    Serial.println(zValue);
    Serial.println(" $");
}
```

Processing IDE Code/Program:

```java
import processing.serial.*;
PFont f6,f8,f12,f10;
PFont f24;
Serial myPort; // The serial port
int xPos = 0; // horizontal position of the graph
float y1=0;
float y2=0;
float y3=0;

void setup ()
{
    // set the window size: and Font size
    f6 = createFont("Arial",6,true);
    f8 = createFont("Arial",8,true);
    f10 = createFont("Arial",10,true);
    f12 = createFont("Arial",12,true);
    f24 = createFont("Arial",24,true);
    size(1200, 700);

    // List all the available serial ports
    println(Serial.list());
    myPort = new Serial(this, "COM10", 9600);
    println(myPort);
    myPort.bufferUntil('\n');
    background(80);
}

void draw ()
{
    serial();
}

void serial()
{
    String inString = myPort.readStringUntil('$'); // reading incomming date from serial
    if (inString != null)
    {
        // extracting all required values of all three axis:
        int l1=inString.indexOf("x=")+2;
        String temp1=inString.substring(l1,l1+3);
        l1=inString.indexOf("y=")+2;
        String temp2=inString.substring(l1,l1+3);
        l1=inString.indexOf("z=")+2;
        String temp3=inString.substring(l1,l1+3);

        //mapping x, y and z value with graph dimensions
        float inByte1 = float(temp1+(char)9);
        inByte1 = map(inByte1, -80,80, 0, height-80);
        float inByte2 = float(temp2+(char)9);
        inByte2 = map(inByte2,-80,80, 0, height-80);
        float inByte3 = float(temp3+(char)9);
        inByte3 = map(inByte3,-80,80, 0, height-80);
        float x=map(xPos,0,1120,40,width-40);

        //ploting graph window, unit
        strokeWeight(2);
        stroke(175);
        Line(0,0,0,100);
        textFont(f24);
        fill(0,00,255);
        textAlign(RIGHT);
        xmargin("EarthQuake Graph (SESMIOGRAPH)",200,100);

        fill(100);
        strokeWeight(100);
        line(1050,80,1200,80);

        strokeWeight(1);
        textAlign(RIGHT);
        fill(0,0,255);
        String temp="X:"+temp1;
        Text(temp,100,95);

        fill(0,255,0);
        temp="Y:"+temp2;
        Text(temp,100,92);

        fill(255,0,0);;
        temp="Z:"+temp3;
        Text(temp,100,89);

        //ploting x y and z values over graph
        strokeWeight(2);
        int shift=40;

        stroke(0,0,255);
        if(y1 == 0)
            y1=height-inByte1-shift;
        line(x, y1, x+2, height-inByte1-shift) ;
        y1=height-inByte1-shift;

        stroke(0,255,0);
        if(y2 == 0)
            y2=height-inByte2-shift;
        line(x, y2, x+2, height-inByte2-shift) ;
        y2=height-inByte2-shift;

        stroke(255,0,0);
        if(y2 == 0)
            y3=height-inByte3-shift;
        line(x, y3, x+2, height-inByte3-shift) ;
        y3=height-inByte3-shift;

        xPos+=1;

        if (x >= width-30) // go back to begining
        {
            xPos = 0;
            background(80);
        }
    }
}

void Line(int x1, int y1, int x2, int y2)
{
    float xx1=map(x1,0,100,40,width-40);
    float xx2=map(x2,0,100,40,width-40);
    float yy1=map(y1,0,100,height-40,40);
    float yy2=map(y2,0,100,height-40,40);

    line(xx1,yy1,xx2,yy2);
    xx2=map(100,0,100,40,width-40);
    yy2=map(0,0,100,height-40,40);
    line(xx1,yy1,xx2,yy2);

    strokeWeight(1);
    for(int i=1;i<21;i++)
    {
        yy2=map(i*10,0,200,height-40,40);
        yy1=yy2;
        line(xx1,yy1,xx2,yy2);
    }
    yy2=map(100,0,100,height-40,40);
    yy1=map(0,0,100,height-40,40);
    for(int i=1;i<41;i++)
    {
        xx1=map(i*5,0,200,40,width-40);
        xx2=map(i*5,0,200,40,width-40);
        line(xx1,yy1,xx2,yy2);
    }

    textAlign(RIGHT); // 100 degree
    // result+=yy1;
    fill(255);
    strokeWeight(1);
    textFont(f12);
    for(int i=-10;i<11;i++)
    {
        String result="";
        result+=5*i;
        ymargin(result, x1,y1);
        y1+=5;
    }

    x1=0;
    y1=0;
    strokeWeight(1);
    textFont(f10);
    for(int i=0;i<41;i++)
    {
        String result="";
        result+=28*3*i;
        xmargin(result, x1,y1);
        x1+=5;
    }

    textAlign(RIGHT);
    textAlign(RIGHT);
}

void ymargin(String value, int x1, int y1)
{
    float xx1=map(x1,0,100,40,width-40);
    float yy1=map(y1,0,100,height-40,40);
    text(value,xx1-5,yy1+5);
}

void xmargin(String value, int x1, int y1)
{
    float xx1=map(x1,0,200,40,width-40);
    float yy1=map(y1,0,100,height-25,25);
    text(value,xx1+7,yy1);
}

void Text(String value, int x1, int y1)
{
    float xx1=map(x1,0,100,40,width-40);
    float yy1=map(y1,0,100,height-25,25);
    text(value,xx1,yy1);
}
```

body:
I cannot see anything in your code that could be a cause for this
behavior. So maybe the cause is _outside_ the code.

How do you simulate an earthquake? I guess you manually move the sensor
somehow. It may well happen that, after moving it, it doesn't settle in
exactly the same orientation it was before. When this happens, the
acceleration of gravity will be in a slightly different direction, and
your calibration will not be valid anymore. You can check for this
condition by watching the displayed values: if they settle to something
almost constant but large (more than 20 in absolute value), then that is
what is happening.

If this is the case, a possible solution would be to redo the
calibration a couple of seconds after detecting an earthquake. I would
suggest a technique that is, in my view, more elegant: calibrate
continuously, i.e. update the calibration every few microseconds.

The idea is that, instead of computing a set of offsets once and for
all, you low-pass-filter the raw readings and use these smoothed
readings as offsets. When you subtract the offsets from the readings,
you are implementing in essence a high-pass filter.

Here is a tentative implementation of this idea. I made the readings
periodic in order to have some control on the time constant of the
filter. In practice, you would have to adapt the time constant to the
requirements of your experiment:

```c++
// Constants to be adjusted, times are in microseconds.
const uint32_t readingPeriod   = 10e3;  // 10e3 us = 10 ms
const float filterTimeConstant = 10e6;  // 10e6 us = 10 s
const float filterConstant = readingPeriod / filterTimeConstant;

// Periodically updated filtered accelerations.
float accelX, accelY, accelZ;

// Internal state of the filter.
uint32_t lastTimeReading = 0;
float offsetX, offsetY, offsetZ;

// Call this from setup()
void initializeOffsets() {
    offsetX = analogRead(x);
    offsetY = analogRead(y);
    offsetZ = analogRead(z);
}

// Call this from loop()
void updateAccelerations() {
    // Take the readings only every readingPeriod us.
    if (micros() - lastTimeReading < readingPeriod)
        return;
    lastTimeReading += readingPeriod;

    // Read the sensors.
    int readingX = analogRead(x);
    int readingY = analogRead(y);
    int readingZ = analogRead(z);

    // Update the offsets.
    offsetX += filterConstant * (readingX - offsetX);
    offsetY += filterConstant * (readingY - offsetY);
    offsetZ += filterConstant * (readingZ - offsetZ);

    // Update the filtered accelerations.
    accelX = readingX - offsetX;
    accelY = readingY - offsetY;
    accelZ = readingZ - offsetZ;
}
```


body:
I would convert the outputs to Integers from Double and see if it's still 'ringing'.

The description suggests it is creating a feedback loop (critically damped) and you have to set a lower limit of those values that also shut the device down.

So, if you are currently reading precision of < 0.00001 ( in any axis) add a break in the program.

Big old guess but good luck.


body:
Just a guess, but is the vibration from the buzzer sufficiently strong to trigger the accelerometer? If so, once the buzzer sounds after detecting an earthquake, it might just keep triggering itself.

To fix this, you probably need to take some sample accelerometer readings to see how strong the buzzer vibrations are compared to the signal from an earthquake. You could then look to change your calibration or try to filter out the signal from the buzzer.

Alternatively, you might need to physically isolate the buzzer from the accelerometer.


message:
ESP8266-01 module "AT" command testing not responding

Firstly I have connected the Arduino UNo to Esp8266-01 Module and uploaded the Simple Blink Sketch using Arduino Uno and It responded correctly as in the Blue Led Light on Esp8266-01 was blinking correctly. Now for AT Commands I uploaded Blank Sketch to Arduino Uno and then on serial monitor with baud rate as 115200 typed in AT but no output is seen on Serial Monitor , Please Help Why Esp8266-01 Module not responding to AT Commands

body:
The "AT" commands are provided by a specific sketch (firmware). The chip can only hold one sketch at a time - that sketch currently is your "blink" sketch.

If you want to have AT commands then you have to put the correct AT command firmware on the chip, removing your Blink sketch in the process.


message:
Touch Sensor and Potentiometer - Need some help

I'm using an Arduino Nano with a capacitive touch sensor and a potentiometer. I'm trying to get my code to differentiate between three different program states.

- One is when my touch sensor is NOT being touched.
- Two is when my touch sensor IS being touched.
- And three is when my touch sensor is being touched AND a potentiometer is being moved at the same time.

I'm having trouble picking up the second program state, when I'm simply touching the fader but not moving the potentiometer. Program state 1 works great, but program state 3 activates even when there's no data coming in from the potentioeter.

Here's the code. And ideas?

```
#include <CapacitiveSensor.h>
#define rxPin 4
#define txPin 1

const byte touchSend = 2;
const byte touchReceive = 7;

byte minimumCp = 200; // Raise if the fader is too sensitive (0-16383)

bool touched = false; //Is the fader currently being touched?

CapacitiveSensor touchSensor = CapacitiveSensor(touchReceive, touchSend);

void setup() {
  touchSensor.set_CS_AutocaL_Millis(0xFFFFFFFF);
  pinMode(rxPin, INPUT );
  pinMode(txPin, OUTPUT);
  Serial.begin(57600);
}
void loop() {
  int faderPos = analogRead(A7);
  int lastfaderValue;
  int totalCp =  touchSensor.capacitiveSensor(30);
  if (totalCp <= minimumCp) {  // Not Touching Fader
      touched = false;
      Serial.println("Not Touching Fader");
      delay(15);}
  if ((faderPos == lastfaderValue) && (totalCp > minimumCp)) { // Touching Fader
      touched = true;
      Serial.println("Touching Fader, NOT Moving");
      delay(15);}
  if ((faderPos != lastfaderValue) && (totalCp > minimumCp)) { // Touching Fader and Moving
      touched = true;
      Serial.println("Touching Fader, Moving");
      delay(15);}
  lastfaderValue = faderPos; }
```

body:
Figured it out.

I had the lastfaderValue integer in the wrong spot. It works when I put it at the beginning of the code (before the setup).

I also added a tolerance, so that the potentiometer can still fluctuate slightly when I'm not touching it.

Works well now.


message:
How can the SAMD21 chip knows when the on-board NINA W102 restarts

I am building a project that requires the SAMD21 microcontroller to send a `resetToFactory` signal to the NINA W102 on Arduino Nano 33 IoT. My plan is that, once the W102 receives the signal will do NVS formatting and restart itself, and then I need the SAMD21 to restart afterward by an event triggering from the W102(W102 needs to finish the restart cycle first), see the figure.
[![enter image description here][1]][1]

The communication protocol is SPI as the WIFININA lib does.

I have few attempts by trying to read the GPIO voltage from W102, however, it doesn't work because SPI on SAMD21 side will just hang until the W102 finished the restart even though I remove the `waitForSlaveReady()` for receiving the reply, so I can't get any event triggering.

By the way, I can't simply use the `RESET_N` because the program won't know to do the NVS formatting first.

Does anyone have related experience or ideas? Thank you very much.

Best regards,

Edwin Lu

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

body:
I have solved this later I post the question.

The solution is using the fact which SPI on the SAMD21 will hang while W102 restarts, so I just set the SAMD21 restart immediately after the program continues.

Best regards,

Edwin Lu


message:
12V Relay not clicking

Trying to power the 12V relay from an Arduino to make an automatic cocktail maker.  Looking to power 12V water pumps off of the relay.  However, the relay is not clicking, only getting the light.

The connections FROM the Arduino TO the relay is as follows:

| Arduino | Relay |
|---------|-------|
| 5V      | VCC   |
| GND     | GND   |
| pin 3   | IN1   |

Also pictures of circuit are provided. The Arduino is powered by USB laptop.

![Relay][1]
![Arduino][2]
[![Test code][4]][4]

  [1]: https://i.stack.imgur.com/T427q.jpg
  [2]: https://i.stack.imgur.com/AsFTj.jpg
  [3]: https://i.stack.imgur.com/GZ5Eg.jpg
  [4]: https://i.stack.imgur.com/7oxIN.jpg

body:
After search the internet,
i believe the 12v relay need 12v to click.

You may check these :

https://handtoolsforfun.com/how-to-connect-a-12v-relay-board-to-arduino/

https://www.instructables.com/Connecting-a-12V-Relay-to-Arduino/


message:
Can MCP2515 CANBUS Controller be used for two way communication?

I tried searching codes for MCP2515 with Arduino,
On Arduino Forums, Instructables, Electronics Hub, YouTube etc.

All of them were codes for a transmitter node and a receiver node.
Sensors on one node and result on the other end.

Can we connect two Arduinos using MCP2515 and communicate TWO WAY?

body:
I never used CAN bus myself, but what you could do is one of the following:

- Letting the transmitter send a specific (short) message to the receiver. In case the receiver has something to transmit, it sends a specific reply back, so the transmitter can request the receiver to send the actual message to be sent. The disadvantage is that polling is needed.
- If you want the receiver to be able to send its message as fast as possible, add a separate wire next to the CAN bus communication. If that line is LOW or HIGH (decide yourself), then the transmitter can 'immediately' send a message to have the receiver send its actual message.


body:
---Yes---
It should work nicely. They operate only in simplex mode (sending or receiving) to the outside world. Internally they also monitor what they are sending for error checking etc. From the user point they would appear to be bidirectional because they can switch between send and receive messages rapidly, message by message. Of course the bus speed helps. You can get upto 1 Meg with these. I use Cory Fowler's "mcp_can.h". You can get it at: "https://github.com/coryjfowler/MCP_CAN_lib". The library has both send and receive .ino files, get them to work first.  Since CAN is priority Based NDA Non Destructive Arbitration the higher priority message will prevail regardless of who else is on the bus or is sending a message.

Do not forget to put jumpers on the module to terminate the bus. Note the bus gets terminated only at the physical ends. The bus design impedance is 60 Ohm, the termination resistors are 120 ohms.

You simply combine the send and receive sections of code in your module, nothing special to do. You initialize both send and receive at the same time with basically the same information.  You will find the information for this in the setup() section of the code. Be sure to check crystal frequencies, I have seen both 8 and 16 Mhz crystals on these boards.

Per the Bosch specification, which is readily available,  The CAN bus does arbitration automatically by a defined priority on a bit by bit basis. To send a message with the MPC2515 you load it and when the bus becomes available it will transmit it, if there is an error it will retry many times (internal counter) and if it fails you will know. When a message is sent it must receive an ACK in a specified part of the can frame. This can be generated by any node. Your internal protocol needs to determine if the right node got the message.
By the time your external logic can determine it wants to send a message and send a signal it will have already been sent in a standard CAN setup. Any number of modules can start transmitting but the arbitration will weed them out and the highest priority message will get through. Every node will receive every message, depending on its filtering etc it may accept it or ignore it. You can pole or take an interrupt any time it receives a message etc.


message:
Can’t set duty cycle to 0% with custom PWM

I'm trying to control a heating element with PWM with an [Arduino Nano][1], but the problem is even if I set the duty cycle to 0 it gives a tiny spike.

I want to generate a square wave of 1Hz and that's why I override the default PWM registers.

Here is the code:

    // Set up fast PWM on the Arduino Uno at 1 Hz on digital pin D9
    void setup() {

        // set I/O pins
        pinMode(LDR_INPUT, INPUT);      // A0
        pinMode(HEATER_OUTPUT, OUTPUT); // D9

        // Enable the PWM output OC1A on digital pins 9
        TCCR1A = _BV(COM1A1) | _BV(WGM11);
        // Set fast PWM and prescaler of 256 on timer 1
        TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS12);
        // Set the PWM frequency to 1Hz: 16MHz/(256 * 1Hz) - 1 = 62499
        ICR1 = 62499;

        // OCR1A = 32149; // this gives me duty cycle of 50%, working fine

        OCR1A = 0;       // but this is not working

        //allow PWM timers to start
        delay(10);
    }

For testing, I connected an LED to the PWM pin (D9) and these are the spikes from the LDR reading from analog pin A0 (I don't have an oscilloscope).

[![Enter image description here][2]][2]

I'm getting the same results with the Nano and Uno. My IDE version is 1.8.14.

How can I fix this problem?

Here is my temperature control function:

    void Compute()
    {
        unsigned long now = millis();
        int timeChange = (now - lastTime);

        if(timeChange>=SampleTime)
        {
            /*Compute all the working error variables*/
            double error = Setpoint - temprature;

            if (error <= 0)
            {
                Output = 0;
                Serial.println("level: 0");
            }
            else if (error <= 1)
            {
                Output = 5;
                Serial.println("level: 1");
            }
            else if (error <= 2)
            {
                Output = 30;
                Serial.println("level: 2");
            }
            else if (error <= 3)
            {
                Output = 50;
                Serial.println("level: 3");
            }
            else if (error <= 10)
            {
                Output = 60;
                Serial.println("level: 4");
            }
            else if (error <= 100)
            {
                Output = 200;
                Serial.println("level: 5");
            }
            else
            {
                Output = 255;
                Serial.println("level: 6");
            }

            analogWrite(HEATER_OUTPUT, Output);
            //OCR1A = map(Output, 0, 255, 0, 62499);
            delay(10);

            lastErr = error;
            lastTime = now;
        }
    }

The problem is that after I override the PWM registers, the `analogWrite()` seems messed up. It's not working, and for all the values of `Output`, the result is almost the same.

### UPDATE 22/06/2021

I'm still struggling to fix this, if I use `analogWrite()` or `digitalWrite()` to turn off the PWM pin, the further changes on `OCR1A` regs are not taking action. whatever values I gave to the OCR1A the pin remains low, if I manually make the pin high with digitalWrite or analogWrite the pin remains high forever the changes on `OCR1A` are not taking into action.

I wrote a test function

    void testPWM3() {

        Serial.println("f: 1Hz | on 0s");
        digitalWrite(HEATER_OUTPUT, LOW); // turn off the pwm pin to get full of (0% duty cycle)
        delay(5000);
        /*
         After turning off the pin with digitalWrite() further changes on OCR1A reg are not taken into action
        */
        digitalWrite(HEATER_OUTPUT, HIGH);
        Serial.println("f: 1Hz | on 125ms");
        OCR1A =  1953;
        delay(5000);

        Serial.println("f: 1Hz | on 250ms");
        OCR1A =  3906;
        delay(5000);

        Serial.println("f: 1Hz | on 500ms");
        OCR1A =  7812;
        delay(5000);

        Serial.println("f: 1Hz | on 1sec");
        digitalWrite(HEATER_OUTPUT, HIGH);  // this works
        delay(5000);
    }

Any advice on this will be greatly helpful, thank you

  [1]: https://en.wikipedia.org/wiki/List_of_Arduino_boards_and_compatible_systems#Official
  [2]: https://i.stack.imgur.com/i5YCj.png

body:
That is how it is supposed to be. In this fast PWM mode, the duty cycle
is `(OCR1A+1)/(ICR1+1)`. If you want a duty cycle of zero, you have to
disengage the PWM and turn the pin to `OUTPUT` `LOW`.

This is [what the Arduino's `analogWrite()` does][core]: it treats the
value 0 as a special case. Note that 255 is also treated as a special
case, although that is not useful.

**Edit 1**: about `analogWrite()` being messed up.

`analogWrite(9, value)` sets `OCR1A` to a value between 1 and 254 (0 and
255 being handled in a different manner). The duty cycle you get is, as
I wrote before `(OCR1A+1)/(ICR1+1)`. This is **not** what your test
function expects.

I suggest you ditch `analogWrite()` and instead set directly `OCR1A`.

**Edit 2**: Once you have taken control of a PWM channel at low-level,
by writing directly to the hardware registers, you should **not** use
the Arduino functions `digitalWrite()` nor `analogWrite()` on the
associated pin. These functions assume those hardware registers are
controlled solely by the Arduino core, and they will fiddle with them in
a way that will likely break your program.

To set the duty cycle to zero, disable the PWM mode and set the pin to
LOW:

```c++
TCCR1A &= ~_BV(COM1A1);  // disable PWM on pin OC1A = PB1
PORTB  &= _BV(PB1);      // set PB1 to LOW
```

[core]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/cores/arduino/wiring_analog.c#L112-L115


body:
Fast PWM works that way, on Duty Cycle 0% the Output is set to high for 1 cycle at TOP+1 for non-inverted PWM mode and to low for inverted mode.
If you want to have a continuous low output, you have to use Phase Correct  or Phase and Frequency Correct PWM.


message:
How to set 16x2 LCD I2C display backlight?

I have 16x2 LCD display with a I2C backpack. This is the library I am using
https://drive.google.com/drive/folders/16_UqfwFm4VKWcdeJfDmHRV2Hj_IoaTai?usp=sharing

So as given in the code below, by changing variable ```back``` to a 0 or 1, I can turn on and off the backlight. However if I change the values of ```back``` to 100, or 50 the backlight does not get affected, how do I make this happen without the need of an external resistor/potentiometer and but with code.

Note that on my backpack, there is no connection between pins A and K to keep the backlight on but if I connect the two, then the backlight is turned off.

If you don't care of the above here's it summarized-

**How do I control Backlight of LCD with I2C backpack through code?**

Code-

```
#include "LiquidCrystal_PCF8574.h"
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
int back = 1; // 1-on, 0-off

LiquidCrystal_PCF8574 lcdI2C;

void setup(){
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, back);
}

void loop(){
delay(1000);
back = 0;
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, back);
delay(1000);
back = 1;
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, back);

}

body: You don't.  The PCF8574 is an IO expander. It doesn't have any provision for PWM. It's either on, or off.