# Question
Title: How can I pause serial transfer and then un-pause it?
So I am running a USB (UART) connection from my Arduino UNO (using the serialtransfer.h library) to my pc (using the pyserial transfer library). This how the ***INTENDED*** cycle of code goes: I receive the list\_ packet and save it to a list on the Arduino . Then the elements in the list are checked and used to control parameters of motor a using GPIO pins. Finally a return message is sent to acknowledge each transfer.

I was hoping to make the return message from Arduino as sort of a flag ; whether to wait or move onto the next transfer, this is on the python side of things.

***However this is not the case as the sending of packets from Arduino is almost instantaneous even with delay functions and before the Arduino can process the information the transfer is done.***

***1)Why doesn't delay() work ?***

***2) Why isn't code sequential ?***

***This is the Arduino side of things***

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;
int motor1 = 13;
int motor2 = 10;

int obj_cordinates[9];
char reply [16] = {"Packet Recieved"};
void setup()
{
  Serial.begin(115200);
  pinMode(motor1,OUTPUT);
  pinMode(motor2,OUTPUT);

  myTransfer.begin(Serial);
}

void loop()
{
  if(myTransfer.available())
  {
    // use this variable to keep track of how many
    // bytes we've processed from the receive buffer
    uint16_t recSize = 0;
    uint16_t sendSize = 0;

    recSize = myTransfer.rxObj(obj_cordinates, recSize);
    sendSize = myTransfer.txObj(reply, sendSize);

     if( obj_cordinates[4] == 15)
    {
      digitalWrite(motor1, HIGH);
      digitalWrite(motor2, LOW);

      delay(5000);

      digitalWrite(motor1, LOW);
      digitalWrite(motor2, HIGH);
      delay(5000);
    }

    myTransfer.sendData(sendSize);
  }

}

```

***The python side of things***

```
import time
from pySerialTransfer import pySerialTransfer as txfer

def Ser_tran_list (list_):

    try:
        link = txfer.SerialTransfer('COM6')
        link.open()
        time.sleep(2) # allow some time for the Arduino to completely reset

        to_transfer = True
        while to_transfer:
            send_size = 0

            # Send a list

            list_size = link.tx_obj(list_)
            send_size += list_size

            # send a character
            str_ = 'Sending data Packet'
            str_size = link.tx_obj(str_, send_size) - send_size
            send_size += str_size
            link.send(send_size)

            while not link.available():
                if link.status < 0:
                    if link.status == txfer.CRC_ERROR:
                        print('ERROR: CRC_ERROR')
                    elif link.status == txfer.PAYLOAD_ERROR:
                        print('ERROR: PAYLOAD_ERROR')
                    elif link.status == txfer.STOP_BYTE_ERROR:
                        print('ERROR: STOP_BYTE_ERROR')
                    else:
                        print('ERROR: {}'.format(link.status))

            # Parse response string

            rec_str_   = link.rx_obj(obj_type=type(str_),
                                     obj_byte_size=16,
                                     start_pos=0)

            # Display the received data

            print('SENT: {} {}'.format(list_,str_))
            print('Recieved: {}'.format(rec_str_))

            to_transfer = False

```

# Answer
> 2 votes
The `delay()` function uses the milliseconds interrupt. Inside an interrupt handler, all other interrupts are suspended so the `millis()` counter doesn't count and `delay()` never ends. `delayMicroseconds()` will work in the interrupt routine because it just sits in a busy loop. Rewrite the code to eliminate the delay function, you can use millis if you want. This is telling you while in the delay function just about everything stops until it is finished.

---
Tags: arduino-uno, programming
---


# Question
Title: 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:)

# Answer
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 (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 votes

---
Tags: arduino-uno, arduino-nano, atmega328, pcb-design, usbasp
---


# Question
Title: 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.

# Answer
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.
> 2 votes

---
Tags: arduino-ide, uploading, arduino-micro, linux
---


# Question
Title: Wire.h library works on Uno but won't compile for ATtiny85
**TL;DR:**

* Arduinos are current hungry so I want to switch my microcontroller
* code works on Uno, I change upload to ATtiny85, code doesn't compile
* Wire.h breaks at the TWBR input
* Should I keep trying to fix this or should I just use ATmega328P without the Arduino?

---

---

---

So I'm working on a project where I send data from an IMU (MPU6050) to a phone using Bluetooth LE (HC08) with a bit of signal filtering by a microcontroller in between. I've been using Pro Minis but the amperage consumption by these boards is ridiculous, so I'm trying to replace these with some ATtiny85's that I have laying around.

The problem is, the Wire.h library won't compile for the ATtiny85. It's also worth noting that the default MPU6050 code mandates use of an interrupt pin, which ATtiny's don't have, so I've modified the code to work without it (I'm not sure if that's part of the problem).

```
#include <SoftwareSerial.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"

