# Question
Title: How to change ArduinoOTA upload timeout?
I'm using `ESP8266WiFiMulti`, `ESP8266WebServer` and `ArduinoOTA` to communicate with my device and perform over-the-air-updates. Everything was working perfectly until I moved the ESP8266 further from the WiFi router. The OTA upload slowed down, which caused upload timeouts after 5 seconds. It fails at a different point each time, usually between 30% and 60%.

How do I increase the OTA timeout to 30 seconds?

Here is the setup code, let me know if you need more:

```
void startWiFi() {
    ESP8266WiFiMulti wifiMulti;
    wifiMulti.addAP(ssid, password);
    wifiMulti.run();
}

void startOTA() {
    ArduinoOTA.setHostname(_hostname);
    ArduinoOTA.setPassword(_password);

    ArduinoOTA.onStart([]() {
        Serial.println("Start OTA");
    });
    ArduinoOTA.onEnd([]() {
        Serial.println("\nEnd OTA");
    });
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
    });
    ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });
    ArduinoOTA.begin();
}

```

# Answer
> 2 votes
The only timeout I can find is in the `espota.py` script itself. That is riddled with such lines as:

```
sock.settimeout(10)

```

You would need to scour that program and change them all.

~~**However**~~

~~ArduinoOTA uses UDP for communication. Because of that it is *unreliable* (yes, that's a technical term). It doesn't have any form of retransmit / retry, so if a packet is lost it's lost for good. No amount of increasing of timeouts will make that packet reappear.
So increasing your timeouts most likely will just make it wait longer before failing.
~~

~~You should consider switching to a more reliable update system which uses TCP instead of UDP - such as downloading an update from a website using `ESP8266httpUpdate`.~~

**Update:**

ArduinoOTA uses a combination of both UDP (to initialise and authenticate the connection) and TCP (to make a "back channel" connection back to your computer) to download the actual binary.

The same still applies: you will need to alter the `espota.py` program to change its timeouts (`sock2` is the back-channel object), but there is also one line in `ArduinoOTA.cpp` that will need to be altered to increase timeouts. Line 294:

```
int waited = 1000;

```

This is not strictly the number of milliseconds to wait for incoming data, but it's not far off - it's a 1 millisecond delay in a loop while looking for incoming data. Increasing that will allow more time for the ESP8266 to wait for data to arrive.

But of course, with an unstable WiFi connection YMMV...

---
Tags: esp8266, wifi, nodemcu, ota
---


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

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

```
#include <Wire.h>

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

#include <Adafruit_NeoPixel.h>

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

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

void setup() {

  Serial.begin(9600);

  Wire.begin();

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

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

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

}

void loop() {
  rainbow(10);
}

void rainbow(int wait) {

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

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

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

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

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

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

  }
}

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

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

  Wire.endTransmission();

  Wire.requestFrom(deviceaddress, 1);

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

  return rdata;
}

```

**ORIGINAL POST:**

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

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

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

Attached is the schematic.

# Answer
# My working details, per-request

## Setup

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

* The code is your code with the near-1 kHz tweak. That said, I believe I also tested it at the default rate and that worked as well. In any case, the images that show the LED changing were taken while that 1 kHz adjustment was made.
* The UNO and Nano are functionally identical for this. They use different serial transceivers which has nothing to do with anything. The Nano will typically have a lower "5V" than the UNO when USB powered owing to the Nano using a diode where the UNO has a FET. Which is unlikely to matter either. They're otherwise the same device so far as the setup goes.
* The 24LC02B uses the same pinout and I2C address and command-sequences as your AT24C16. It is a smaller memory, not that it makes a difference; we're reading from address 0. I did not find I necessary to add external pull-up resistors and it worked, so it seemed unnecessary to add them to demonstrate that it can work since adding them should only improve it's chances for working correctly.
* The LEDs are the Adafruit ADA1643 12 Neopixel Ring. We're both using the first LED of a string, doesn't really matter how long the are. We're only lighting one "pixel" so I just powered it from USB. Have no idea what you're doing there. But for one LED lit, I doubt a difference there would matter much.
* You'll see a resistor connecting SDA at the EEPROM to IN on the addressable LED(s). I put that there in case by some chance the EEPROM could drive SDA low while the addressable LED code was driving the LED data line high. while. I doubt that can happen, but it was a small thing to do. For what it's worth, I did run it briefly without it in series, and it also worked fine that way as well. I'm only telling you this so you have all the information and not because *I* think it matters; I don't.

## Running

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

## Configuration Pictures
> 1 votes

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

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

# Answer
This is just a hacky idea how you could solve this.

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

But there's a different problem: the EEPROM will write to the bus occasionally whenever it receives something that looks like its address. This in turn can

* interfere with WS2812 communication.
* damage the EEPROM's I2C interface if you control the WS2812 with push/pull signal (by setting gpios HIGH/LOW).

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

# Answer
This won't work with 24Cxx EEPROMS.
The I2C bus works this way:

* Master writes out an address.
* Slave takes over the SDA line and pulls it high or low to indicate an ACK or NAK.
* Master writes out a command for reading from an address.
* Again Slave takes over SDA and ACKs the command.
* Master is continuing to pulse SCL while Slave puts out data to SDA.
* After every byte (or word) Master has to take over SDA to confirm the data has been received.

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

---

It might work with 25Cxx EEPROMS.

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

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

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

# Answer
## setClock(1000) Problem

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

Specifically to address this content in your update:

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

And your line:

```
Wire.setClock(1000);

```

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

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

I dug in to see what causes `setClock` to behave poorly for low rates, and there's not a lot to it. The I2C/Wire prescaler is set to divide-by-1 and left that way. `setClock` calls `twi_setFrequency`, which calculates `TWBR` using this expression:

```
TWBR = ((F_CPU / frequency) - 16) / 2;

```

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

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

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

## Suggestion

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

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

```

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

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

---
Tags: eeprom, neopixel
---


# Question
Title: Recommend an Arduino Uno shield to monitor the state of 5 DPDT electrical switches
I have a project where I need to monitor the state of 5 DPDT electrical switches with Arduino Uno. Also, the Arduino board will be measuring the output from 3 thermocouples on 3 of the analogue pins as input and sending signals to open and close 3 relays for heaters on the 3 of the digital pins as output. The data with the state of the microswitches and the measurements from the thermocouples will be send over a serial connection to a PC.

I think I need a shield with at least 20 inputs for monitoring the 5 DPDT electrical switches (5 x 2 x 2). The common of the switches will be connected to a common rail. Can I use an I2C extension shield for this purpose? Is this going to create an issue with the serial connection? Any specific shield recommendations?

# Answer
If you're really set on measuring the state of every single connection of every single switch (though I still don't see the need) then yes, you'll need 20 IO connections.

You could create those with IO expanders (MCP23017 for example), or you could use multiplexing.

Instead of 4x5 (20) IO pins you'd instead need 2+10 (12) IO pins.

Treat all the "Common" connections as the rows of a keypad and all the NC and NO connections as the columns of a keypad. Add a smattering of diodes to isolate everything, and you can then scan through the switches one at a time checking each of the two switch states.

You can read more about keypad matrices here.
> 0 votes

---
Tags: arduino-uno, i2c, switch
---


title: How to use this confing function

text:
# Question
Title: How to use this confing function
For INA3221 current sensor, I found this library, however, I don't understand how to use the `INA3221SetConfig()` function as defined in the .cpp file link.

```
void SDL_Arduino_INA3221::INA3221SetConfig(void)
{

      // Set Config register to take into account the settings above
      uint16_t config =
          INA3221_CONFIG_ENABLE_CHAN1 |
          // INA3221_CONFIG_ENABLE_CHAN2 |
          // INA3221_CONFIG_ENABLE_CHAN3 |
          INA3221_CONFIG_RESET |
          INA3221_CONFIG_AVG1 |
          INA3221_CONFIG_VBUS_CT2 |
          INA3221_CONFIG_VSH_CT2 |
          INA3221_CONFIG_MODE_2 |
          INA3221_CONFIG_MODE_1 |
          INA3221_CONFIG_MODE_0;
      wireWriteRegister(INA3221_REG_CONFIG, config);
    }

```

It seems like the function is called automatically when the `.begin()` function is called and whatever is defined in the config function is written to the register. The use of | operator confuses me. I tried to comment out the some settings to see if it works but it makes no difference. There isn't any documentation so I am in a fix. Could you please tell how can I change the configuration settings e.g. instead of all the three channels or change the config\_mode?

# Answer
> 3 votes
Without looking at the library, you can check yourself if this method (`INA3221SetConfig`) is called from the `begin` method (of the same class). Just trace back the methods manually until you find a call to this method.

About the `|` or 'bit-wise-or' operator (see https://en.wikipedia.org/wiki/Bitwise\_operations\_in\_C), these are used to set bits in a byte/word/long.

Most registers have 8, 16 or 32 bits and with the `|` operator you can easily set multiple bits at the same time. Each value (e.g. `INA3221_CONFIG_ENABLE_CHAN`) has a value that is a power of 2 (mostly defined in the form `1 << ..something..` you can add them (with +) or `|` them together, but | is more clear what the purpose is and repeatedly calling `|` the same bit twice is not a problem (it still gives the same result).

---
Tags: arduino-uno, library, functions
---


# Question
Title: ESP8266: #include <Keyboard.h> causes fatal error: HID.h: No such file or directory
OS: Mac Arduino: 1.8.13 Keyboard Library: 1.0.2

I have a generic ESP8266 board, and I have the following code

```
void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
  Keyboard.begin();
}

void loop() {}