//==============================================================================
// MPU6050 initialization code
MPU6050 mpu;
uint16_t packetSize;
uint16_t fifoCount;
uint8_t fifoBuffer[64];
Quaternion q;
VectorInt16 aa;
VectorInt16 aaReal;
VectorInt16 aaWorld;
VectorFloat gravity;

//==============================================================================
// microcontroller initialization code
int avg_counter = 0;
int pts_to_avg = 15;
int * x_array = (int*)malloc(sizeof(int) * 25);
int * y_array = (int*)malloc(sizeof(int) * 25);
int * z_array = (int*)malloc(sizeof(int) * 25);

//==============================================================================
// HC-08 initialization code
const byte rxPin = 3;
const byte txPin = 4;
SoftwareSerial bleSerial(rxPin, txPin);

//==============================================================================
void setup() {
  // MPU6050 setup code ========================================================
  Wire.begin();
  TWBR = 24;
  mpu.initialize();
  mpu.dmpInitialize();
  mpu.setXAccelOffset(-1343);
  mpu.setYAccelOffset(-1155);
  mpu.setZAccelOffset(1033);
  mpu.setXGyroOffset(19);
  mpu.setYGyroOffset(-27);
  mpu.setZGyroOffset(16);
  mpu.setDMPEnabled(true);
  packetSize = mpu.dmpGetFIFOPacketSize();
  fifoCount = mpu.getFIFOCount();

  // microcontroller setup code ================================================

  // HC-08 setup code ==========================================================
  // make sure your HC-08 is set to the same baud as below!
  bleSerial.begin(19200);
  delay(100);
}

//==============================================================================
void loop() {
  while(fifoCount < packetSize){
    fifoCount = mpu.getFIFOCount();
  }

  if(fifoCount == 1024){
    mpu.resetFIFO();
    bleSerial.println(F("FIFO overflow!"));
  }else{
    if(fifoCount % packetSize != 0){
      mpu.resetFIFO();
    }else{
      while(fifoCount >= packetSize){
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        fifoCount -= packetSize;
      }

      mpu.dmpGetQuaternion(&q,fifoBuffer);
      mpu.dmpGetAccel(&aa, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &q);
      mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
      mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);

      // points are averaged to keep the baud low w/o FIFO overflow
      if(avg_counter <= pts_to_avg){
        // add live data to this array and hold onto it to be averaged
        x_array[avg_counter] = aaWorld.x;
        y_array[avg_counter] = aaWorld.y;
        z_array[avg_counter] = aaWorld.z;
        avg_counter++;
      }else{
        // average data from the array
        int x_average=0;
        int y_average=0;
        int z_average=0;

        // sums the data in #_average
        for(int i = 0; i < avg_counter; i++){
          x_average += x_array[i];
          y_average += y_array[i];
          z_average += z_array[i];
        }

        // divides by avg_counter (which should == pts_to_avg)
        x_average /= avg_counter;
        y_average /= avg_counter;
        z_average /= avg_counter;

        // resets counter so the array data can be overwritten with future data
        avg_counter = 0;

        // prints data to serial port (if BT is connected, sends via BT)
        bleSerial.print(x_average);
        bleSerial.print(",");
        bleSerial.print(y_average);
        bleSerial.print(",");
        bleSerial.println(z_average);
      }
    }
  }
}