```

However I get the following ouput:

> In file included from /Users/quba/Sandbox/sketch\_feb07a/sketch\_feb07a.ino:1:0:
> /Applications/Arduino.app/Contents/Java/libraries/Keyboard/src/Keyboard.h:25:17: fatal error: HID.h: No such file or directory
> #include "HID.h"
> ^
> compilation terminated.
> exit status 1
> Error compiling for board Generic ESP8266 Module.
> Could not find boards.txt in /Users/quba/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.7. Is it pre-1.5?

# Answer
The Keyboard library is for Arduino ATMega32U4 based Arduinos (and other similar ones with USB) only. The ESP8266 does not have USB, so how can it possibly use the Keyboard library?
> 4 votes

---
Tags: esp8266, keyboard
---


# Question
Title: 4 Pelteir Plate Water Bottle wired to Arduino Uno
Note - I plan to use the Arduino Starter kit to make this project.

Hey everyone,

I've had an idea for a project recently and I would like to get some insight on its plausibility. Is it possible to heat and cool a bottle of water using 4 pelteir plates? I'd like to heat up or cool a bottle of water using 2 pelteirs for heating and 2 for cooling. Could the amount of power for the peltiers to function be supplied from a laptop, computer, or battery pack? The role of the Arduino is to program in some safety features or some things to help the circuit function better if necessary. For example, a feature I want to add in is if the cold pelteirs are on, the hot peltiers are off if nessecary. I might add an LCD to display which setting is on/off if I can (example: Cold: ON, Hot: OFF)

Thanks guys.

# Answer
When it comes for amount of power from laptop, then this is not realy reasonable to expect even USB3, maybe some older laptops PCMCIA, or hardware docks. When it comes to Desk, They would have to be adjusted to get the ATX from PSU (it would have to be upgraded for purpose) We are still talking about a small Can or Yacult botle...
Even then insulate, insulate (and same again)
Then its a question of speed and how hot or cold) Battery pack that charges even when not used, used as buffer might work (for a short time).
Controlling it from Arduino is easy part using function that switches one on other off whenever you want and then calling the function itself to make sure both steps happen, rather then manualy editing or using one output for controlling power on/off and another on two way relay switching between sets (relay would increase consumption here).
> 1 votes

# Answer
In a word, no. Laptop or desktop computer usually have USB ports, which put out like 10 watts of power for a "high current" USB port. That is not enough to do much heating or cooling. You want a high power supply. The pelteir plates I've seen run on 12V DC. Get a 5A 12V supply, or even higher.

You might be able to draw larger amounts of current from a USB-C port or a USB-C power supply, but why? Get a dedicated high current power supply that puts out the maximum voltage your peltier plates can handle.

Note that there is no reason to have 2 plates for heating and 2 plates for cooling. Run the current one way and they heat. Reverse the current and they cool.

Also I'm not sure of the value of using 2 plates to cool. A single plate able to handle more power would likely be more efficient, and easier to insulate. (With 2 plates you'd need 2 heatsinks, which will allow twice as much heat to leak through when the power is off. Doubling the current you feed into a single plate should give double he heating/cooling, without increasing the heat leakage when it's off. Just make sure you don't exceed the maximum rated current of your plate, and that you have a large enough heatsink to handle the heat transfer.)

You could use an H-bridge meant for controlling motors to provide either +12V or -12V under software control. Those generally handle high current.

You could also use a digital thermometer and make a thermostatically controlled system. You'd measure the temp in the bottle, and when it got to your desired temp range, turn off the power. When the temp moved outside the desired range, you'd turn the power back on.
> 1 votes

---
Tags: arduino-uno, power, peltier
---


# Question
Title: RFM95 digital io to control mute on PAM8403 to get rid of hiss while receiving
I am building a solution with an ESP32, a PAM8403 amp, a parallel TFT display, and a RFM95 LoRa module. All works great but I want to get rid of the noise that is generated when Lora is in receive mode.

I can do this by pulling pin 12 low on the PAM8403, which mutes all sound. However I have ran out of output pins on my ESP32, and it's too late to use a IO expander as the PCB has been built.

My initial idea was to use the RX/TX pins on the ESP32 when the unit was out of diagnostics mode. However if I can avoid this then that would be great. In my code when I issue `Lora.sleep() / Lora.idle()` the hissing goes away.

So I started to wonder if I could just trigger the mute function through another logic state that goes low when LoRa is idle and high when sleeping (allowing the mute to deactivate).

I am using the `LoRa` library by Sandeep Mistry, and I was wondering if I could use `DIO1, DIO2`, etc. as an IO PIN to control mute. If not, is it possible to use any of the already connected pins to behave in the desired way?

Thanks all in advance!

# Answer
No, there is no way you can use the DIO pins to indicate sleep mode. They can only be set to indicate certain events, and sleep/idle is not one of them.

However the nRESET pin is optional, and you can use the `setPins()` function in the LoRa library to change which pin it's connected to - and one option is to set it to `-1` in which case the library ignores it (this must be run *before* `.begin()` is called) as it's only used during `begin()` to initially reset the LoRa module.

You could either tie nRESET HIGH (to 3.3V) to never reset it, or couple it with the reset signal of another peripheral so it gets reset at the same time - just be careful with your initialisation order in this case so you don't reset the module after configuring it...
> 2 votes

---
Tags: interrupt, esp32
---


title: LF: flexible scheduler/timer library

text:
# Question
Title: LF: flexible scheduler/timer library
I'm working on a few arduino projects where I've needed a flexible scheduler and/or timer library and was wondering if anyone has a library they recommend?

**Case 1:** I have a sensor that needs to collect observations every hour, but it has a specific measurement sequence:

* Power up/boot (takes about 15 seconds)
* Warm-up for 60 seconds.
* Observe (2 min), collect raw data, generate stats
* Cool-down for 5 min.
* Power off

In this case have a single micro-controller acting as a data-logger that is controlling multiple sensors and writing to an SD card.

**Case 2:** I have an oven that needs to be controlled to a user-specified temperature profile (up say to 6 points of change), i.e.:

* Turn on heater
* Set temperature, 100C and hold for 2 min
* Set temperature, 160C and hold for 15 min
* Set temperature, 250C and hold for 1 hr
* ....
* Set temperature, 100C and hold for 1 hr
* Turn off heater

I'm familiar with non-blocking timers and (in the past) have cobbled together a few simple timers with millis() and some ulong variables. Alas, the complexity and debugging time rapidly grows with the number of dependent timers. Before I sit down and sketch out a class definition, I figured I'd ask what others are using.

# Answer
Some libraries I find good (opinion-based):

* TaskManagerIO: https://github.com/davetcc/TaskManagerIO
    + does a good job at managing events / scheduling things for a certain (system) time, or even repetitively.
    + with that you could e.g. use a `scheduleFixedRate()` API to call a function every 60 minutes. Then starts the power up (I assume asynchronously, by setting a pin or something), and just primes the scheduler with the `scheduleOnce()` API to call another function in 15 seconds. That target function then starts the warmup and schedules the next function / step for 60 seconds into the future, et cetera. It would express the flow very naturally.
* If accurate timekeeping is needed so that it's really every hour, you might want to use an external RTC module. Also depends on the microcontroller you're using, many have a builtin one that you can feed with a 32.768 kHz crystal and thus you don't need an external chip
> 1 votes

---
Tags: library, timers
---


# Question
Title: can't connect paj7620 (gesture detector module) to nodemcu
I'm trying to connect paj7620 to nodemcu micro-controller. I have implemented the following code and it worked perfect on arduino uno. The problem is that I was made to migrate to nodemcu.

Here is my code:

```
/*
 * Copyright (c) 2015 seeed technology inc.
 * Website    : www.seeed.cc
 * Author     : Wuruibin
 * Modified Time: June 2015
 * Description: This demo can recognize 15 gestures and output the result.
 *              You can adjust the reaction time according to the actual circumstance
 *              by modifying "#define GES_REACTION_TIME  500".
 *
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <ESP8266WiFi.h>
#include <Wire.h>
#include "paj7620.h"

/*
Notice: When you want to recognize the Forward/Backward gesture or other continuous gestures, your gestures' reaction time must less than GES_REACTION_TIME(0.8s).
        You also can adjust the reaction time according to the actual circumstance.
*/
#define GES_REACTION_TIME       800
#define GES_QUIT_TIME           1000

void setup()
{
    uint8_t error = 0;

    Serial.begin(9600);
    Serial.println("\nPAJ7620U2 TEST DEMO: Recognize 15 gestures.");

    error = paj7620Init();          // initialize Paj7620 registers
    if (error)
    {
        Serial.print("INIT ERROR,CODE:");
        Serial.println(error);
    }
    else
    {
        Serial.println("INIT OK");
    }
    Serial.println("Please input your gestures:");
    Serial.begin(115200);
  Serial.println();

  // Serial.print("Setting soft-AP configuration ... ");
  // Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");

  Serial.print("Setting soft-AP ... ");
  Serial.println(WiFi.softAP("NODEMCU") ? "Ready" : "Failed!");

  Serial.print("Soft-AP IP address = ");
  Serial.println(WiFi.softAPIP());
}