```

When using Arduino as ISP, selecting "Board: ATtiny25/45/85", "Processor: ATtiny85", & "Clock: Internal 1MHz", the following error showed up:

```
exit status 1
'TWBR' was not declared in this scope

```

this error did *not* occur when compiling for the Uno. If you comment out TWBR, then you get an enormous error message (I'll only paste a bit):

```
In file included from c:\users\auphynne\appdata\local\arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.4-arduino2\avr\include\avr\io.h:99:0,

                 from C:\Users\auPhynne\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\libraries\Wire\src\utility\twi.c:25:

C:\Users\auPhynne\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\libraries\Wire\src\utility\twi.c:426:15: error: 'TWINT' undeclared (first use in this function)

    TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;

               ^

C:\Users\auPhynne\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\libraries\Wire\src\utility\twi.c:426:28: error: 'TWSTA' undeclared (first use in this function)

    TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;

                            ^

C:\Users\auPhynne\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\libraries\Wire\src\utility\twi.c:426:40: error: 'TWEN' undeclared (first use in this function)

    TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;

                                        ^

exit status 1
Error compiling for board ATtiny25/45/85.

```

To try to remedy this, I went into

```
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c

```

and hardcoded this line from

```
// initialize twi prescaler and bit rate
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;

```

to

```
// initialize twi prescaler and bit rate
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
TWBR = 24;

```

and I still got the same gruesome error message.

Pins are what you'd expect, 5v power to both modules and grounded, plus:

* Uno D4 -\> HC08 RXD
* Uno D3 -\> HC08 TXD
* Uno SCL -\> MPU6050 SCL
* Uno SDA -\> MPU6050 SDA

(again note that the interrupt pin is not used, and this worked quite well when building on the Uno! I got data on my phone's BT serial terminal app so that doesn't seem to be the problem)

**Any ideas on how I can get Wire.h to compile on my ATtiny85?**

**Or... should I just abort and go with the ATmega328P** (without the accompanying Uno) since it comes in the Quad Flat SMD package? (footprint matters for the long term)

# Answer
> 7 votes
You get this error, because the ATTiny85 doesn't have full I2C hardware. It only as an USI (Universal Serial Interface). This can be utilized to do the rest of the I2C protocol via software. There are some libraries out there to do that, most of them are somewhat named `TinyWire`. There were dedicated libraries for master and slave operation named `TinyWireM` and `TinyWireS`. And I composed one library with both functionalities (and some more) in TinyWire. The last one - I think - is not usable for you, because the`SoftwareSerial` library needs the PinChangeInterrupt to work, but TinyWire uses it for detecting stop conditions on the I2C bus.

So for your case you can use the TinyWireM library. Note that the master operations need exact timing. Using to much interrupts in this time can cause problems in transmission. Test it and disable interrupts, if it is needed.

# Answer
> 2 votes
If you want Wire.h library to work on attiny85 use:

https://github.com/SpenceKonde/ATTinyCore

I did and it compiles.

---
Tags: i2c, attiny, wire-library
---


title: Can Arduino take 19.5 V

text:
# Question
Title: Can Arduino take 19.5 V
I have a 19.5 V power adapter, can I safely connect it to my Arduino? I don't want to damage it. It is very simple, just lights some LEDs, and I don't want to burn the LEDs either.

# Answer
You can do it but you will have nothing left from the regulator for LEDs etc. The best solution is to invest in a buck converter, they are only a few dollars from your favorite china supplier, sometimes even less then a buck. While you are at it purchase two or three you can then use them to generate other voltages as you progress with the Arduino. I use this method a lot, it is a way to use my old laptop power supplies. If you do not have one your next purchase should be a multimeter, even a cheap one is better than none. Then a logic analyzer, again less than $10.00 US. You could also purchase a 8 to 12V wall wart with maybe about 2 amp output and be safe while probably costing less then the buck converter. Have fun!
> 1 votes

# Answer
The Arduino Uno has a maximum voltage range of 6 to 20 v and a recommended range of 7 to 12 v

Using it at 19.5 v may work if the power supply is well regulated but it is uncomfortably close to the limits and dropping nearly 15v across the linear regulator on the Uno may cause it to get fairly hot.
> 1 votes

---
Tags: power
---


# Question
Title: 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?

```
    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();
    }