void loop()
{
    uint8_t data = 0, data1 = 0, error;

    error = paj7620ReadReg(0x43, 1, &data);             // Read Bank_0_Reg_0x43/0x44 for gesture result.
    if (!error)
    {
        switch (data)                                   // When different gestures be detected, the variable 'data' will be set to different values by paj7620ReadReg(0x43, 1, &data).
        {
            case GES_RIGHT_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_LEFT_FLAG)
                {
                    Serial.println("Right-Left");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Right");
                }
                break;
            case GES_LEFT_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_RIGHT_FLAG)
                {
                    Serial.println("Left-Right");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Left");
                }
                break;
                break;
            case GES_UP_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_DOWN_FLAG)
                {
                    Serial.println("Up-Down");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Up");
                }
                break;
            case GES_DOWN_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_UP_FLAG)
                {
                    Serial.println("Down-Up");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Down");
                }
                break;
            case GES_FORWARD_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Forward-Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                break;
            case GES_BACKWARD_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Backward-Forward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                break;
            case GES_CLOCKWISE_FLAG:
                Serial.println("Clockwise");
                break;
            case GES_COUNT_CLOCKWISE_FLAG:
                Serial.println("anti-clockwise");
                break;
            default:
                paj7620ReadReg(0x44, 1, &data1);
                if (data1 == GES_WAVE_FLAG)
                {
                    Serial.println("wave");
                }
                break;
        }
    }
    delay(100);
}

```

```
------------------------
|paj7620    | nodemcu  |
------------------------
| VCC       | 3.3v     |
------------------------
| GND       | GND      |
------------------------
| SCL       | D1       |
------------------------
| SDA       | D2       |
------------------------

```

After connecting the ports like the above table, I get the following error when I am trying to upload the code on nodemcu.

Would someone help me how to resolve this error?

**Wiring**

**PS** I have also tried I2C Scanner as @timemage mentioned in comments.

**PS 2** It works properly when I connect the paj7620 to arduino compiling the above code.

**output:**

# Answer
> 1 votes
Special thanks to @timemage for his support. After struggling with the board for more than 6 hours it works properly. I will describe and give more details about how the problem was solved later on.

Arduino Uno has 5 Analog inputs, while there isn't any of them on nodemcu. To connect paj7620 to nodemcu, it is noticable that as @timemage said:

> "The A4 and A5 on the UNO are where the ATMega328P's I2C bus signals happen to be. Earlier versions of the Arduino UNO and related boards didn't have dedicated SDA and SCL headers as they do now. On those UNO that have SDA and SCL pins on the upper digital header, they are the same exact signal as those found on A4 and A5."

So the first schema was correct.

As it is implied from the fifth page of this link there isn't any difference among 3.3v inputs on nodemcu. But I have changed wiring like the following image and it works!

```
#COLOR MAPPING
RED: VCC - 3.3v
BLACK: GND
ORANGE: SCL - D1
GREEN: SDA - D2

```

I hope it helps, cause there isn't any way to trace the problem. :)

# Answer
> 0 votes
You've gotten rather quiet over there since I suggested zooming in on your sensor board. Just so this question doesn't circulate around in the system for years, here's *an* answer:

Your soldering should closer to this. Hopefully better, as these are ones I did:

The solder short of sort web-up the sides of the pins. The use the term "fillet" for that. Where your pads around the through-hole looks broader than the ones that are on the board above, it should probably look a bit better. **There shouldn't be unfilled parts of the through-hole**, in any case. At least not on the side you're soldering.

I expect it will at least show in the I2C scanner when you fix that. It *may* show a different address from what is default in the library, in which case you may need to tell it to use the address that shows in the scanner.

---
Tags: nodemcu
---


# Question
Title: [SOLVED]Normalization not working on input buffer. How to solve this?
I wrote a piece of code that takes input from a sensor which is called the World Famous Pulse Sensor from Analogue Pin 1 and stores it in an Array with 127 elements then finds the largest in it, divides the rest by the largest, multiplies by 64 which is the maximum y length on my OLED and prints it onto the OLED. It still gives me pre-normalized and scaled values on Serial Plotter.

What am I doing wrong? Here is my code.

```
#include <U8glib.h>
U8GLIB_SSD1306_128X64 u8g(12, 11, 8, 9, 10);
int x, y;int Buffer2[128];
void pageBP();
const int pageCount = 1;
int p;
void (*pages[pageCount])() = {pageBP};
int duration [pageCount] = {1000};
void setup() {

  u8g.setFont(u8g_font_unifont);
  u8g.setColorIndex(1);
  p = 0;
  Serial.begin(9600);

}

void loop() {

u8g.firstPage();
  do {
    (*pages[p])();
  } while( u8g.nextPage() );
  delay(duration[p]);
  p = p+1;
  if (p == pageCount)
    p=0;
}

void pageBP() {
  for(x = 0;x < 128;x++) {
Buffer2[x] =(analogRead(A1)>>2);//IP for PPG
Serial.println(Buffer2[x]);
delay(5);
}
for(int i = 1;i < 128; i++)
    {
       if(Buffer2[0] < Buffer2[i])
           Buffer2[0] = Buffer2[i];
    }
    for(int i = 1;i < 128; i++)
    {
       64*(Buffer2[i]/Buffer2[0]);
    }
  for(x = 0;x < 127;x++) {

u8g.drawLine(x, Buffer2[x], x, Buffer2[x+1]); //OP to OLED for ECG

u8g.drawLine(64, 0, 64, 63);
u8g.drawLine(0, 32, 128, 32);}
for(x=0;x<128;x+=8)
u8g.drawLine(x, 31, x, 33);
for(x=0;x<64;x+=8)
u8g.drawLine(63, x, 65, x);
u8g.drawFrame(0, 0, 128, 64);
}

```

Here is Garbage Graph.

# Answer
I will point out some problems with your code:

* Look at this line:

```
  64*(Buffer2[i]/Buffer2[0]);

```

It doesn't do anything. You calculate a scaled value, but you are not saving it anywhere. You need to assign that value to a variable (like an element in a new array).
* With this code

```
  for(int i = 1;i < 128; i++)
  {
      if(Buffer2[0] < Buffer2[i])
          Buffer2[0] = Buffer2[i];
  }

```

You are overwriting the first value in your buffer to find the highest value. That might not be a problem for you, but to be clean here, you should just use a new variable, that holds the highest value outside of the buffer.
* I'm not sure what you are trying to do with this line:

```
  u8g.drawLine(x, Buffer2[x], x, Buffer2[x+1]);

```

Normally, you would want to draw a line from one point in the graph to the next. So the second x parameter would need to be the x value for the next point. Currently you are just drawing a vertical line. I would instead write

```
  u8g.drawLine(x, Buffer2[x], x+1, Buffer2[x+1]);

```

since you already are only counting to 127 instead of 128.
* Even if you get the above right, the Serial Monitor would still show the unscaled values, since you are printing to Serial directly after measuring. So to display the scaled values in the Serial Monitor, you need to move the line

```
  Serial.println(Buffer2[x]);

```

down to after the scaling, for example in the same for loop as the OLED display code.
* And finally you should really fix your indentation. That will make your code way more readable and thus better understandable. The Arduino IDE even has an autoformat feature, that you could use for that.
> 2 votes

---
Tags: arduino-nano
---


# Question
Title: analogRead() doesn't read more than 500Hz
I connected a wave generator to the analog pins to read the frequencies of the waves generated. I used different frequencies of sine waves with a minimum of 0V and maximum of 5V.

Whenever the voltage is greater than 2.5V, I made one of the digital pins HIGH, and LOW when less than 2.5V. Now by measuring the square wave from the digital pin, it always has the same frequency as the sine waves until 500Hz.

After 500Hz, the square wave's frequency doesn't agree with the sine wave, which made me think that the problem is in the `analogRead()`. Is there a way to have higher frequency?

Code:

```
const int sensorPin1 = A0;
const int sensorPin2 = A1;
const float maximumPower = 2.5;
int calibration = 1;

void setup() {
  Serial.begin(57600);
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
}

void loop() {
  int voltage2 = 3;
  int voltage1 = 3;
  int sensorVal = abs(analogRead(sensorPin1) - analogRead(sensorPin2));
  float ratio = abs(analogRead(sensorPin2) / analogRead(sensorPin1));
  float voltageDifference = (sensorVal / 1024.0) * 5.0;
  float power = calibration * voltageDifference;
  if (power >= maximumPower || voltage1 <= 1 || voltage2 <= 1) {
    digitalWrite(6, LOW);
  }
  else {
    digitalWrite(6, HIGH);
  }
}

```

# Answer
You have 4 calls to `analogRead()` in your loop. At about 112 µs per call, that's already taking 448 µs. Add to that the time taken by the floating point calculations, and you are likely to end up with something in the order of 500 µs per loop iteration. This should give you a sampling rate close to 2 kHz, which should allow you to detect the highs and lows of an input signal up to 1 kHz, provided the duty cycle is close to 50%.

There are a couple of easy optimizations that could be done here. Two of the calls to `analogRead()` serve no purpose, as the results are never used. And the floating point calculations are also pointless. The whole loop can be simplified to this:

```
void loop() {
    if (abs(analogRead(A0) - analogRead(A1)) >= 512) {
        digitalWrite(6, LOW);
    } else {
        digitalWrite(6, HIGH);
    }
}

```

This should take about 224 µs per iteration. If you need to go faster, you will have to increase the working frequency of the ADC. This can cost some accuracy, but if accuracy is not critical to your application, it can be a good trade-off. See Nick Gammon's page on the Arduino ADC for details. If that's not enough, you will have to use external components, e.g. an analog subtractor made from an op-amp, and a couple of comparators.
> 2 votes

---
Tags: analogread, frequency, digitalwrite, analog
---


# Question
Title: confirming this will blink LED at given frequency
I want to blink an LED at an specific frequency, ie: 7Hz

here what Im doing

```
int ledPin = 4;
float freq = 7;

void setup() {
  pinMode(ledPin, OUTPUT);
}

float periodo() {
  float peri = 1/freq;
  float halfer = peri/2;
  float millisec = halfer*1000;
  return millisec;
  //return ((1/freq)/2)*1000;
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(periodo());
  digitalWrite(ledPin, LOW);
  delay(periodo());
}

```

Is this correct? is that the best way to do it?

thanks in advance!

# Answer
You can check if it is correct by timing it for one minute and check if it is (approximately) ok.

However, I see a few improvements:

* First is that you always return 1/7/2\*1000 = 71.429, which is rounded down to 71. 71 * 14 = 994 ms so you get a bit faster speed than 7 Hz. if this is a problem you have to compensate for this.
* Another small problem is that you `delay`, but the `digitalWrite` commands also take some time which is not included for the delays. So you need also to take this into account when using a precise delay.
* When using floats I always use float constant numbers, like 1.0 and 7.0 instead of 1 and 7. This can especially be useful when you divide two integers (e.g. 1/7), which results in 0.14 this is rounded down to 0 as it is an int.

The best you can do is using the `millis` command. You keep a timer and compare it to the current `millis` value. If it is too high, do a state change. This will take into account every other method you do meanwhile the `digitalWrite`s.

Something like: (code fixed due to EdgarBonet's remarks)

```
const float FREQ = 7.0; // Hz
const int PIN_NR = 4;

unsigned long _startTime;
unsigned long _counter;

int _currentState = LOW;

void setup()
{
  _startTime = millis();
  _counter = 0;
  _currentState = LOW;
  digitalWrite(PIN_NR, _currentState);
}

void loop()
{
  if (_startTime + _counter * 1000.0 / FREQ / 2.0 >= millis())
  {
    _counter++;
    _currentState = ~_currentState;
    digitalWrite(PIN_NR, _currentState);
  }
}

```

Some small notes:

* \_currentState is the current state of the LED, with ~ you can flip it (it's called the `not` operator).
* \_startTime is the (close to zero) value of the `millis` value at startup.
* Take in mind there is a limit how long this app can run or precise. `millis` works with ms, meaning you cannot get beyond 500 Hz, and you get 'approximations' with frequencies below in some cases. E.g. when Freq = 80 Hz, you get 1000 * 1 / 80 / 2 = 1000 / 160 = 6.25 =\> 6, which is actually 1000/6/2=83.3 Hz.
* Also the counter is added once per state change, and because of 1000 * \_counter ... an overflow exists when \_counter \>= 256 * 256 * 256 * 256 / 1000 = about 4 million. With 1000 state changes per second, this happens after 4000 seconds, which is 66 minutes. For 7 Hz it will not occur fast.
> 2 votes

---
Tags: programming, led
---


# Question
Title: Arduino IDE - scope of the pre-processor "#define"
I'm creating an Arduino library and have 3 files - a "test.ino" program, and two library/class files: "testLibrary.h" and a "testLibrary.cpp".

The library makes use of some hardware-specific resources such as registers and ISRs that depend upon which I/O pin is used, and this should be done at compile time.

I would like to *#define* a pin number in the main program which, at compile time, is used in the library to determine which code sections are activated. Since this will be a standard Arduino library for use by others, it should compile and run without users having to change their compiler or *#include* path to make it work.

But it seems that the scope of *#define* in the main program/sketch does not extend to the library.

test.ino

```
#define PIN_NUMBER 3
#include "testLibrary.h"
void setup() {}
void loop() {}

```

testLibrary.h

```
#ifndef _TESTLIBRARY_h
#define _TESTLIBRARY_h
#ifndef PIN_NUMBER
#error PIN is not defined
#endif
class test {
public:
  test();
  ~test();
};
#endif

```

testLibrary.cpp

```
#include "testLibrary.h"
test::test(){}*
test::~test(){}

```

Compiling the above branches to "#error" using the Arduino IDE 1.8.13 and also using Visual Studio with Visual Micro.

Is there a way for me to have an Arduino library use a "#define" from the main sketch?

# Answer
> 2 votes
The scope of a `#DEFINE` macro is the translation unit. That is the current `.c` or `.cpp` file that is currently being compiled.

In you code `PIN_NUMBER` is defined in `test.ino`. The `#include` macro literaly copies the content of `testLibrary.h` into `test.ino`. So for the compiler this is working perfectly fine as `PIN_NUMBER` is defined.

Your `testLibrary.cpp` however is not happy with that. Including `testLibrary.h` for compilation lacks the definition of `PIN_NUMBER`.

The Arduino IDE is very limited and does not offer you a way to define `PIN_NUMBER` globally. This is usually done with the compiler argument `-DPIN_NUMBER=3`. All translation units will get this argument and thus the compilation would succeed. No need to define `PIN_NUMBER` in code.

---
Tags: library, compiler
---


# Question
Title: I2C_anything from Nick Gammon. Value of two senders to be received and printed by receiverslave
Following the suggestion of Fiendish to post here: Hello

Nick, thank you very much for this I2C-anything library that works a treat with two arduinos (one sender, one receiver).

Is there any suggested method or at least an example sketch of having two different sender arduinos send their floats to the receiver e.g. by alternating slave adresses in the receiver loop? With a simple re-insertion of the section (but with a different address) into the receiver sketch restarting with Wire.begin() and then Wire.begin(new address) things are botched up.

In addition: if I define -float f in sender A- and -float e in sender B- the receiver keeps on printing the float e value in the serial.Print ("float value e"); serial.println(e); -postion, no matter if I swap from Sender A to sender B -by changing the SCL/SDA connections, and the serial.Print ("float value f");serial.println(f); prints fancy numbers.

If at least the swapping would cause the floats to be printed in the correct position I could maybe switch the respecive senders I2C down in turns....

Of course hotplugging /hotswitching SDA and SCL from senders causes the senders sketch to be blocked at times.

The idea of sending data from Sender B to Sender A, and from Sender A to to receiver left me frustrated the last few hours, due to the fact that Im a total noob and/or that its simply not possible to have two masters send to one slavereciver without running into i2C conflicts. Unless some unknown acrobatics is performed.

The ultimate idea is to have two separate megas (with i2c sensors attached to them) execute feedbackloops and still be able to transfer these values and other values to a display via I2C. the alternate way could be that a dac is used to translate the I2C values into voltages that hardware....)

Any help greatly appreciated Best Daniel

# Answer
Dear Chrisl and Sim Son

Please accept my apologies for not replying earlier, am still recovering form a timbering accident and have limited painless access to my laptop.

thinking in boxes: BOX 1 = Arduino Mega number one regulates the pressure of proportional valves (via I2C conected quaddac MCP4728 to 0-10V) based on the flowvalues of 4 I2C-connected FLowsensors.

BOX 2= Arduino Mega number two does the same with a second set of 4 flowsensors and 4 analog proportional valves.