```

# Answer
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`.

```
if (someArduinoStringObj == '\0') someArduinoStringObj = "some literal";

```

This can be abstracted to the somewhat nonsensical:

```
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:

```
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:

```
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.
> 2 votes

---
Tags: arduino-ide, string, compilation-errors
---


# Question
Title: Water level switches / reed switches and Arduino Uno
How could I estimate the max number of switches that I could connect to an Arduino Uno?

I am questioning if Arduino has enough power to simultaneously operate an X number of switches with no issues.

I am using an external power adapter of 12 volt/2 amps (barrel).

Here is the hardware: https://m.hellasdigital.gr/el/products/tank-pool-water-level-liquid-sensor-float-switch

# Answer
thank you a lot about your input it was very useful. My source of issues was a faulty sensor. After I changed it things are smooth now. I separated the power cables from the signal as well that is super important.

Thank you a lot about the valuable input!
> 1 votes

---
Tags: arduino-uno, sensors, switch
---


# Question
Title: My Arduino don't show port but is working
I have some problem with **Arduino uno** and asked here, 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

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 ?

Note : I have seen this post which the STm32F103C8 board have some port on Arduino IDE (as you can see below ):

**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

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.

# Answer
> 1 votes
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.**

---
Tags: stm32, upload
---


title: Encrypting the code using AES . ESP32

text:
# Question
Title: 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

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

```
#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 :

You can see my encryption and decryption not correct.

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() {}

```

# Answer
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.
> 2 votes

---
Tags: esp32
---


title: NodeMCU wont connect to Blynk

text:
# Question
Title: 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();
}

```

# Answer
> 1 votes
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!

# Answer
> 0 votes
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.

---
Tags: code-review, blynk
---


# Question
Title: 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. 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:

Could you please help me fix it? Thanks

# Answer
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.
> 0 votes

---
Tags: atmega328, bootloader
---


# Question
Title: 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" Pullup Resistor "floating" (I am not sure how to make a schematic of the "floating" pin).  (Credit to EasyEDA for the schematic). Thanks,

Austin

# Answer
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 where he describes the problems and solutions to ghosting.
> 2 votes

---
Tags: arduino-mega, c++, led, c, resistor
---


# Question
Title: 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?

# Answer
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:

```
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:

```
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.
> 6 votes

# Answer
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.
> 2 votes

# Answer
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.
> 2 votes

---
Tags: analogread
---


# Question
Title: 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

# Answer
> 1 votes
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 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();
}

```

# Answer
> 0 votes
That board is specifically designed for the Feather ecosystem, so you'd need to provide the relevant connections, 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?

---
Tags: feather
---


title: How to connect SIM7100A to Arduino?

text:
# Question
Title: How to connect SIM7100A to Arduino?
I've been searching for how to connect a SIM7100A module to an Arduino (Uno or Mega), but I haven't been able to find any posts anywhere, nor videos nor any kind of documentation that shows how to do it. Does anyone here know how to connect it so I can send simple AT commands to the module from the Arduino? (I just want to make GET requests and get GPS coordinates)

# Answer
Got it to work, in part thanks to the documentation that @Juraj posted. My pinout is the following, in case anyone needs it:

SIM7100A -\> Arduino Mega

SUPPLY -\> 5V (the SIM7100A's SUPPLY pin powers the actual board, it's different from the VDD pin which is only for the Serial communication)

GND (both lower & upper) -\> GND

VDD -\> 3.3V

TXD -\> RXD2

RXD -\> voltage divider (5V to 3.3V) -\> TXD2

Once the module is powered (the PWR LED is on), you gotta press the module's reset button for about 3 seconds and then wait for the NET and STA LEDs to turn on, then you can start sending AT commands to it.

I don't know if this will be the case for everyone, but for me, the serial communication through the SIM's USB debug port is with 9600 bauds, but the communication through the TXD and RXD pins is with 115200 bauds.
> 1 votes

---
Tags: serial, gsm, gps
---


title: SPI.begin doesn't work after tristate

text:
# Question
Title: 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. I have been having problems with keeping the current consumption of the nRF24L01 low which appears to be a common problem as noted here. 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(). 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?

# Answer
I finally found an answer here. 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.
> 2 votes

---
Tags: atmega328, spi, nrf24l01+
---


# Question
Title: 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

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.

# Answer
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).
> 1 votes

---
Tags: variables
---


# Question
Title: 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?

# Answer
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:

```
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, which can make your code shorter and simpler.
> 2 votes