Splitting this to two arduinos was originally because a) i was unable figure out how to get 2 DACS on the same I2C line and handle the LDAC address fiddling which turned out to be a good approach because the total number of required GPIO pins exceeds the available number of pins of one Mega (many rotary encoders attached, TTL signal delayer for 8 channels, pots to set values, status LEDS.

Both arduinos are supposed to send the values for the flow-setpoints, actual pressure values, actual flow values, other sensor data to a third arduino MEGA =BOX 3 that displays all kind of things on a large TFT. (for what its worth, this third Mega has some inputs from a different set of other I2C sensors that basically provide TTL signal outputs, if event-criteria have been met. the latter TTL are fed back to the first two arduinos to provide decision criteria in if loops)

So, i learn from you that the multimaster approach unlikely to be fun at all, especially given my limited knowledge and loathing /ignorance to handle and send strings. You will at least laugh at me now but i saved quite some time the on day i wrote to you by simply translating all the flow etc values of BOX 1, Box 2-Ardinos (pressures, flowsetpoints and actual flow values into voltages with the help of additional multiplexed DACs, then I pick up the the voltages with I2C-ADCs hooked to the Arduino with the SPI-display (BOX 3) that in turns translates into the true values and prints to the TFT. Any delay and inprecision at the displays side is acceptable so far, analog value fluctuation has been smoothed, the additional hardware is no issue at this stage of the project.

I am sorry that his original issue regarding I2C led me astray to oldfashioned analog data processing

BUT: if you have any hints or pointers to libraries as how two arduinos that act already as I2C Masters can send their data (a bundle of floats) via UART/RXTX, or any other bus to a receiver that handles these as printable variables: more than welcome, i will try to keep abreast of what you suggest.

Best Daniel
> 0 votes

---
Tags: i2c
---


title: Alternatives to Nextion display

text:
# Question
Title: Alternatives to Nextion display
I am wanting to have a display where I can design the GUI on a program and then somehow transfer it to the display. For the graphics I want to make, it would be really hard to manually write the code. I heard that the Nextion displays do this but they are quite costly. Is there some cheaper alternative? If not, can you make a normal display do all of that?

# Answer
We work with Proculus displays, and we are a distributor of this display here in Brazil (Victor Vision). The display is great, very professional. Used in medical equipments, and cheaper than Nextion. They are starting now in the web and selling in Alibaba.
> 3 votes

---
Tags: programming, arduino-ide, library, display, tft
---


# Question
Title: How to wire and control a 16mm button with 2 legs using arduino?
I can't find any tutorials online explaining how to wire and control a 16mm push button like the one in the picture:

Do you have any suggestions as to how use it with an arduino or a raspberry pi?

# Answer
> 1 votes
A pushbutton is a pushbutton. It is a momentary switch. Since it has flexible wires, and needs a place to mount, you should probably wire it using a breadboard.

That pushbutton looks like a panel mount pushbutton. You might want to mount it in a pice of plastic or sheet metal. (Unscrew that nut up by the red part that you press. Measure the outside diameter of the threaded part. Drill a hole ≈1/64" (≈0.4MM) bigger than the switch diameter into the plastic/metal. Insert the pushbutton from underneath the panel. screw the nut back on to secure it. Tighten moderately tight with needle-nose pliers, being careful not to round off the corners of the nut.

To wire it:

Get a breadboard. Run wires from your Arduino to the breadboard.

Wire the pushbutton into the breadboard as well.

There are various libraries that offer switch debouncing, or you can write your own fairly easily.

I suggest using INPUT\_PULLUP mode, and wiring your switch between an Arduino digital input and ground. When the switch is open, the input will read HIGH. When you press the the switch, the input will drop to LOW.

If you want to debounce the switch input yourself: When the switch changes state, note the value of `millis()`, and ignore any new changes for a brief period (try 20-100 mS).

---
Tags: arduino-uno, button, raspberrypi
---


# Question
Title: What is touch_pad_get_status() supposed to return?
What I want to do: I have 7 touch buttons on my board (ESP32 TTGO T-Display) and I want to attach interrupts to everyone, calling the same function. In this function I would like to use touch\_pad\_get\_status() or other to get which button was touched. Then a switch case would do the rest.

What I'm facing: This code

```
  Serial.print("Button ");
  uint32_t touch = touch_pad_get_status();
  Serial.println(String(touch));

```

always returns 0, no matter what.

What I've tried: Including this part of code to the setup

```
  touch_pad_init();
  touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); //tried the SW MODE too
  touch_pad_io_init(TOUCH_PAD_GPIO15_CHANNEL);

```

But nothing seem to work. I don't want to make 7 different functions...

Thanks in advance.

# Answer
> 4 votes
As pointed out from people in the comments, things need to be different. If you use the function `touchAttachInterrupt`, things are a bit simpler. The example that comes with the ESP32 library is enough to make you understand.

If you want to do what I did, this is how:

```
  touch_pad_init();
  touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
  touch_pad_config(TOUCH_PAD_GPIO2_CHANNEL, 500);
  touch_pad_config(TOUCH_PAD_GPIO15_CHANNEL, 500);
  touch_pad_config(TOUCH_PAD_GPIO13_CHANNEL, 500);
  touch_pad_isr_register(TouchButton, NULL);
  touch_pad_intr_enable();

```

Put this code in the `setup()`. Of course needs the `init()`, but also needs to be set to timer mode, or otherwise you're going to need to `start()` probably. The `config()` is to configure the pin as an interrupt. I've set 500 in the threshold because the readings of `touch_pad_read()` told me it went from 800 untouched to 50 touched, so the midterm I chose 500. `isr_register` is the function that tells to call `TouchButton()`, with `NULL` as argument to it.

```
void TouchButton(void *arg)
{
  uint32_t touch = touch_pad_get_status();
  touch_pad_clear_status();
  Serial.print("Button ");
  Serial.println(String(touch));
}

```

This is the declaration of the callback function I've done. It should be noted that `clear_status()` should be called as soon as possible after the `get_status()`, preventing the system from panicking (that's the name). You'll also see in the serial monitor that each button represents a power of 2. That's because the `get_status()` returns the pin mask in binary. So just do something similar to this

```
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
    if ((pad_intr >> i) & 0x01) {
        s_pad_activated[i] = true;
    }
}

```

and you'll get a vector of which one was pressed.

---
Tags: functions
---


# Question
Title: Arduino measuring high-voltage electric fence
I would like to know if someone has experience with measuring high voltages using an Arduino.

I know you can use resistors to lower the voltage, however.

I want to be able to measure the pulses of an electric fence used to prevent farm animals from escaping. These pulses are high-voltage and will not always be a similar voltage. I want to read these voltages, to scan for differences.

So, I wondered if someone has done something like that, and if the Arduino gets weird when it gets a voltage above 5 V at a low amperage on its analog port.

--here some possible solutions for those wanting to know the answer-- -mostly based on comments and answers below-

* Using resistors as a voltage divider while keeping an eye on the maximum spark gap distance and capacitive coupling.
* using a transformer/coils to reduce the voltage.
* using a high voltage probe to measure it.
* using neon bulbs or other light sources to measure it.
* charging a capacitor and measuring discharge time with high resistance(only works for the total power)

-this list is meant as a summary of what is discussed further ideas and solutions are still welcome-

# Answer
You are talking about measuring 2 to 10 kV pulses, with about 1 to 5 J of energy per pulse.

The maximum current may be very low, but the voltages you want to measure are very high, and will very probably damage your Arduino without proper measures.

You will at least need a voltage divider to reduce the voltage the Arduino sees to 5 V (or 3.3 V for some Arduinos) to be able to make a measurement with the Arduino's ADC.

The voltages are high enough to bridge a fair distance with a spark; they could well bridge a physically small resistor or the distance between two connections on your breadboard or PCB.

To be honest, I think you shouldn't go anywhere near such voltages with an Arduino, unless you know exactly what you are doing when preparing the signal for an Arduino's ADC pin.
> 4 votes

# Answer
When you say 'scan for differences', do you mean differences along the fence, or something else? Do you plan to use the Arduino as a portable voltmeter? If so, buying a HV probe for a standard voltmeter sounds a lot more practical.

However, if you plan to install multiple sensor points along the fence so that you can continually monitor pulse amplitudes along the fence, then that is a different kettle of fish, especially if you are thinking about outdoor use over a long fence length.

Can you elaborate a bit, please?
> 0 votes

---
Tags: analogread, voltage, analog
---


# Question
Title: Difference between char array and unsigned char array
I have written a small test code for Arduino Uno which is as follows:

```
unsigned char tes[4];
char testing[4];

void setup() {
    Serial.begin(9600);
    for (int i = 0; i < 4; i++) {
        testing[i] = i;
        tes[i] = i;
    }
    for (int i = 0; i < 4; i++) {
        Serial.print("unsigned char is: ");
        Serial.println(tes[i]);
        Serial.print("char is: ");
        Serial.println(testing[i]);
    }
}

void loop() {
}

```

and the output which I get is as follows

```
unsigned char is: 0
char is:
unsigned char is: 1
char is:
unsigned char is: 2
char is:
unsigned char is: 3
char is:

```

Can someone help me out why is the difference in output.

# Answer
***tl;dr : Since unsigned char is represented as a byte value, the output to the serial is the byte representation, not the char***

I re-wrote the code you had for reference:

```
#define CHARS 255
#define BAUD 115200

unsigned char unsChar[CHARS];
char sinChar[CHARS];

void setup() {
  Serial.begin(BAUD);
  Serial.println("~~Setup~~");
  for(int i = 0; i < CHARS; i++) {
    unsChar[i] = (unsigned char)i;
    sinChar[i] = (char)i;
  }
}

void loop() {
  Serial.println("~~Loop~~");
  for(int i = 0; i < CHARS; i++) {
    Serial.print("INDEX        : ");
    Serial.println(i);
    Serial.print("unsigned char: ");
    Serial.println(unsChar[i]);
    Serial.print("         char: ");
    Serial.println(sinChar[i]);
    Serial.println("---------------------");
  }
  delay(10000);
}

```

When you run this you'll see the `unsigned char` is simply printed to the serial like any other `byte` value but the `char` value is printed as a character according to the ASCII chart.

If you compare the documentation for `unsigned char`

> **An unsigned data type that occupies 1 byte of memory**. Same as the byte datatype.
> The unsigned char datatype encodes numbers from 0 to 255.
> For consistency of Arduino programming style, the byte data type is to be preferred.

versus a normal (signed) `char`:

> A data type used to store a character value. Character literals are written in single quotes, like this: 'A' (for multiple characters - strings - use double quotes: "ABC").
> Characters are stored as numbers however. You can see the specific encoding in the ASCII chart. This means that it is possible to do arithmetic on characters, in which the ASCII value of the character is used (e.g. 'A' + 1 has the value 66, since the ASCII value of the capital letter A is 65). See `Serial.println` reference for more on how characters are translated to numbers.
> **The size of the char datatype is at least 8 bits.** It’s recommended to only use char for storing characters. For an unsigned, one-byte (8 bit) data type, use the byte data type.

So size wise an array of chars and unsigned chars are going to be the same. It's more about the representation of the underlying number (byte) and what works best for your use case.
> 2 votes

# Answer
An unsigned char is treated as a number, and a signed char as a character. See the https://simple.wikipedia.org/wiki/ASCII table for the result.
> 0 votes

---
Tags: arduino-uno, arduino-mega, c++, c
---


# Question
Title: Configure input pullup through registers
I can set pin mode to input or output through the DDRx registers. How can I enable the internal pullup resister through a register?

# Answer
> 2 votes
Credits to GoForSmoke. Also see Gerben's comment below.

See: https://forum.arduino.cc/index.php?topic=286145.0

```
byte ddrcMask =       ~
(
        (1 << DDC0) |  // pinMode( 14, INPUT ); // Set to input
        (1 << DDC1) |  // pinMode( 15, INPUT ); // Set to input
        (1 << DDC2) |  // pinMode( 16, INPUT ); // Set to input
        (1 << DDC3)    // pinMode( 17, INPUT ); // Set to input
);

byte portcMask =
(
        (1 << PORTC0) |  // digitalWrite( 14, HIGH ); // Enable the pullup
        (1 << PORTC1) |  // digitalWrite( 15, HIGH ); // Enable the pullup
        (1 << PORTC2) |  // digitalWrite( 16, HIGH ); // Enable the pullup
        (1 << PORTC3)    // digitalWrite( 17, HIGH ); // Enable the pullup
);

byte pincMask = ( (1 << PINC0) | (1 << PINC1) | (1 << PINC2) | (1 << PINC3) );

void setup( void )
{
  // Configure the pins for input
  DDRC = DDRC & ddrcMask;

  // Enable the pullups
  PORTC = PORTC | portcMask;

  // Read all four inputs
  uint8_t Pdat = PINC & pincMask;
}

void loop( void )
{
}

```

---
Tags: arduino-uno, port-mapping, pull-up
---


# Question
Title: How to make Arduino react to serial information?
I want to write a program that allows me to control the LED connected to pin 13 of the Arduino. When the program is started, the LED should be off. The user should open the serial monitor to communicate with the Arduino. If the user sends the character '1' through the serial monitor then the LED should turn on. If the user sends the character '0' through the serial monitor then the LED should turn off.

So I tried:

```
void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  int bytenum = Serial.available();
  if (bytenum != 0)
  {
    int bval = Serial.read();
    if (bval != 0)
    {
        digitalWrite(13, HIGH);
    }
  }
  digitalWrite(13, LOW);
}

```

But when launching it the LED never light up:

# Answer
I see two issues:

**1. Sketch**

The line:

```
digitalWrite(13, LOW);

```

is always executed, meaning the LED (which might be broken, see below), is on for a very small time, probably not enough to be visible.

You can use the next sketch (for 0 and 1 to switch it off/on):

```
const uint8_t LED = 13;

void setup()
{
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop()
{
  while (available_characters != 0)
  {
    switch (Serial.read())
    {
      case '0':
        digitalWrite(LED, LOW);
        break;

      case '1':
        digitalWrite(LED, HIGH);
        break;

      default:
        // Ignore
        break;
    }
  }
}

```

You can make this sketch smaller in case you want '0' for off, and anything else for on:

```
const uint8_t LED = 13;

void setup()
{
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop()
{
  while (Serial.available() != 0)
  {
    digitalWrite(LED, Serial.read() == '0' ? LOW : HIGH);
  }
}

```

**2. Lack of a resistor**

I think your LED is now broken, and hopefully only the LED and not your Arduino.

Always use a resistor just before or after the LED when connecting a LED. As a guideline, use e.g. 220R or 330R.

Remember as formula: V = I * R

The tricky thing is that LEDs have a forward voltage (Vf), so the actual formula is:

```
 (V - Vf) = I * R

```

Now most LEDs can handle mostly 20 mA, but 10 mA is more than enough to make them bright.

Below is a list of typical values for the forward voltage. Let's assume it's 1.8V as you are using a red one in your example.

The MINIMUM resistor value to be used is:

```
(5 V - 1.8 V) = 0.01 A * R <=>
3.2 V = 0.01 A * R <=>
R = 320 ohm

```

So use a 330 ohm resistor. (note that 220 ohm will still result in less than 20 mA).
> 0 votes

---
Tags: arduino-uno, serial, programming, led
---


# Question
Title: UNO R3 + WiFi ATmega328P+ESP8266 (32Mb memory) USB-TTL CH340G For Arduino Uno - External ESP8266 Pins
This board have pins to ESP8266's GPIOs.

What is `Tout` pin ? On the back of the board it label pins :`GPIO12`, `GPIO02`, and **another** `GPIO02` ? a continuity test shows that they are not connected. So what is it ?

# Answer
From esp8266 datasheet:

> TOUT - ADC pin. It can be used to test the power-supply voltage of VDD3P3 (Pin3 and Pin4) and the input power voltage of TOUT (Pin 6). However, these two functions cannot be used simultaneously.

from the pinout PDF of the Uno+WiFi board:
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Serial Monitor stops working when using PinMode
I'm having a lot of trouble with my recent Arduino sketch. I need to reset an IC by setting a pin high then low. I also am using the serial monitor for some testing but as soon as I try and do a Serial.print, nothing appears. My Arduino is also on a custom PCB, where D7 is connected to the IC's (MAX3421) reset pin, and also to the Arduino's reset pin. To try and make my issue clearer, ill post some code and the serial monitor output below:

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

  pinMode(7, OUTPUT);
}

void loop()
{
  Serial.println("TEST");
}

```

\[nothing in serial monitor\]

---

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

  //pinMode(7, OUTPUT);
}

void loop()
{
  Serial.println("TEST");
}

```

\[lots of TESTs\]

Any help is appreciated, Thomas

# Answer
> 1 votes
My issue was that pin 7 was connected to the reset pin on the Arduino, meaning every time it was set to output, the Arduino was reset. You can see this here:

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

  Serial.println("a");

  delay(100);

  pinMode(7, OUTPUT);
}

void loop()
{
  Serial.println("test");
}

```

which outputs a stream of a's separated by 100ms (plus a bit)

---
Tags: arduino-uno, serial
---


# Question
Title: SSD1306 unable to display Text and waveform cohesively.Why?
Here is my code I am collecting data using an ECG sensor and trying to enhance the incoming data by stretching it across the x axis. Which results in this.

After this the screen eventually just goes black. What am I doing wrong? This is my code.

```
#include <U8glib.h>
U8GLIB_SSD1306_128X64 u8g(12, 11, 8, 9, 10);
int Buffer[128];int Buffer2[128];int max=0;
//int largest;
void pageECG();     // Page-1

const int pageCount = 2;
int p;
void (*pages[pageCount])() = {pageECG};
int duration [pageCount] = {10000};
void setup() {

  u8g.setFont(u8g_font_unifont);
  u8g.setColorIndex(1);
  p = 0;
  Serial.begin(9600);

}

void loop()
{
u8g.firstPage();
  do {
    (*pages[p])();
  } while( u8g.nextPage() );
  delay(duration[p]);
  p = p+1;
  if (p == pageCount)
    p=0;
}
void pageECG() {
for(int x = 0;x < 128;x++)
{
Buffer[x] =(analogRead(A0)*0.075);//This loop takes data input
delay(5);
if(Buffer[x]<32&&Buffer[x]!=2)
x-=2;
if(Buffer[x]>32&&Buffer[x]!=62)
x+=2;
Serial.println(Buffer[x]);
}

for(int x = 0;x < 127;x++)
{
u8g.setFont(u8g_font_unifont);
u8g.drawStr( 0, 60, "ECG");
u8g.drawLine(x, Buffer[x], x,Buffer[x+1]); //OP to OLED for BP

}}

```

# Answer
Well, one problem is this: You have made an array of pointer to function, but only initialized the first of the two, to `pageECG`.

```
const int pageCount = 2;
int p;
void (*pages[pageCount])() = {pageECG};

```

The last line there roughly equivalent to:

```
void (*pages[pageCount])() = {pageECG, nullptr};

```

Later in `loop()` you have:

```
  u8g.firstPage();
  do {
    (*pages[p])();
  } while( u8g.nextPage() );
  delay(duration[p]);
  p = p+1;
  if (p == pageCount)
    p=0;

```

After the first execution of `loop()`, `p` is 1. Since it was not 2, it was not reset by your `if (p == pageCount) p=0;` So on the next pass through `loop()`, `(*pages[p])();` is `(*pages[1])();` where `pages[1]` is `nullptr`.

In practice, what you're doing is generating and executing an AVR `icall` (indirect call) instruction to address 0x0000 (`nullptr` representation) to the reset vector. So, your sketch starts over almost like a reset, except the hardware has not been reset. Importantly, the interrupts are still configured as they were and the global interrupt flag is on, which means all manner of potential weirdness if one of them manages to execute before you get back ground `setup().` So, it's difficult to say exactly why you're seeing what you're seeing. But, it doesn't surprise me as a potential outcome. And it may not be the *only* problem; just *a* problem.
> 1 votes

---
Tags: ssd1306
---


title: String comparison problem

text:
# Question
Title: String comparison problem
I have this callback function in my Firmata sketch. It receives a string as a character array and does something with it. The problem is, that the string is being sent to the Arduino in `T\0h\0i\0s\0` form - after each character there is a `\0` terminator. As you can see, my function is switching the d13 LED on if the string incoming is `COMMAND`. I had tried to use several comparison methods:

* `strcmp(myString, "COMMAND") == 1`;
* `myString == "COMMAND"`;
* `strcmp(myString, "COMMAND\0") == 1`;
* `myString == "COMMAND\0"`;
* `strcmp(myString, "C\0O\0M\0 M\0A\0N\0D\0") == 1`;
* `myString == "C\0O\0M\0 M\0A\0N\0D\0"`;
* `==` with saving the `COMMAND` to a char array variable;
* `strcmp` with saving the `COMMAND` to a char array variable;
* last two things with converting both the incoming and the needed to a String instance;
* comparing a String instance with a directly stated `"COMMAND"`...

Nothing works. How can I compare the strings workably?

Full Arduino sketch:

```
#include <Firmata.h>

void stringCallback(char *myString)
{
  if (strcmp(myString, "COMMAND") == 1) {
    digitalWrite(13, HIGH);
  }
  Firmata.sendString(myString);
}

void sysexCallback(byte command, byte argc, byte *argv)
{
  Firmata.sendSysex(command, argc, argv);
}