---
Tags: interrupt, rtc, sleep
---


# Question
Title: 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)

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?

# Answer
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:

```
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:

```
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);
  }
}

```
> 1 votes

# Answer
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:

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

```
> 2 votes

---
Tags: array, class, pointer
---


# Question
Title: 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?

# Answer
`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

```
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:

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

```
> 1 votes

# Answer
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.
> 0 votes

---
Tags: arduino-nano, interrupt
---


# Question
Title: 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

# Answer
> 1 votes
Thanks to Juraj 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

---
Tags: serial
---


title: Dealing with USB Unplugging?

text:
# Question
Title: Dealing with USB Unplugging?
The following code, debugs SerialUSB Native Port, *plugged* to a PC, and *connected* through a Terminal Monitor (such as *Termite*, with any bps, 8N1, RTS/CTS).

At start, the ports seeks for communication, and you see fast blinks.

If **`SerialUSB`**, **Plugged** and **Connected**, communication happens, a.k.a. slow blinks.

But if USB is **Unplugged** after **`SerialUSB`**, even if you **Disconnect** it before, the code turn into an **`Halt`** state, a.k.a. no blinks.

If you **Plug** back the USB, it returns to **`!SerialUSB`**, so if you **Disconnect** (if it were connected) and **Connect** back the terminal, it recovers the **`SerialUSB`** state, not without a `reset()` line to react. Seems the same happens for `Serial`.

**Any clue about why the Arduino goes into that `Halt` state after a USB disconnect?**

**How should we deal with that? How one should prevent this state?**

Most people asserts this is a power source problem. This happens *with* and *without* the 5V Barrel Power Source.

```
// ARDUINO DUE BLINK LED
void setup(){
  pinMode(13,OUTPUT);
  Serial.begin(115200);
  SerialUSB.begin(115200);
  while(!Serial){
    digitalWrite(13,HIGH);delay(500);
    digitalWrite(13,LOW);delay(500);
  }
  Serial.println("System Reset");
}
void loop(){
  int n=0;
  while(!SerialUSB){
    Serial.println("USB Unplugged or Terminal Disconnected");
    digitalWrite(13,HIGH);delay(50);
    digitalWrite(13,LOW);delay(450);
    n=n+1;
    if (n>=5){
      Serial.println("Resetting to Connect if Disconnected");
      digitalWrite(13,HIGH);delay(450);
      digitalWrite(13,LOW);delay(50);
      rstc_start_software_reset(RSTC);
    }
  }
  SerialUSB.println("USB Plugged and Terminal Connected");
  Serial.println("USB Plugged and Terminal Connected");
  digitalWrite(13,HIGH);delay(50);
  digitalWrite(13,LOW);delay(50);
}

```

# Answer
> 1 votes
This is not possible to do because the protocol CDC/ACM don't send that type of information so you can't detect if the Arduino is connected or not, that's why it halts. (You could make a keep-alive function but I don't know if this is possible with what you're doing)

---
Tags: serial, arduino-due
---


# Question
Title: 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.

# Answer
> 1 votes
You need to initialise `buttonState` to the current signal state and initialise `lastDebounceTime` to the current time, something like this:

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

```

Compare with this very simple debouncer I put on GitHub.

# Answer
> 1 votes
Initializing my buttonState solved my problem:

```
int buttonState = LOW;

```

---
Tags: button, debounce
---


# Question
Title: Is it possible to read multiple buttons with the CD74HC4067?
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, 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;
}

```

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

```
// 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);
}

```
> 0 votes

---
Tags: arduino-mega, arduino-ide, multiplexer, demultiplex
---


# Question
Title: Arduino Uno - Raspberry PI - Float Sensors - Water pumps
I am experimenting with Aquaponics and since I am a software developer I found it "smart" to use arduino/raspberry in order to control the water flow and not simply use a water pump with mechanical means.

The advantage is that I am able to expand easier the system. The disadvantage is that I haven't yet met the reliability that I would lie to have. I am a software engineer with basic knowledge in the hardware field. That is why I thought of starting with Raspberry.

Initially I made a setup with a single raspberry PI a few float sensors like this: https://www.hellasdigital.gr/electronics/sensors/humidity-sensor/tank-pool-water-level-liquid-sensor-float-switch/

and relay like this one: https://wiki.52pi.com/index.php/DockerPi\_4\_Channel\_Relay\_SKU:\_EP-0099

I saw that sometimes the system was hanging with the relays open! This had the side effect to loose water. This is the most precious in aquaponics!

Thus I thought of creating a cluster. Thus I made a cluster of three Raspberrys. The two had the relays and only one PI had the sensors. In order to open the water pump both PIs should have given the green light. This worked better and when one of the PIs hanged then we lost no water.

But again I am thinking that it was not acceptable that the system was hanging so often (at least several times per week). Thus I thought maybe if I use an Arduino for this purpose then this would be better.

Thus this is what I did. I created a simple program (no cluster and a single Arduino). Unfortunately this had even worst results!!!

For the Arduino I used normal 5 Volt relays like this one: https://www.nettop.gr/index.php/hlektronika/relay/8-channel-5v-relay-module-with-light-coupling-5v.html and the same float sensors.

I do not believe that is software related the issue but it must be hardware. The problem is that my knowledge in the hardware field is limited! What should I do in order to prevent this? Do you think that is related with the water pumps and the relays ?

The same erroneous behavior happens at both the Raspberry and Arduino, I mean that the relay stays open and the water overflows. For Raspberry I can tell that the system stop to respond, I am sure about it. But for Arduino I cannot say for sure if the whole system was frozen or if input only for the float did not work.

I paste a link to the quick and dirty Arduino code as well for your reference. The temperature were the systems were operating could be quite hot (30 ~ 48 degrees Celsius) for several hours.

Here is the code for the Arduino:

```
#define POT_1_FLOAT_SENSOR  2
#define POT_1_RELAY_1       11

#define PIPE_1_FLOAT_SENSOR  5
#define PIPE_1_RELAY_1       9

#define PIPE_2_FLOAT_SENSOR       3
#define PIPE_2_RELAY_2      10

#define PIPE_3_RELAY_3       12
#define PIPE_3_FLOAT_SENSOR       4

// pot 1
const unsigned long POT_1_MAX_WATERING_PERIOD = 120000;
const unsigned long POT_1_DRAIN_PERIOD = 70000;

unsigned long pot1StartMillis = 0;
unsigned long pot1DelayStartMillis = 0;

// Pipe 2
const unsigned long PIPE_2_MAX_WATERING_PERIOD = 300000;
const unsigned long PIPE_2_DRAIN_PERIOD = 300000;

unsigned long pipe2DelayStartMillis = 0;
unsigned long pipe2StartMillis = 0;

// Pipe 3
const unsigned long PIPE_3_MAX_WATERING_PERIOD = 760000;
const unsigned long PIPE_3_DRAIN_PERIOD = 300000;
unsigned long pipe3DelayStartMillis = 0;
unsigned long pipe3StartMillis = 0;