void setup()
{
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(STRING_DATA, stringCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.begin(57600);
  pinMode(13, INPUT);
}

void loop()
{
  while (Firmata.available()) {
    Firmata.processInput();
  }
}

```

Full code of the desktop program:

```
import pyfirmata, time

class CustomArduino(pyfirmata.Arduino):
    def __init__(self, port: str):
        pyfirmata.Arduino.__init__(self, port)
        self.iterator = pyfirmata.util.Iterator(self)
        self.iterator.start()

        self.add_cmd_handler(0x71, self.receiveString)

    def receiveString(self, *args, **kwargs):
        print(f'Raw: {args}\n'
              f'Received: {pyfirmata.util.two_byte_iter_to_str(args)}')

    def sendString(self, data):
        self.send_sysex(0x71, pyfirmata.util.str_to_two_byte_iter(data))

    def send_sysex(self, sysex_cmd, data=[]):
        """
        Sends a SysEx msg.
        :arg sysex_cmd: A sysex command byte
        : arg data: a bytearray of 7-bit bytes of arbitrary data
        """
        msg = bytearray([pyfirmata.pyfirmata.START_SYSEX, sysex_cmd])
        msg.extend(data)
        msg.append(pyfirmata.pyfirmata.END_SYSEX)
        self.sp.write(msg)

print('STRING TESTER\nPlease input your COM port: ', end = '')
myCom = str(input())
device = CustomArduino(myCom)

while True:
    device.sendString(input('Send: '))
    time.sleep(1)

```

Strange detail: my Arduino is on the `COM6` COM-port. If I connect it via my program and send `com6` to the arduino, the D13 LED turns on!

# Answer
> 0 votes
As @timemage stated, `strcmp` returns `0` for equal. Sincerely in the provided code, while you send a message, which contents are **not** `COMMAND`, the LED will be turned on.

To get what we need, we must compare `strcmp` return value with `0`! If it equals, then the strings match, and your suggested code is being executed:

```
void stringCallback(char *myString)
{
  if (strcmp(myString, "COMMAND") == 0) {
    digitalWrite(13, HIGH);
  }
  Firmata.sendString(myString);
}

```

---
Tags: string
---


# Question
Title: Error Compiling for board Arduino Nano while using Adafruit GFX
Whys is this happening to me?? I have to meet a deadline please help!! Here is my code.

```
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

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

// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI   11
#define OLED_CLK   12
#define OLED_DC    9
#define OLED_CS    8
#define OLED_RESET 10
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
  OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);
void setup()
{
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
}

  display.display();
  delay(2000);

  display.clearDisplay();

  display.drawPixel(10, 10, SSD1306_WHITE);

  display.display();
  delay(2000);
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  }
void loop()
{
drawLine(20,60,5,50,256);

}

```

The Error

> C:\Users\hp\AppData\Local\Temp\ccyB6dO1.ltrans0.ltrans.o: In function `loop': C:\Users\hp\Desktop\Sunfox\Sunfox\BP_Plus_ECG\February_11\OLED_Testing_w_Adafruit\Test_2\Test_2/Test_2.ino:51: undefined reference to` drawLine(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)' collect2.exe: error: ld returned 1 exit status exit status 1 Error compiling for board Arduino Nano.

# Answer
Currently, you defined a forward declaration for `drawLine`, however I assume you want to call the method (function) inside `display`.

So change

```
drawLine(20,60,5,50,256);

```

into

```
display.drawLine(20,60,5,50,256);

```

And you can remove the forward declaration, because this method is already defined in the library.

```
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);

```

Note, if you call `drawLine` without an instance (which is `display`), then the linker tries to find the `drawLine` function which it cannot find, so you get a linker error (see `ld returned` in your error, together with `undefined reference`).
> 1 votes

---
Tags: programming, adafruit, functions, oled, ssd1306
---


title: 4 Bit Counter up and down

text:
# Question
Title: 4 Bit Counter up and down
we are asked to create an Arduino code that would run a 4 Bit Binary UP counter once a push button switch is pressed and then 4 Bit Binary Down counter on the second click. Then vice versa. This should be done using only one switch. I figured out the Count up portion but I don't know how to add the count down code for the same switch. Can someone help me with this. Thank you. **please see below for my program**

```
int buttonState = 0;
int timer = 300;
int pin8 = 8;
int pin9 = 9;
int pin10 = 10;
int pin11 = 11;

void setup()
{
pinMode(7,INPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);

}

void loop()
{
digitalWrite(pin8, LOW);
digitalWrite(pin9, LOW);
digitalWrite(pin10, LOW);
digitalWrite(pin11, LOW);
buttonState = digitalRead(7);

if(buttonState == HIGH)
{
digitalWrite(pin8, HIGH);
delay(timer);
digitalWrite(pin8, LOW);
delay(timer); //bit 1
digitalWrite(pin9, HIGH);
delay(timer);
digitalWrite(pin9, LOW);
delay(timer); //bit 2
digitalWrite(pin8, HIGH);
digitalWrite(pin9, HIGH);
delay(timer);
digitalWrite(pin8, LOW);
digitalWrite(pin9, LOW);
delay(timer); //bit 3
digitalWrite(pin10, HIGH);
delay(timer);
digitalWrite(pin10, LOW);
delay(timer); //bit 4
digitalWrite(pin8, HIGH);
digitalWrite(pin10, HIGH);
delay(timer);
digitalWrite(pin8, LOW);
digitalWrite(pin10, LOW);
delay(timer); //bit 5
digitalWrite(pin9, HIGH);
digitalWrite(pin10, HIGH);
delay(timer);
digitalWrite(pin9, LOW);
digitalWrite(pin10, LOW);
delay(timer); //bit 6
digitalWrite(pin8, HIGH);
digitalWrite(pin9, HIGH);
digitalWrite(pin10, HIGH);
delay(timer);
digitalWrite(pin8, LOW);
digitalWrite(pin9, LOW);
digitalWrite(pin10, LOW);
delay(timer); //bit 7
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin11, LOW);
delay(timer); //bit 8
digitalWrite(pin8, HIGH);
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin8, LOW);
digitalWrite(pin11, LOW);
delay(timer); //bit 9
digitalWrite(pin9, HIGH);
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin9, LOW);
digitalWrite(pin11, LOW);
delay(timer); //bit 10
digitalWrite(pin8, HIGH);
digitalWrite(pin9, HIGH);
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin8, LOW);
digitalWrite(pin9, LOW);
digitalWrite(pin11, LOW);
delay(timer); //bit 11
digitalWrite(pin10, HIGH);
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin10, LOW);
digitalWrite(pin11, LOW);
delay(timer); //bit 12
digitalWrite(pin8, HIGH);
digitalWrite(pin10, HIGH);
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin8, LOW);
digitalWrite(pin10, LOW);
digitalWrite(pin11, LOW);
delay(timer); //bit 13
digitalWrite(pin9, HIGH);
digitalWrite(pin10, HIGH);
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin9, LOW);
digitalWrite(pin10, LOW);
digitalWrite(pin11, LOW);
delay(timer); //bit 14
digitalWrite(pin8, HIGH);
digitalWrite(pin9, HIGH);
digitalWrite(pin10, HIGH);
digitalWrite(pin11, HIGH);
delay(timer);
digitalWrite(pin9, LOW);
digitalWrite(pin9, LOW);
digitalWrite(pin10, LOW);
digitalWrite(pin11, LOW);
delay(timer); //bit 15
}
}

```

# Answer
> 2 votes
Currently you are just setting the LEDs manually one after another in your code. That is not actually a binary counter (as it is most likely wanted by the exercise), but only looks like one.

First you need to understand, what a counter really is: Basically it is just a variable, that holds a number. Where exactly this variable is saved, is not important. For your case you would use a variable in your code. The Counter/Timer hardware in the Arduino uses a fixed SFR (Special Function Register) for it.

That the counter is 4bit, means, that its value is hold by only 4 bits. That gives you a value range from 0 to 15 (`2^4` values). So a 4bit counter variable would count from 0 to 15. You could just have a counter variable, that you could increment or decrement (depending on the direction, that you want to count).

```
// Declare counter variable and initialize with zero
int counter_variable = 0;
// Increment
counter_variable++;
// or Decrement
counter_variable--;

```

For the "binary" part: Here it is important to understand, that the decimal number from 0 to 15 is already saved in the variable as binary (since microcontrollers/computers only know binary, nothing else). So you can write out the state of the 4 least significant bytes of the counter variable:

```
digitalWrite(pin8  ,counter_variable & 0b0001);
digitalWrite(pin9  ,counter_variable & 0b0010);
digitalWrite(pin10 ,counter_variable & 0b0100);
digitalWrite(pin11 ,counter_variable & 0b1000);

```

The `&` is a bitwise AND. The result of the operation will only leave bits set, when they are set on both sides. So here we are isolating the corresponding bits. `digitalWrite()` will interpret anything but zero as HIGH. Thus the pin is set HIGH, if the corresponding bit is set in `counter_variable`. But you see, that we are repeating us here. We could use a for loop and define our pins in an array:

```
// at global scope
int led_pins[4] = {8, 9, 10, 11};

// in the button if statement
for(int i=0; i<4; i++){
    digitalWrite(led_pins[i], counter_variable & (1 << i));
}

```

We have organized the pins of the LEDs in an array, so they can be easily indexed. Then we are looping through the pins array and setting the pins similar to the last version. But now we are using `(1 << i)`. The `<<` operator shifts the bits of the number before it by the number of digits, that comes after it. Decimal `1` is binary `0b0001`. So, when `i` is 2 (for example), this would shift the bits 2 digits to the left, giving you `0b0100`. We are just generating the same bit patterns as in the last version.

But we can even optimize further via direct port manipulation. Inside the microcontroller the output pins are controlled via simple Special Function Registers. They work somewhat like a variable. All output pins are organized into socalled "Ports" (groups of up to 8 pins). Each port has one `PORTx` registers (where `x` stands for the character associated with that port), which sets the state of the pins, if they are in output mode. Setting the corresponding bit in the correct `PORTx` register will set the pin to HIGH. Clearing the bit (setting to zero) will set the pin to LOW.