// Pipe 1
const unsigned long PIPE_1_MAX_WATERING_PERIOD = 180000;
const unsigned long PIPE_1_DRAIN_PERIOD = 300000;
unsigned long pipe1DelayStartMillis = 0;
unsigned long pipe1StartMillis = 0;

bool pot1RedFlag = false;
bool pot1SetStartTime = false;

bool pipe1RedFlag = false;
bool pipe1SetStartTime = false;

bool pipe2RedFlag = false;
bool pipe2SetStartTime = false;

bool pipe3RedFlag = false;
bool pipe3SetStartTime = false;

void setup()
{
  Serial.begin(9600);
  // initialize the pushbutton pin as an input:
  pinMode(POT_1_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(POT_1_RELAY_1, OUTPUT);
  digitalWrite(POT_1_RELAY_1, LOW);

  pinMode(PIPE_1_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(PIPE_1_RELAY_1, OUTPUT);
  digitalWrite(PIPE_1_RELAY_1, LOW);

  pinMode(PIPE_2_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(PIPE_2_RELAY_2, OUTPUT);
  digitalWrite(PIPE_2_RELAY_2, LOW);

  pinMode(PIPE_3_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(PIPE_3_RELAY_3, OUTPUT);
  digitalWrite(PIPE_3_RELAY_3, LOW);

  pot1StartMillis = millis();
  pipe1StartMillis = millis();
  pipe2StartMillis = millis();
  pipe3StartMillis = millis();
}

void loop()
{
  checkAbstractWateringTimer(pot1SetStartTime, pot1RedFlag, pot1DelayStartMillis,
                                POT_1_DRAIN_PERIOD, POT_1_MAX_WATERING_PERIOD,
                                pot1StartMillis, POT_1_FLOAT_SENSOR, POT_1_RELAY_1);

  checkAbstractWateringTimer(pipe1SetStartTime, pipe1RedFlag, pipe1DelayStartMillis,
                                PIPE_1_DRAIN_PERIOD, PIPE_1_MAX_WATERING_PERIOD,
                                pipe1StartMillis, PIPE_1_FLOAT_SENSOR, PIPE_1_RELAY_1);

  checkAbstractWateringTimer(pipe2SetStartTime, pipe2RedFlag, pipe2DelayStartMillis,
                                PIPE_2_DRAIN_PERIOD, PIPE_2_MAX_WATERING_PERIOD,
                                pipe2StartMillis, PIPE_2_FLOAT_SENSOR, PIPE_2_RELAY_2);

   checkAbstractWateringTimer(pipe3SetStartTime, pipe3RedFlag, pipe3DelayStartMillis,
                                PIPE_3_DRAIN_PERIOD, PIPE_3_MAX_WATERING_PERIOD,
                                pipe3StartMillis, PIPE_3_FLOAT_SENSOR, PIPE_3_RELAY_3);

  delay(200);
}

void checkAbstractWateringTimer(bool &abstractSetStartTime, bool &abstractRedFlag, unsigned long &abstractDelayStartMillis,
                                unsigned long abstractDrainPeriod, unsigned long abstractMaxWateringPeriod,
                                unsigned long &abstractStartMillis, int abstractFloatSensor, int abstractRelay) {
  if (!abstractSetStartTime || (abstractSetStartTime && millis() - abstractDelayStartMillis >= abstractDrainPeriod)) {

    if(digitalRead(abstractFloatSensor) == LOW && !abstractRedFlag) // Need one more condition in order to emulate the delay...
    {
      digitalWrite(abstractRelay, LOW);
      Serial.println("Pot 1 pump is open");

      // Set it only once at the beginning
      if (pot1SetStartTime) {
        abstractStartMillis = millis();
        abstractSetStartTime = false;
      }

      Serial.print("duration ");
      Serial.println(millis() - abstractStartMillis);

      if (millis() - abstractStartMillis >= abstractMaxWateringPeriod)  //test whether the MAX watering period has elapsed
      {
        // Close pump and do not oopen it again. Red Flag...
        Serial.println("Pot 1 pump is closed and the red flag is ON");
        digitalWrite(abstractRelay, HIGH);
        abstractRedFlag = true;
      }
    }
    else
    {
      Serial.println("Pot 1 Pump is closed");
      digitalWrite(abstractRelay, HIGH);
      abstractSetStartTime = true;
      abstractDelayStartMillis = millis();
    }
  }
}

```

Please any ideas, suggestions or tests that I could do are more than welcome in order to create a reliable system.

-- UPDATE -- Both when I was using Raspberry and Arduino I haven't included any resistors between the float sensor pins and the ground. Are there any chances that this is related with the instabilities that I experienced?

Maybe I should add a resistor (10K) between the float sensor pin and the ground?

Thank you

# Answer
> 1 votes
As requested, I've collated my comments into an answer.

How long are the cable runs? Is there any electrically noisy equipment near the cable runs? Consider using some form of galvanic isolation to interface the float sensors to the MCU. Texas Instruments has a great series of videos on the subject of galvanic isolation which discusses inductive, capacitive and optical isolation techniques. Isolate the signals in both directions – both the inputs and the outputs.

For stronger pull-ups you could try 1K resistors, though this will use more current.

Something else to consider is debouncing the float sensor signals either in hardware with a low-pass RC filter or with a software debouncer (which I've put on GitHub).

The relays require 50 to 60 mA drive current but the Arduino pins can only supply 40 mA, so the external power supply is a good idea.

Redundancy, i.e. having multiple sensors for the same measurement, will guard against the loss of a single sensor causing chaos in a critical system, e.g. loss of precious water in a hot climate. You could have 3 float sensors for each water level at different locations, then use a voting system of \>= 2 to take action. The system should also flag when sensors disagree so that someone can investigate the issue. And also route the cables via 3 different paths. This physical separation will guard against a single localised event (e.g. a wayward tractor or lightning strike) damaging all the sensors at the same time.

Also consider the fail-safe mode. For example, this could be to switch off all water valves when sensors disagree and then send an alert to someone and/or sound an alarm.

As your aquaponic farm is outside, consider lightning strike protection such as using TVS diodes on all inputs and outputs.

You could add feedback sensors to the relays to verify whether they have actually responded to the commands from the Arduino to switch on or off, i.e. compare commanded value with FB sensor value. These sensors could be pullup/pulldown resistors.

These additional relay FB sensors and the float sensors could be incorporated into the fail-safe logic. Some examples include:

1. If a relay is on when it's supposed to be off, flag the discrepancy.
2. If it takes 5 minutes to fill a tank and the inlet relay has been on for \>5 minutes, it might be overflowing or dodgy sensors.
3. If the float sensors say a tank is empty, but the inlet relay has been on for \>5 mins, something is wrong, e.g. leaking tank or dodgy sensors.
4. If it takes 10 mins to drain a tank but the float sensors say it's still full after 11 mins, something is wrong, e.g. blocked drain or dodgy sensors.
5. Are inlet and outlet relays on at the same time? Is this a valid condition?

There are many permutations. Happy coding...

# Answer
> 0 votes
thank you for your valuable input. I can say that now the system is stabilized. The source of my issues was a faulty sensor but I have taken into account all advices. For example I separated the signal cables from the power cables that this was one more source of issues, I have introduced the pull up resistors, I have used separate power source for the relay module.

Generally for me ALL the comments from this thread were super important.

Thank you!

---
Tags: arduino-uno, sensors, relay, raspberrypi
---


# Question
Title: 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

# Answer
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.
> 1 votes

---
Tags: serial, esp8266
---


# Question
Title: 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; }

```

# Answer
> 2 votes
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.

---
Tags: sensors, arduino-nano, potentiometer, capacitors
---


# Question
Title: 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.

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

# Answer
> 1 votes
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

---
Tags: esp32, spi, arduino-nano-33-iot
---


# Question
Title: 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);

}

```

# Answer
You don't. The PCF8574 is an IO expander. It doesn't have any provision for PWM. It's either on, or off.
> 3 votes

---
Tags: i2c, esp32, lcd
---