You are using the Arduino pins 8 to 11. If you look at a pinout diagram of the Arduino Uno, you will see, that these pins are also marked as `PB0` to `PB3`, which stands for "Port B, pins 0 to 3 (inside that port)". The corresponding `PORTx` register is `PORTB`. So we can set all pins of the port at once by assigning a new value to that register. The following code would set an alternating on/off pattern for all 8 pins of PORTB:

```
PORTB = 0b10101010;

```

Now we only want to use the lowest 4 bits and set them to the values, that our counter variable has. So we are masking away the 4 higher bits with the bitwise AND operator and then assign that value to the register:

```
PORTB = counter_variable & 0b00001111;

```

So now the if statement in `void loop()` might look like this (using a for loop):

```
if(buttonState == HIGH){
    // count up counter variable
    for(int counter_variable=0; counter_variable < 16; counter_variable++){
        // write out to the pins
        PORTB = counter_variable & 0b00001111;
        // delay a bit to show the value
        delay(timer);
    }
}

```

And now we want that each consecutive button to count in the other direction than before. So we can declare another variable as direction and then use another if statement, to switch between two for loops:

```
// On global scope
int direction = 1;

// in void loop()

if(buttonState == HIGH){
    if(direction == 1){
        // count up counter variable
        for(int counter_variable=0; counter_variable < 16; counter_variable++){
            // write out to the pins
            PORTB = counter_variable & 0b00001111;
            // delay a bit to show the value
            delay(timer);
        }
        // change direction
        direction = -1;
    } else {
        // count up counter variable
        for(int counter_variable=15; counter_variable >= 0; counter_variable--){
            // write out to the pins
            PORTB = counter_variable & 0b00001111;
            // delay a bit to show the value
            delay(timer);
        }
        // change direction
        direction = 1;
    }
}

```

Note:

* This is probably not the most efficient way, but I think it is quite understandable (which is also important).
* This still uses much `delay()` calls, just as your code. That will make your button unresponsive. The counter must first finish, before the button will react again. That might be ok for you. If not, you need to restructure the program for using a non-blocking coding style like in the `BlinkWithoutDelay` example from the Arduino IDE (using `millis()`). There are lots of tutorials about that on the web.
* When using a non-blocking coding style, you also need to check the button for the transition to HIGH, instead for the state high. Otherwise the code would run only, while the button is pressed.
* Buttons bounce, when being pressed. So there are many transitions between HIGH and LOW for a few ms, when the button is pressed. In the code above this is not important, because the started counter needs so long, that every bounce is finished after the counter finished. With code, that needs less than a few ms, you might get into problems there. I would suggest the `Bounce2` library for that. It handles the bounce detection for you.

---
Tags: arduino-uno, programming, led, interrupt, timers
---


# Question
Title: Issue with simple timer based on millis()
Sorry to bother but I am at my wits end. I'm experimenting with timers, and starting very simple. The following code is supposed to print the content of a variable each time an interval of time has passed, then update that variable. But for some reason I'm getting no output on the serial monitor.

I have used the serial monitor before on other projects without issue, so I'm not sure what the problem could be.

Is there any error in my code?

```
unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
const long interval = 1000;

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

void loop() {
  if (currentMillis - previousMillis >= interval) {
    Serial.println(previousMillis);
    previousMillis = currentMillis;
  }
  else {
    ;
  }
}

//  previousMillis += interval;

```

# Answer
> 2 votes
Since `currentMillis` is just a simple variable, it will not automatically update. In fact the initialization with `millis()` in global scope is unnecessary. Just initialize the value with 0. At the time, where the global variables are created, the time is 0ms anyways.

You need to update the `currentMillis` variable everytime, before using it. So just insert

```
currentMillis = millis();

```

right at the start of the `loop()` function.

---
Tags: timers, millis
---


# Question
Title: How can I stop my servo looping when my sensor doesn't detect movement?
I have this project with my Arduino UNO where I want my servo motor SG90 to go full speed to 180 degrees when the PIR sensor sends HIGH value and go slowly back to zero when the value is LOW.

I have this code working where the servo goes full speed back to zero:

```
#include <Servo.h>

Servo myservo; //creates a servo object
int pos = 0; //variable to store servo position
//amount of time we give the sensor to calibrate(10-60 secs according to the datasheet)
int calibrationTime = 30;
//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
int pir = 12; //digital pin connected to the PIR's output
int pirPos = 13; //connects to the PIR's 5V pin

void setup() {
  myservo.attach(4); //attaches servo to pin 4
  Serial.begin(9600); //begins serial communication
  pinMode(pir, INPUT);
  pinMode(pirPos, OUTPUT);
  digitalWrite(pirPos, HIGH);
  //time for calibration

  Serial.println("calibrating sensor ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(calibrationTime - i);
    Serial.print("-");
    delay(1000);
  }
  Serial.println();
  Serial.println("done");

  //this waits until the PIR's output is low before ending setup
  while (digitalRead(pir) == HIGH) {
    delay(500);
  }

  Serial.print("SENSOR ACTIVE");
}

void loop() {
  if (digitalRead(pir) == HIGH)
    myservo.write(180);              // tell servo to go to position in variable 'pos'
  Serial.print("Motion detected!");

  if (digitalRead(pir) == LOW)
    myservo.write(0);              // tell servo to go to position in variable 'pos'
  Serial.print("Motion ended!");
}

```

I'd like the servo to go slowly back to zero, so I tried this :

```
#include <Servo.h>

Servo myservo; //creates a servo object
int pos = 0; //variable to store servo position
//amount of time we give the sensor to calibrate(10-60 secs according to the datasheet)
int calibrationTime = 30;
//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
int pir = 12; //digital pin connected to the PIR's output
int pirPos = 13; //connects to the PIR's 5V pin

void setup() {
  myservo.attach(4); //attaches servo to pin 4
  Serial.begin(9600); //begins serial communication
  pinMode(pir, INPUT);
  pinMode(pirPos, OUTPUT);
  digitalWrite(pirPos, HIGH);

  //time for calibration
  Serial.println("calibrating sensor ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(calibrationTime - i);
    Serial.print("-");
    delay(1000);
  }
  Serial.println();
  Serial.println("done");

  //this waits until the PIR's output is low before ending setup
  while (digitalRead(pir) == HIGH) {
    delay(500);
  }

  Serial.print("SENSOR ACTIVE");
}

void loop() {
  if (digitalRead(pir) == HIGH)
    myservo.write(180);              // tell servo to go to position in variable 'pos'

  Serial.print("Motion detected!");

  if (digitalRead(pir) == LOW)
    for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15ms for the servo to reach the position
    }

  Serial.print("Motion ended!");
}

```

The problem is with this code the servo does go slowly back to zero but then goes full speed back to 180 and again and again ....

Any idea? I'm a beginner in Arduino, so I assume it must not be that hard to figure out. Thanks.

# Answer
> 2 votes
Don't set the pos to 180 in the `(digitalRead(pir) == LOW)` branch if you do not want it to repeatedly jump up to 180 for as long as the condition is true.

```
void loop() {
  if (digitalRead(pir) == HIGH)
     pos = 180;
  myservo.write(pos);              // tell servo to go to position in variable 'pos'

  Serial.print("Motion detected!");

  if (digitalRead(pir) == LOW)
    for (; pos > 0; pos -= 1) { // decay to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15ms for the servo to reach the position
    }

  Serial.print("Motion ended!");
}

```

Alternately, you could use `pos` as a state variable and simplify things:

```
void loop() {
  if (digitalRead(pir) == HIGH)
     pos = 180;
  elif (pos > 0 ){
     pos--;
     delay(15);
  }
  myservo.write(pos);
}

```

---
Tags: servo, loop
---


title: Whats wrong with my POST request?

text:
# Question
Title: Whats wrong with my POST request?
Ive been trying to get POST working on my ESP8266. I followed this tutorial https://techtutorialsx.com/2016/07/21/esp8266-post-requests/ which works, but once i change the request URL to anything else i get -1 response from http.POST() which the library returns when "no info".

I have no clue what the "no info" means and what im doing wrong. Does anyone have any suggestions? Below is the code im using.

```
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

    HTTPClient http;    //Declare object of class HTTPClient

    //http.begin("http://192.168.1.88:8085/hello"); //Works fine
    //http.begin("https://httpbin.org:8080/post"); //Causes -1 as httpCode
    //http.begin("https://httpbin.org/post"); //Causes -1 as httpCode
    http.begin("https://XXXXX.execute-api.eu-west-2.amazonaws.com/XXXXX/XXXXX");
    http.addHeader("Content-Type", "application/json");  //Specify content-type header

    int httpCode = http.POST("{\"key\":\"1\",\"id\": \"ESPXXX2\",\"action\": \"rbg\",\"value\": \"255255000\"}");   //Send the request
    String payload = http.getString(); //Get the response payload

    Serial.println(httpCode);   //Print HTTP return code
    Serial.println(payload);    //Print request response payload

    http.end();  //Close connection

  } else {

    Serial.println("Error in WiFi connection");

  }

  delay(10000);  //Send a request every 10 seconds

```

Only serial output im getting is "-1" for httpCode and empty line for payload.

# Answer
I ended up ditching HTTPS since it doesnt seem to be implemented all that well (Requires hardcoding of fingerprint). Changed the architecture of my system so that HTTPS is handled by Python which doesnt require jumping through hoops.
> 1 votes

---
Tags: esp8266, programming, http
---