body:
I've made a light switcher that switches lights on for 15s after a correct tag is presented, and also when door is opened for 6 seconds (its for outside) so i can see a keyhole after leaving for a brief amount of time. It works perfectly, but the rfid reader stops reading tags after random amounts of time (sometimes after hour and sometimes after days) - I've tried i think everything in terms of software (except watchdog) and i simply ran out of ideas. I need it to work, so i draw all the connections in the picture below - if anyone got any ideas, please let me now.

*Side note - everything is mounted and hidden outside so each even smallest hardware change is very hard to do so please, don't throw random ideas in this matter even tho **every** help is appreciated*

[![scheme][1]][1]

EDIT: I made a photo of interior of the enclosure that holds relay, arduino and charger PCB and decided to add it here too

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

```
#include <SPI.h>
#include <MFRC522.h>

//blue
const byte UID1[] = {0xA7, 0x8C, 0x24, 0xD9};
//blacks
const byte UID2[] = {0x10, 0x84, 0xD2, 0x2A};
const byte UID3[] = {0xDC, 0x46, 0xB6, 0x91};
const byte UID4[] = {0xB0, 0xE8, 0xC4, 0x2A};
//reds
const byte UID5[] = {0x9E, 0xC8, 0xEA, 0xB3};
const byte UID6[] = {0xFE, 0xA5, 0xF7, 0xB3};
//const byte UID6[] = {0x70, 0xBA, 0x35, 0xA5};

#define RST_PIN 9
#define SS_PIN 10

MFRC522 rfid(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
int in1 = 7;
int dooropen = 8;
int state = 0;
int testerbester = 0;
void setup() {
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  pinMode(in1, OUTPUT);
  pinMode(dooropen, INPUT);
  digitalWrite(in1, LOW);
  delay(2000);
}

void loop() {
  delay(200);
  state = digitalRead(dooropen);
  if (state == HIGH) {
    //Serial.println("Door Opened");
    testerbester = 1;
    digitalWrite(in1, HIGH);
  } else {
    if (testerbester == 1) {
      delay(6000);
      testerbester = 0;
      digitalWrite(in1, LOW);
    } else {
      digitalWrite(in1, LOW);
    }
    if ( ! rfid.PICC_IsNewCardPresent())
    {
      return;
    }
    if ( ! rfid.PICC_ReadCardSerial())
    {
      return;
    }
    if ((rfid.uid.uidByte[0] == UID1[0] &&
         rfid.uid.uidByte[1] == UID1[1] &&
         rfid.uid.uidByte[2] == UID1[2] &&
         rfid.uid.uidByte[3] == UID1[3]) ||
        (rfid.uid.uidByte[0] == UID2[0] &&
         rfid.uid.uidByte[1] == UID2[1] &&
         rfid.uid.uidByte[2] == UID2[2] &&
         rfid.uid.uidByte[3] == UID2[3]) ||
        (rfid.uid.uidByte[0] == UID3[0] &&
         rfid.uid.uidByte[1] == UID3[1] &&
         rfid.uid.uidByte[2] == UID3[2] &&
         rfid.uid.uidByte[3] == UID3[3]) ||
        (rfid.uid.uidByte[0] == UID4[0] &&
         rfid.uid.uidByte[1] == UID4[1] &&
         rfid.uid.uidByte[2] == UID4[2] &&
         rfid.uid.uidByte[3] == UID4[3]) ||
        (rfid.uid.uidByte[0] == UID5[0] &&
         rfid.uid.uidByte[1] == UID5[1] &&
         rfid.uid.uidByte[2] == UID5[2] &&
         rfid.uid.uidByte[3] == UID5[3]) ||
        (rfid.uid.uidByte[0] == UID6[0] &&
         rfid.uid.uidByte[1] == UID6[1] &&
         rfid.uid.uidByte[2] == UID6[2] &&
         rfid.uid.uidByte[3] == UID6[3]))
    {
      digitalWrite(in1, HIGH);
      delay(15000);
      digitalWrite(in1, LOW);
    }
    rfid.PICC_HaltA();
  }
}
```

  [1]: https://i.stack.imgur.com/MSICK.jpg
  [2]: https://i.stack.imgur.com/WcqLa.jpg

title: I'm desperate and need help with MFRC522 (stops working randomly)

Answers: 0


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

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

  [1]: https://i.stack.imgur.com/WwLeG.gif

title: How to make Arduino react to serial information?

Answers: 1

body:
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.

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

  [1]: https://i.stack.imgur.com/5dlYs.png

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).


body:
[This][1] 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 ?

[![pic][2]][2]

  [1]: https://www.aliexpress.com/item/33006588335.html?spm=a2g0s.12269583.0.0.5c4c4e9fviBsDu
  [2]: https://i.stack.imgur.com/LLKZz.png

title: UNO R3 + WiFi ATmega328P+ESP8266 (32Mb memory) USB-TTL CH340G For Arduino Uno - External ESP8266 Pins

Answers: 1

body:
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][1] of [the Uno+WiFi board][2]:

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

  [1]: https://robotdyn.com/pub/media/0G-00005215==UNO+WiFi-R3-AT328-ESP8266-CH340G/DOCS/PINOUT==0G-00005215==UNO+WiFi-R3-AT328-ESP8266-CH340G.pdf
  [2]: https://robotdyn.com/uno-wifi-r3-atmega328p-esp8266-32mb-flash-usb-ttl-ch340g-micro-usb.html
  [3]: https://i.stack.imgur.com/DIuTT.png


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

title: Serial Monitor stops working when using PinMode

Answers: 1

body:
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)


body:
I want to replace the outdated gyro in a wiimotion plus with a BNO055. Based off what I've read from [wiibrew][1], and im currently trying to get the wiimote to recognize the nano as an extension over I2C. Theres a lot of things at play here, but this summarizes the parts related to my issue:

 1. When playing a game that needs WiiMotion Plus (WMP), the wiimote will send out a request to a slave device with address 00x53 to read register 0xFE every ~8 seconds.
 2. If there is an actual register there, and it has [the correct two byte id][2] (this case it should be 0x00, 0x05), it will write 0x04 to 0xFE, activating the WMP and it will subsequently start sending motion data

I got my register information by copying the registers of an *actual* wiimotion plus, so i know the information is correct, yet for some reason i receive the requests from the wii and it doesn't send the activation byte back, it ignores it and keeps asking for requests. Heres an outut from my code.
```
23:38:28.599 -> WM+ tester
23:38:37.628 ->
23:38:37.628 -> Recieving information...
23:38:37.628 -> Handling request to register 254
23:38:37.628 ->       Sending bytes: 0,5,254,0,0,0,0,159,1,255,0,44,1,236,1,93,1,59,1,79,1,0,0,0,0,201,2,190,2,218,2,148,
                                     ^^^ the extension id
23:38:37.675 ->
23:38:37.675 -> Recieving information...
23:38:37.675 -> Handling request to register 254
23:38:37.675 ->       Sending bytes: 2,183,2,164,2,149,2,13,10,0,72,97,110,100,108,105,110,103,32,114,101,113,117,101,115,116,32,116,111,32,114,101,
23:38:37.767 ->
23:38:37.767 -> Recieving information...
23:38:37.767 -> Handling request to register 254
23:38:37.767 ->       Sending bytes: 103,105,115,116,101,114,32,0,32,32,32,32,32,32,83,101,110,100,105,110,103,32,98,121,116,101,115,58,32,0,44,0,
```
Since the slave cant know the length of bytes requested, it sends the maximum of 32 and **theoretically** the wii should take what it needs. But as i noted, the wiimote doesn't accept this and keeps requesting bytes, moving up the registers as it goes. My code for these interactions is here (most of which is documentation for future use):
```
// All values are big-endian.
// Assume data is tightly packed.

// The i2c stream is 0x100 bytes long, and it is mirrored across the entire 16-bit address space up to 0xa4FFFF
// Peripheral Protocol is 400kHz "fast" I2C
// NOTE: the structure of this code does not allow for passthrough devices

// References:
// https://github.com/denizkoekden/arduino-wiimote
// http://wiibrew.org/wiki/Wiimote/Extension_Controllers
// http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Wii_Motion_Plus
// http://randomhacksofboredom.blogspot.com/

#include "Wire.h"

#define EMPTY_BYTE 0xFF
#define SERIAL_BAUD 115200
#define CLOCK_FREQ 400000

byte wiimote_registers[0x100] = {0xB5,0x26,0x42,0x7F,0x7E,0x7E,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8,0xFF,0xFF,0x0,0x0,0xA4,0x20,0x0,0x5,0x7A,0x8A,0x77,0x2B,0x77,0x3A,0x31,0x48,0xD5,0x27,0x27,0xE6,0xC8,0x30,0xB1,0xF9,0x83,0x4D,0x78,0x45,0x78,0xE0,0x36,0xDA,0xD1,0xDC,0x2A,0xCC,0x2D,0x4F,0x48,0xCD,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x25,0xE0,0x8E,0xCE,0xFA,0x1E,0x25,0x8A,0x9F,0xCB,0x8B,0xFC,0x5,0x96,0xFF,0x1A,0xD3,0xC8,0x15,0x97,0xCF,0xAF,0xB7,0xCC,0x72,0x79,0x87,0x78,0x35,0x9B,0x27,0x6C,0x9C,0x6A,0x1C,0xD4,0x88,0x8E,0xD6,0xA,0xE1,0xDA,0xBD,0x38,0xA5,0xD5,0xB,0x9D,0x3A,0xAC,0x26,0x1A,0x4D,0xFA,0x5,0x21,0x24,0xD8,0x6A,0xA3,0xED,0x60,0xEB,0x1A,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8,0xFF,0xFF,0x0,0x0,0xA4,0x20,0x0,0x5,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8,0xFF,0xFF,0x0,0x0,0xA4,0x20,0x0,0x5,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8,0xFF,0xFF,0x0,0x0,0xA4,0x20,0x0,0x5,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8,0xFF,0xFF,0x0,0x0,0xA4,0x20,0x0,0x5,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8,0xFF,0xFF,0x0,0x0,0xA4,0x20,0x0,0x5,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8,0xFF,0xFF,0x0,0x0,0xA4,0x20,0x0,0x5,0x55,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2,0xFF,0xFF,0x0,0x0,0xA6,0x20,0x0,0x5};
static byte state = 0;

const byte inactive_expansion[2] = {0x00, 0x05};
const byte active_expansion[2] = {0x04, 0x05};

const byte inactive_address = 0x53; // starts at 0xa60000
const byte active_address = 0x52; // starts at 0xa40000

const byte inactive_id[6] = {0x00,0x00,0xA6,0x20,0x00,0x05};
const byte active_id[6] = {0x00,0x00,0xA4,0x20,0x04,0x05};

// IMPORTANT REGISTERS AND WHAT THEY SHOULD HOLD

const byte id_reg = 0xa600fa;
  // holds id, used to identify extension type

const byte activate_reg = 0xa600fe;
  // activates the wmp when 0x04 is written to it
  // activation changes the extension identifier and makes the wmp start reporting motion data
  // writing 0x05 or 0x07 to this register can also implement passthrough mode
  // but we wont allow for other extensions to be connected, making that feature useless

const byte deactivate_reg = 0xa400f0;
  // deactivates the wmp when 0x55 is written to it
  // writing 0x55 to it also activates whatever extesion is connected to the wmp
  // deactivation reverts whatever changes activation has made

const byte init_reg = 0xa600f0;
  // starts initialization of the wmp when 0x55 is written to it
  // initialization does little, except for changing init-shift and init_rand_shift registers

const byte init_reg_2 = 0xa500fb;
  // would normally start initialization process once 0x00 was written to it
  // however wmp games dont do this, so its useless

const byte init_shift_reg = 0xa600f7;
  // during initialization it changes from 0x02 to 0x04 to 0x08 to 0x0C to 0x0E then stays at 0x0E
  // yet wmp games dont read this, making it useless

const byte init_shift_rand_reg = 0xa60050;
  // after initialization, registers 0xa60050 to 0xa600cf will change briefly, but randomly, for a total of 128 bytes

const byte calibration_reg = 0xa60020;
  // 32 bytes of calibration information which are reported once activated

const byte motion_reg = 0xa40008;  // (or sometimes 0xa40000)
  // 6 bytes of gyro information which are reported once activated

/*
  This is a representation of the data to be stored in motion_reg and calibration_reg

  The motion data's bits of data are split into two parts.
  The first part is the first 0-7 bits of data
  The last part is the last 8-13 bits of data
  Unused Bytes are filled with 0x00

              struct motion_data {
                byte yaw_down_7_0;
                  // Byte 0, <7:0>

                byte roll_left_7_0;
                  // Byte 1, <7:0>

                byte pitch_left_7_0;
                  // Byte 2, <7:0>

                byte yaw_down_13_8;
                  // Byte 3, <13:8>
                  // Bit 1 reserved for Yaw Slow Mode & Bit 0 reserved for Pitch Slow Mode

                byte roll_left_13_8;
                  // Byte 4, <13:8>
                  // Bit 1 reserved for Roll Slow Mode & Bit 0 reserved for Extension Connected

                byte pitch_left_13_8;
                  // Byte 5, <13:8>
                  // Bit 1&0 are unused, Bit 1 is left as 1, and Bit 2 is left as 0
              };

  As for the calibration data,
  uid_1,2 seem to be just a unique ID.
  crc32_msb,lsb is a crc32 of all calibration data except the checksum bytes.

              struct calibration_block {
                // Gyro values at 0 deg/sec to 16 bits of precision.
                u16 yaw_zero;
                u16 roll_zero;
                u16 pitch_zero;

                // Gyro values at "scale" deg/sec.
                u16 yaw_scale;
                u16 roll_scale;
                u16 pitch_scale;

                // Angular velocity of the above scale values in deg/sec divided by 6.
                // e.g. A value of 45 would mean the "scale" values represent the gyro at 270 deg/sec.
                u8 degrees_div_6;
              };

              struct calibration_data {
                // Calibration for "fast" mode.
                calibration_block fast;

                u8 uid_1;
                u16 crc32_msb;

                // Calibration for "slow" mode.
                calibration_block slow;

                u8 uid_2;
                u16 crc32_lsb;
              };

*/

/*
 * This function pointer informs the Arduino that a byte has been
 * written to one of the registers corresponding to the Extension.
 * Specifically, if you assign the function foo to this pointer and
 * you write yy bytes starting at the register address 04a400xx of
 * the Wiimote, then this library will call foo(xx, yy).  The bytes
 * are written to the global array wiimote_registers.
 *
 * Note that count will always be less than eight.  If you write
 * eight or more bytes to the Wiimote, this callback will be
 * invoked several times.
 */
void (*wiimote_receive)(byte offset, byte count) = NULL;

static void receive_bytes(int count) {

  Serial.println("");
  Serial.println("Recieving information...");
  delay(100);

  if (count == 1) {
    state = Wire.read();
  }

  else if (count > 1) {
    byte addr = Wire.read();
    byte curr = addr;

    Serial.print("Recieved bytes to register ");
    Serial.println(addr);
    delay(100);

    Serial.print("Incoming bytes... ");
    for (int i = 1; i < count; i++) {
      byte d = Wire.read();
      wiimote_registers[curr++] = d;

      Serial.print(d);
      delay(100);
    }

    Serial.println("");
    if (wiimote_receive) {
      wiimote_receive(addr, (byte) count - 1);
    }
  }
}

static void handle_request() {

  static byte last_state = EMPTY_BYTE;
  static byte offset = 0;  // apparently offset starts at 0x08? im not sure if this is true

  Serial.print("Handling request to register ");
  Serial.println(state);
  delay(100);

  switch (state) {

  default:
    if(last_state == state) offset += 32;
    else {
      last_state = state;
      offset = 0;
    }

    Serial.print("      Sending bytes: ");
    for(int i = 0; i < 32; i++){
      Serial.print(wiimote_registers[state+offset+i]);
      Serial.print(",");

      delay(50);
    }
    Serial.println("");
    delay(100);

    Wire.write(wiimote_registers + state + offset, 32);
    break;
  }

}

void setup() {
  Serial.begin(115200);
  Serial.println("WM+ tester");

  Wire.begin(inactive_address);
  Wire.setClock(CLOCK_FREQ);

  Wire.onReceive(receive_bytes);
  Wire.onRequest(handle_request);
  delay(5000);
}

void loop() {
}
```
How can i get the wiimote to acknowledge the response and send the activation byte to 0xFE?

  [1]: http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Wii_Motion_Plus
  [2]: http://wiibrew.org/wiki/User:Marcan/Wiimote#Identification

title: Help Convincing Wiimote a Nano is a WiiMotion Plus

Answers: 0


body:
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**
[![enter image description here][1]][1]

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

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

title: 4 Bit Counter up and down

Answers: 1

body:
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.


body:
[![enter image description here][1]][1]I am displaying text using this code.

    #include <U8glib.h>
    U8GLIB_SSD1306_128X64 u8g(12, 11, 8, 9, 10);
    int Buffer[128];int Buffer2[128];int max=0;

    void pageEMG();
    void recordEMG();
    void pageECG();
    void recordECG();
    void pageBP();
    void recordBP();
    void clear_screen();

    const int pageCount = 10;
    int p;
    void (*pages[pageCount])() = {clear_screen,recordEMG,pageEMG,clear_screen,recordECG,pageECG,clear_screen,recordBP,pageBP,clear_screen};
    int duration [pageCount] = { 100,5000,10000,100,5000,10000,100,5000,10000,100};
    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 recordEMG(){
    for(int x=0;x<128;x++)
    {
    Buffer[x]=analogRead(A2)*.091;
    Serial.println(Buffer[x]);
    delay(35);
    }
    u8g.drawStr( 0, 20, "Reading EMG...");
    }
    void pageEMG() {

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

    }}
    void recordECG(){
    for(int x=0;x<128;x++)
    {
    Buffer[x]=analogRead(A0)*.08;
    Serial.println(Buffer[x]);
    delay(35);
    }
    u8g.drawStr( 0, 20, "Reading ECG...");
    }
    void pageECG() {

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

    }}
    void recordBP(){
    for(int x=0;x<128;x++)
    {
    Buffer[x]=analogRead(A1)*.091;
    Serial.println(Buffer[x]);
    delay(35);
    }
    u8g.drawStr( 0, 20, "Reading BP...");
    }
    void pageBP() {

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

    }}
    void clear_screen(void) {
      u8g.setColorIndex(0);
    u8g.drawBox(1, 1, 64, 128);
    }
And my text is coming inverted.

Why is this happening?

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

title: Why is my text inverted while using U8glib?

Answers: 0


body:
i am trying to calculate the battery voltage using ESP-12E module. I am using a voltage divider circuit to calculate the same. Here is how my circuit looks like:

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

And here is how my code looks like:

    float volt =0.0;
    float temp=0.0;
    float r1=320000.0;
    float r2=100000.0;

    void setup(){
        Serial.begin(115200);
        Serial.println(String(VoltageCalculator()).c_str());
    }

    float VoltageCalculator(){
      for (int thisReading = 0; thisReading < numReadings; thisReading++) {
        readings[thisReading] = 0;
      }
      Serial.println(analogRead(A0));
      for(int i = 0;i<=10; i++){
        total = total - readings[readIndex];
        // read from the sensor:
        readings[readIndex] = analogRead(A0);
        // add the reading to the total:
        total = total + readings[readIndex];
        // advance to the next position in the array:
        readIndex = readIndex + 1;

        // if we're at the end of the array...
        if (readIndex >= numReadings) {
          // ...wrap around to the beginning:
          readIndex = 0;
        }

        // calculate the average:
        float analogvalue = total / numReadings;

        //  int analogvalue = analogRead(A0);
        temp = (analogvalue * 3.3) / 1024.0;
        volt = temp / (r2/(r1+r2));
      }

      if(DEBUG_ENABLE){
        Serial.println();
        Serial.print("Actual Voltage : ");
        Serial.print(volt);
        Serial.println();
      }

      float volt_percent;

      if(volt == 3.1){
        volt_percent = 0;
      } else{
        float volt_diff = volt - 3.1;
        volt_percent = (volt_diff/1.1)*100;
        if(DEBUG_ENABLE){
          Serial.println();
          Serial.print("Voltage percentage : ");
          Serial.print(volt_percent);
          Serial.println();
        }
      }
      return volt_percent;
    }

When i use this circuit with NodeMCU it works very fine, but when it comes to ESP-12E module it do not show the proper voltage. on `Serial.println(analogRead(A0));` always shows 1024.

Any suggestions why this is happening and how can i do this to achieve the most accurate value?

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

title: Calculate battery (18650 Li-ion) voltage using ESP8266-12E

Answers: 1

body:
Everything was correct and my circuit is also good. The only difference i found is to this below line:

`temp = (analogvalue * 3.3) / 1024.0; `

Which should be

`temp = (analogvalue * 1.0) / 1024.0;`

We are multiplying because we are referencing the voltage from voltage divider circuit as 1 volt.

After doing this, i am getting the exact values battery voltage which then i convert to percentage.

Thank you!


body:
This is my code.

    #include <U8glib.h>
    U8GLIB_SSD1306_128X64 u8g(12, 11, 8, 9, 10);
    void clear_screen();
    const int pageCount = 1;
    int p;
    void (*pages[pageCount])() = {clear_screen};
    int duration [pageCount] = {2000};
    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 clear_screen()
    {
      u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 20, "BP");
      }
This is the output is a floating text which says BP starts at 20 y length and progresses towards the right after every page refresh. and moves 20 y length down as soon as it reaches the end of the OLED
Check this video out.
[Video to the Error][1]

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

title: U8glib+ 7-pin SSD1306 gives moving text without explicitly specifying in code

Answers: 0


body:
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.

title: Error Compiling for board Arduino Nano while using Adafruit GFX

Answers: 1

body:
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`).


body:
I'm making a custom board with AtMega2560-16AU as MCU and CH340G as bootloader (schematic can be seen in the picture).  I have printed the custom PCB and soldered everything in place now I want to program the bootloader.

[![pcb schematic][1]][1]

I connected my Arduino UNO with my custom board like shown in the fritzing schematic below. My custom pcb doesn't look like Arduino MEGA but the connections are the same.

[![connections][2]][2]

I go to Arduino IDE and upload the ArduinoISP example (baudrate:115200) while choosing programmer as "Arduino as ISP".
[![step 1][3]][3]

And when I upload the example I get a response like this:

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

             System wide configuration file is "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf"

             Using Port                    : COM4
             Using Programmer              : arduino
             Overriding Baud Rate          : 115200
             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : Arduino
             Description     : Arduino
             Hardware Version: 3
             Firmware Version: 4.4
             Vtarget         : 0.3 V
             Varef           : 0.3 V
             Oscillator      : 28.800 kHz
             SCK period      : 3.3 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.00s

    avrdude: Device signature = 0x1e950f (probably m328p)
    avrdude: reading input file "C:\Users\ahmet\AppData\Local\Temp\arduino_build_251950/ArduinoISP.ino.hex"
    avrdude: writing flash (4354 bytes):

    Writing | ################################################## | 100% 0.68s

    avrdude: 4354 bytes of flash written
    avrdude: verifying flash memory against C:\Users\ahmet\AppData\Local\Temp\arduino_build_251950/ArduinoISP.ino.hex:
    avrdude: load data flash data from input file C:\Users\ahmet\AppData\Local\Temp\arduino_build_251950/ArduinoISP.ino.hex:
    avrdude: input file C:\Users\ahmet\AppData\Local\Temp\arduino_build_251950/ArduinoISP.ino.hex contains 4354 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 0.53s

    avrdude: verifying ...
    avrdude: 4354 bytes of flash verified

    avrdude done.  Thank you.

As far as I know so far there's no problem.

And now I move to step 2 which now requires me to switch the board to ArduinoMega from tools. And click burn bootloader.
[![enter image description here][4]][4]

When I click burn bootloader I get a response like this:

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

             System wide configuration file is "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf"

             Using Port                    : COM4
             Using Programmer              : stk500v1
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega2560
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PA0
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    10     8    0 no       4096    8      0  9000  9000 0x00 0x00
               flash         65    10   256    0 yes    262144  256   1024  4500  4500 0x00 0x00
               lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0xffffff (probably .avr8x_mega) (retrying)

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000 (retrying)

    Error while burning bootloader.
    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000
    avrdude: Yikes!  Invalid device signature.
             Double check connections and try again, or use -F to override
             this check.

    avrdude done.  Thank you.

Now when I clicked burn the bootloader I got a response saying invalid signature.
So far I tried to:

 1. Change baudrates and try the same steps.
 2. Tried to change the avrdude.txt file. I tried to change the
    signature that was searched for which I couldn't change it because
    windows 10 wouldn't allow me even though I gave myself all the admin
    permissions.

So as a solution to this signature problem people have put an electrolytic capacitor that has 10nF or 10uF value between GND and RST pins of the programmer Arduino.

Also when I tried this for the first time I got a value different than "Off" for oscillator in the 2nd step.

So what should I do? Do I need to change my oscillator and try again or do I need that polarized 10uF capacitor?

Sorry for poorly formatting this post. Thank you so much for reading. Any answers would be appreciated.

  [1]: https://i.stack.imgur.com/zmrEi.png
  [2]: https://i.stack.imgur.com/jHzx3.png
  [3]: https://i.stack.imgur.com/8KPIz.png
  [4]: https://i.stack.imgur.com/jEGpX.png

title: Programming custom Arduino Mega with Arduino Uno

Answers: 1

body:
I finally found the problem with this board. I had a 22pF capacitor between RST and GND on the board I had ordered.

You should not have a capacitor there or it should be 100nF, values such as 22pF or 10nF will cause the board to malfunction and therefore you can't burn the bootloader.


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

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

```c++
#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.

title: How can I stop my servo looping when my sensor doesn't detect movement?

Answers: 1

body:
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);
    }


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

title: Issue with simple timer based on millis()

Answers: 1

body:
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.


body:
I made a circuit where when I press a button, a LED lights up using a pull-down resistor. But when I tried the same with a pull-up resistor instead, the LED remains off (whereas I expected it to be on by default and go off when I push the button). What is the problem?

Here is the circuit:

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

And here the code:
```
int BUTTON = 7;
int LED = 8;

void setup()
{
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
}

void loop()
{
  digitalWrite(LED, digitalRead(BUTTON));
}
```

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

title: Arduino pull-up resistor not working

Answers: 0


body:
I have an elegoo car model and am trying to make it turn 90 degrees whenever it gets to a 90 degree turn. This model has line tracing and it works fine on curved surfaces but doesn't work so on 90 degree turns.

        /Line Tracking IO define
    #define LT_R !digitalRead(10)//connected to pin 10. Value is inverted
    #define LT_M !digitalRead(4)
    #define LT_L !digitalRead(2)

    #define ENA 5//input to enable motor A. Controls speed
    #define ENB 6//input to enable motor B
    #define IN1 7//Control spinning direction of motor A. If one of them is high motor spin(an OR gate)
    #define IN2 8//Same motor A
    #define IN3 9//3 and 4 are for motor B
    #define IN4 11

    #define carSpeed 100

    void forward(){ //car goes forward
      analogWrite(ENA, carSpeed);
      analogWrite(ENB, carSpeed);
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      Serial.println("go forward!");
    }

    void back(){ //car goes backwards
      analogWrite(ENA, carSpeed);
      analogWrite(ENB, carSpeed);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      Serial.println("go back!");
    }

    void left(){ //goes left
      analogWrite(ENA, carSpeed);
      analogWrite(ENB, carSpeed);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      Serial.println("go left!");
    }

    void right(){ //goes right
      analogWrite(ENA, carSpeed);
      analogWrite(ENB, carSpeed);
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      Serial.println("go right!");
    }

    void stop(){ //power is shut off
       digitalWrite(ENA, LOW);
       digitalWrite(ENB, LOW);
       Serial.println("Stop!");
    }

    void setup(){
      Serial.begin(9600);
      pinMode(LT_R,INPUT);//takes input from all the sensors
      pinMode(LT_M,INPUT);
      pinMode(LT_L,INPUT);
    }

    void loop() {

      if(LT_M){
        forward();
        while(LT_M);
      }
      else if(LT_R) {
        right();
        while(LT_R);
      }
      else if(LT_L) {
        left();
        while(LT_L);
      }

      else if (LT_M && LT_R && !LT_L) {
      delay(500);
      right();
      }

      else if (LT_L && LT_R && !LT_R) {
       delay(500);
       left();
        }

title: How to make car turn 90 degrees?

Answers: 1

body:
First: Your code as 2 problems:

- As stated in the comments by PeterPaulKiefer, when you use

        pinMode(LT_R,INPUT);

    That is not working as intended by you. `LT_R` is defined at the top as

        #define LT_R !digitalRead(10)

    Thus the compiler will see

        pinMode(!digitalRead(10), INPUT);

    `digitalRead()` will return zero or one, thus you are configuring pin 0 or pin 1 here (depending on the state of the sensor at startup). Instead you need to directly use the pin number (10) or use another define for the pin number itself. Your code only works, because all the pins are configured as INPUT (tristate) at startup of the microcontroller, so that they don't break something with a wrong signal. You got lucky there.

- The last two else if statements are never executed:

        else if (LT_M && LT_R && !LT_L) {
            delay(500);
            right();
        }
        else if (LT_L && LT_R && !LT_R) {
            delay(500);
            left();
        }

    The conditions here will first evaluate `LT_M` (in the first statement) and `LT_L` (in the second statement) respectively. Only if these are true, the rest of the expression will be evaluated. But you already checked for both of them being true above. When they are, the following else if statements don't get executed (thats the logic of if else statements). And if they are false, the code will also not be executed.

    When you get to a 90° right corner, the middle and right sensor will trigger. Currently this will lead to the robot just keeping going forward.

So you need to change your code to actually check every every possible combination of the sensor states.

Also keep in mind, that a sharp corner needs way more turning, than a curve. Depending on the width of the line are the distance between your sensors, you might or might not be able to distinguish between those two cases. You should analyze, which sensor states you would have in which situations, write that down and then write code for every state. You could also put all sensor states into one single number, so that it is easier to check for it in the code. Something like this:

    byte all_states = digitalRead(2) + 2*digitalRead(4) + 4*digitalRead(10);

Each combination will give you a unique number to work with. Effectively this stores the states of the sensors in one bit of the number each. Bit 0 is for pin 2, bit 1 is for pin 4 and bit 2 is for pin 10. You can also write this with bitwise operators:

    byte all_states = digitalRead(2) | (digitalRead(4)<<1) | (digitalRead(10)<<2);

For example: If the right sensor is triggered, but not the others, you would get a binary number `0b00000100`, which is decimal `4`. If the left and the middle sensor are triggered, but not the right one, this results in `0b00000011`, which is decimal `3`. Then you could check with a switch statement:

    switch(all_states){
        case 0: //No sensors triggered
            break;
        case 1: // Left sensor triggered
            break;
        case 2: // middle sensor triggerd
            break;
        case 3: // middle and left sensor triggered
            break;
        ...
    }

You see how it works. The code for each case then goes inbetween of each case and break line.


body:
I want to simulate christmas lights and the different modes of lighting it can produce by pressing a button. I tried to do this by having a button pressed which changes an int variable (1-3) which then corresponds to 1 of 3 of my if statements that each have their own code that lights the leds in a different manner. What I have noticed is that if I were to press the button while my program is in the middle of executing one of these light modes, the operation is NOT interrupted and I'd have to wait for the operation to finish before I could press the button and switch to a different mode. As you know, in actual Christmas lights, this is not the case. One can easily switch between modes with a push of a button with no delays. How can I achieve this through code? P.S. I am a newbie in Arduino. My code is written below

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

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

    const int buttonPin =2;
    int ledPin[5] = {3,5,6,9,10};
    int counter = 1;
    int brightness = 0;
    void setup(){
     Serial.begin(9600);
     pinMode(buttonPin, INPUT);
       for(int i = 0; i<5; i++)
        {
           pinMode(ledPin[i], OUTPUT);
          Serial.println(ledPin[i]);
        }
    }
    void loop(){

      int reading = digitalRead(buttonPin);
      if (reading != 0){
        counter++;
     if(counter == 4)
        {
          counter = 1;
        }
      }

      if (counter == 1) // mode 1 of the christmas lights (default mode)
      {
        digitalWrite(3, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(10, HIGH);
        delay(300);
        digitalWrite(3, LOW);
        digitalWrite(6, LOW);
        digitalWrite(10, LOW);
     delay(300);
        digitalWrite(5, HIGH);
        digitalWrite(9, HIGH);
        delay(300);
        digitalWrite(5, LOW);
        digitalWrite(9, LOW);
        delay(300);
      }
      else if (counter == 2)// mode 2 of the christmas lights
      {
          for(brightness =0; brightness <= 255; brightness++)
          {
            analogWrite(3, brightness);
            analogWrite(5, brightness);
            analogWrite(6, brightness);
            analogWrite(9, brightness);
            analogWrite(10, brightness);
            delay(3);
          }
          for(brightness =255; brightness >= 0; brightness--)
          {
            analogWrite(3, brightness);
            analogWrite(5, brightness);
            analogWrite(6, brightness);
            analogWrite(9, brightness);
            analogWrite(10, brightness);
            delay(3);
          }
      }
      else if (counter == 3)// mode 3 of the christmas lights
      {

        for (int i = 0; i < 5; i++)
        {
            digitalWrite(ledPin[i], HIGH);
            delay(150);
          digitalWrite(ledPin[i], LOW);
            delay(150);
        }
        for (int i = 3; i > 0; i--)
        {
            digitalWrite(ledPin[i], HIGH);
            delay(150);
          digitalWrite(ledPin[i], LOW);
            delay(150);
        }
      }
    }

title: How to interrupt and direct my program where I want it to in the code by clicking a button?

Answers: 0


body:
I am stuck on this for a while, I am trying to generate a 100 hz square wave with 50% duty cycle in pin 3 and trying to verify it with wire at pin 4; I am getting 64000 but not 100 in serial monitor.

```

#define LEDPIN 3

uint16_t val2= pulseIn(4, HIGH);

ISR(TIMER1_COMPA_vect) { digitalWrite(LEDPIN, !digitalRead(LEDPIN)); }
void setup() {
Serial.begin(9600);
pinMode(LEDPIN, OUTPUT);
// initialize Timer1 (the 16-bit timer) using channel A output compare
noInterrupts(); // disable global interrupts
// TIMER 1 for interrupt frequency 100 Hz:
cli(); // stop interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 100 Hz increments
OCR1A = 19999; // = 16000000 / (8 * 100) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 8 prescaler
TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // allow interrupts
//TCCR1A = 0; // Timer/Counter Control Register 1A
//TCCR1B = 0; // (both control registers need to be configured)
//// set compare match register to desired timer count:
//OCR1A = 15624; // Output Compare Register 1A (i.e., for channel A)
//TCCR1B |= (1 << WGM12); // CTC (Clear Timer on Compare Match) mode
//TCCR1B |= (1 << CS10); // for 1,024 prescaler; UNO has a 16 MHz clock
//TCCR1B |= (1 << CS12);
//TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable global interrupts:
}
void loop() {
uint16_t val = OCR1A/8;

ICR1 = val -1;
OCR1A = val/2 - 1 ; // 50% duty cycle for pin 3
//OCR1B = val/2 - 1 ; // 50% duty cycle for pin 4
//uint16_t val2= pulseIn(4, HIGH);
Serial.print(val2);
delay(1000);
Serial.print("\n");

}

```

title: 100 hz Square Wave of 50% duty cycle in digital pin 3 and verifying with pin 4

Answers: 1

body:
You wrote:

```c++
uint16_t val2 = pulseIn(4, HIGH);
```

It makes no sense to call this here, as the timer has not been
initialized. You probably cannot expect anything but a timeout in this
context.

```c++
noInterrupts();
cli();
```

These two are synonyms. No need to repeat yourself. Actually, no need to
block interrupts at all.

```c++
sei();
interrupts();
```

Ditto.

```c++
OCR1A = 19999; // = 16000000 / (8 * 100) - 1
```

This is supposed to fire interrupts at 100 Hz. But if you want a
100 Hz output signal, you should fire the interrupts at 200 Hz
(two interrupts per cycle). Thus:

```c++
OCR1A = 9999; // = (16 MHz / 8) / (2 * 100 Hz) - 1
```

Then,

```c++
// Set CS12, CS11 and CS10 bits for 8 prescaler
TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);
```

This is configuring Timer 1 for an external clock source. If you
want ÷8 prescaler, you should only set bit `CS11`. Check the datasheet.

```c++
uint16_t val = OCR1A/8;
ICR1 = val -1;
OCR1A = val/2 - 1 ; // 50% duty cycle for pin 3
```

This doesn't make any sense to me. Why are you setting `ICR1`? Why are
you changing `OCR1A` although it was already configured in `setup()`?
You can remove all this. Here is the `loop()` I used for testing:

```c++
void loop() {
    Serial.println(pulseIn(3, HIGH));
    delay(1000);
}
```

And it repeatedly printed `4955`, which is quite close to the expected
value (namely 5000).


body: I've seen normal Arduino boards connecting to it no problem (Uno, Nano, etc.). I'm trying to connect it to my Seeeduino Xiao. It has UART compatible pins, so I'm fairly certain wiring isn't an issue. I think I'm having a hard time with the coding.

title: How do I set up communication between the "Seeeduino Xiao" and the "Adafruit Bluefruit LE UART Friend - Bluetooth Low Energy (BLE)"?

Answers: 1

body:
Nevermind, I figured it out. For anyone that has this problem to:

First, use the "blueart_cmdmode" example file. Then, follow these steps:

HOW TO GET THE SEEEDUINO XIAO TO WORK WITH THIS

1) Make sure the "Adafruit_BluefruitLE_UART ble(Serial1, BLUEFRUIT_UART_MODE_PIN);"
line of text above the "void error" line is UNCOMMENTED. Everything else in that
block is to still be commented.

2) Define the pins in "BluefruitConfig.h" as such:
#define BLUEFRUIT_SWUART_RXD_PIN       6    // Required for software serial!
#define BLUEFRUIT_SWUART_TXD_PIN       7    // Required for software serial!
#define BLUEFRUIT_UART_CTS_PIN         0    // Required for software serial!
#define BLUEFRUIT_UART_RTS_PIN         -1   // Optional, set to -1 if unused

3) Wire the pins as defined above.

4) Make sure the Bluefruit is switched to "CMD" mode.


body:
I want my ESP8266-based device to create an accesspoint that allows the user to input their home ssid and password. There is a device object that holds most of the data defined elsewhere.

I'm trying to use the ESP8266WebServer library. It requires me to define parameterless callback functions. Where should I declare and define these callback functions so that they can access the server object? In all the example code, the server object is global. I'd want to avoid that, and I'd also like to avoid having a server object as a permanent Device class member.

How should I go about this? It is not allowed to define the callback functions inside Device::getWifiCredentials, and if I declare them outside then server isn't in scope.

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

// Function to create AccessPoint to get ssid and password
int Device::getWifiCredentials() {

    ESP8266WebServer server(80);
    server.begin();

    // define callbacks
    server.on("/", handleRoot); // initial page

    server.on("/ssid", handleCredentials); // catch response from initial page

    // wait for credentials to be delivered
    server.handleClient();

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

    return ACTION_SUCCESSFUL;

}

// **Where can these functions be defined to allow them to access the server object?**

void handleRoot() {
};

void handleCredentials() {

    String ssid;
    String pw;

    if( server.hasArg() ){
        ssid = server.arg("ssid");
        pw = server.arg("pw");
    }
};
```

title: Where to define web server callback functions so they can access server object? (ESP8266WebServer library)

Answers: 1

body:
put your server declaraition outside the constructor and call a class callback :

    #include <Arduino.h>
    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>

    ESP8266WebServer server(80);

    // Function to create AccessPoint to get ssid and password
    int Device::getWifiCredentials() {
    server.begin();

        // define callbacks
        server.on("/", std::bind(&Device::handleRoot, this); // initial page

        server.on("/ssid", std::bind(&Device::handleCredentials, this); // catch response from initial page

        // wait for credentials to be delivered
        server.handleClient();

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

        return ACTION_SUCCESSFUL;
    }


body:
I need some help with my ideas please, I have a smart home system and I am trying to control the Philips hue light but without the bridge.
I want to do that by XBee S1 + FURTHER ESP 32.
so, who did that or have any ideas about how that can possible.
Any links, Videos, tutorials will be greater.
thanks all.

title: Controlling lights by XBee S1+ ESP32 without bridge

Answers: 0


body:
This is my log, honestly no idea what the problem is here, tried updating java, didnt work.
```

Sketch uses 11216 bytes (4%) of program storage space. Maximum is 262144 bytes.
Global variables use 2384 bytes (7%) of dynamic memory, leaving 30384 bytes for local variables. Maximum is 32768 bytes.
processing.app.debug.RunnerException
 at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
 at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
 at processing.app.SketchController.upload(SketchController.java:732)
 at processing.app.SketchController.exportApplet(SketchController.java:703)
 at processing.app.Editor$UploadHandler.run(Editor.java:2055)
 at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: Error touching serial port '/dev/ttyACM0'.
 at processing.app.Serial.touchForCDCReset(Serial.java:107)
 at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
 ... 5 more
Caused by: jssc.SerialPortException: Port name - /dev/ttyACM0; Method name - openPort(); Exception type - Permission denied.
 at jssc.SerialPort.openPort(SerialPort.java:170)
 at processing.app.Serial.touchForCDCReset(Serial.java:101)
 ... 6 more
```

title: Problem uploading my sketch onto my arduino. Arduino 1.8.13, Linux Ubuntu 20.4

Answers: 0


body:
**update** I have updated the code(second code segment) so that the null character is inserted into the array which solves the problem of writing past the end of the array. in order to stop the program from crashing i can only put the null character at the end of the array. this means that i need to increase the size of the array to accommodate for it. infuriatingly as soon as i do anything with the size variable, ie. size = size+1 the program takes a great deal longer to execute. i have no idea whats going on here so any help would be much appreciated. i have simplified the code further and the actual text file i am using on the server is included if anyone wanted to try it out. many thanks.

**original post**
i have written a sketch which uses the HTTPClient library to download 3 files from a server and write them to 3 SPIFFS files on an ESP32 using arduino IDE. It works fine but I am trying to improve the speed. The following code is the code which works:

    #include <Arduino.h>

    #include <WiFi.h>
    #include <WiFiMulti.h>

    #include <HTTPClient.h>

    #define Serial Serial

    WiFiMulti wifiMulti;

    #include <SPIFFS.h>

    #include "SPIFFS.h"

    #define FORMAT_SPIFFS_IF_FAILED true

    String url = "http://server.com";
    String fileName[] = {"/file1", "/file2", "/file3"};
    String fileSuf = ".dat";
    String imageSuf = ".gif";
    int fileIndex = 0;
    int numFiles = sizeof(fileName) / sizeof(fileName[0]);

    String filePath = url + fileName[fileIndex] + fileSuf;
    String imagePath = fileName[fileIndex] + imageSuf;

    void setup() {

      Serial.begin(115200);

      if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
        Serial.println("SPIFFS Mount Failed");
        return;
      }

      SPIFFS.format();

      ///connect to the internet
     wifiMulti.addAP("xxx", "xxx"); //work network

    //    download files
        while(fileIndex < numFiles){
          getFiles(); //retreive gif image
          fileIndex++;
        }
        fileIndex = 0;

    }

    void loop() {

    }

    long timer;
    int speed;

    void getFiles() {

      // wait for WiFi connection
      if ((wifiMulti.run() == WL_CONNECTED)) {

        //generate paths
        filePath = url + fileName[fileIndex] + fileSuf;
        imagePath = fileName[fileIndex] + imageSuf;

        Serial.println(filePath);
        Serial.println(imagePath);

        HTTPClient http;

        Serial.print("[HTTP] begin...\n");

        // configure server and url
        http.begin(filePath);
        timer = millis(); //set timer

        Serial.print("[HTTP] GET...\n");
        // start connection and send HTTP header
        int httpCode = http.GET();
        if (httpCode > 0) {
          // HTTP header has been send and Server response header has been handled
          Serial.printf("[HTTP] GET... code: %d\n", httpCode);

          // file found at server
          if (httpCode == HTTP_CODE_OK) {

            // get lenght of document (is -1 when Server sends no Content-Length header)
            int len = http.getSize();

            // create buffer for read
            byte buff[2048] = { 0 };

            // get tcp stream
            WiFiClient * stream = http.getStreamPtr();

            // read all data from server
            while (http.connected() && (len > 0 || len == -1)) {

              // get available data size
              size_t size = stream->available();

              if (size) { ///
                // read up to 128 byte
                int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); //calculate size of buffer(is it full?)

                appendFile(SPIFFS, imagePath, buff, c); //addi buffer to file in flash

                if (len > 0) {
                  len -= c;
                }
              }
            }

            Serial.println();
            Serial.print("[HTTP] connection closed or file end.\n");

          }
        } else {
          Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        speed = millis() - timer;
        Serial.println(speed); //print time taken in millis;
        http.end();

      }

    }

    void appendFile(fs::FS &fs, String _path, byte message[], int arr_size) {

      File file = fs.open(_path, FILE_APPEND);

       file.write(message,arr_size);

    }

So thats all well and good but i experimented with how to speed it up.The following code finishes the task of downloading and writing to flash in a third of the time but because i pass the array to the print method without telling it where the buffer ends it prints 'junk' bytes on the end making the file corrupted.

My question is, why is my working method so much slower than the other method. is there any way i can get the same speed as method 2 but without printing the unwanted bytes each time? it seems like i should be able to specify this without sacrificing so much speed.

as an example of the speed file1 took 9102 ms to complete in the first approach and 3303 ms in the second. a big difference! any advice would be much appreciated, thanks!
Heres the second approach' code:
(The only changes are changing the buffer array from byte to char and using file.print(message) in the appendFile function instead of file.write(message,array_size);

    #include <Arduino.h>

    #include <WiFi.h>
    #include <WiFiMulti.h>

    #include <HTTPClient.h>

    #define Serial Serial

    WiFiMulti wifiMulti;

    #include <SPIFFS.h>

    #include "SPIFFS.h"

    #define FORMAT_SPIFFS_IF_FAILED true

    String path = "/test.txt";
    String filePath = "http://gonadgranny.atwebpages.com/text.txt";

    void setup() {

      Serial.begin(115200);

      if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
        Serial.println("SPIFFS Mount Failed");
        return;
      }

      SPIFFS.format();

      ///connect to the internet
     wifiMulti.addAP("xxx", "xxx"); //work network

          getFiles(); //retreive gif image

    }

    void loop() {
      readFile(SPIFFS, path);
      delay(5000);

    }

    long timer;
    int speed;

    void getFiles() {

      // wait for WiFi connection
      if ((wifiMulti.run() == WL_CONNECTED)) {

        //generate paths

        Serial.println(filePath);
        Serial.println(path);

        HTTPClient http;

        Serial.print("[HTTP] begin...\n");

        // configure server and url
        http.begin(filePath);
        timer = millis(); //set timer

        Serial.print("[HTTP] GET...\n");
        // start connection and send HTTP header
        int httpCode = http.GET();
        if (httpCode > 0) {
          // HTTP header has been send and Server response header has been handled
          Serial.printf("[HTTP] GET... code: %d\n", httpCode);

          // file found at server
          if (httpCode == HTTP_CODE_OK) {

            // get lenght of document (is -1 when Server sends no Content-Length header)
            int len = http.getSize();

            // create buffer for read
            char buff[2048] = { 0 };

            // get tcp stream
            WiFiClient * stream = http.getStreamPtr();

            // read all data from server
            while (http.connected() && (len > 0 || len == -1)) {

              // get available data size
              size_t size = (stream->available()) ; //make one bigger

              if (size) { ///
                // read up to 128 byte
                int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); //calculate size of buffer(is it full?)

                appendFile(SPIFFS, path, buff, c); //addi buffer to file in flash

                if (len > 0) {
                  len -= c;
                }
              }
            }

            Serial.println();
            Serial.print("[HTTP] connection closed or file end.\n");

          }
        } else {
          Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        speed = millis() - timer;
        Serial.println(speed); //print time taken in millis;
        http.end();

      }

    }

    void appendFile(fs::FS &fs, String _path, char message[], int arr_size) {

      message[(arr_size-1)] = '\0'; //put in end of array

      File file = fs.open(_path, FILE_APPEND);

       file.print(message);

    }

    void readFile(fs::FS &fs, String path) {
      Serial.printf("Reading file: %s\r\n", path);

      File file = SPIFFS.open(path);
      if (!file || file.isDirectory()) {
    //    Serial.println("- failed to open file for reading");
        return;
      }

    //  Serial.println("- read from file:");
      while (file.available()) {
        Serial.write(file.read());
      }
    }

title: Trying to improve speed of downloading files from server and writing to SPIFFS

Answers: 0


body:
I am trying to find out if it is possible to trigger programmatically the *double-tap on reset button* function, implemented in modified version of Atmel's SAM-BA bootloader. The board of interest is Arduino Zero.
In case this is not possible using the stock board setup, if this can be achieved by hardware or bootloader modifications.

title: Forcing bootloader startup through program

Answers: 1

body:
Theoretically it is quiet easy to fake that double-tap with software, but there might be some obstacles in practice.

The bootloader uses an unsigned long value in RAM memory to indicate if the double tap happend. The actual bootloader for the zero uses the following definitions.

    // zero specific; but other boards use the same values AFAIK
    // (in board_definitions_arduino_zero.h)
    #define BOOT_DOUBLE_TAP_ADDRESS  (0x20007FFCul)
    #define BOOT_DOUBLE_TAP_DATA  (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))

    // for all bootloader (in main.c)
    #define DOUBLE_TAP_MAGIC 0x07738135

When the bootloader is started after a reset, it checks, if that was a power on reset (POR) or not. If it has been a POR, it sets the indicator value to 0 `BOOT_DOUBLE_TAP_DATA = 0;`.

If it does not detect a POR, the bootloader continues with checking the indicator value whether it is set to the tap magic.

If the magic can be found  the indicator value is set back to 0 and the bootloader is started. Otherwise the value is set to the "double tap magic": `BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC`. The bootloader waits for 500 ms to let the user reset the zero a second time (double tap) and resets the indicator value after that time interval.

-------

**How to:**

To simulate a double tap, you just need to set the indicator variable with the magic value from within you program. Use the definitions above. Then perform a software reset.

-------

**The caveats:**

* If the bootloader was changed, that could make you code useless.
* I have not the time to test my ideas, so this is just an unverified method. It might fail for some reasons, I do not see actually.
* You have to find a method to reset the zero with the program. Iknow some methods but I've not tried any of them so far.

-------

**Reset Methods:** (as a starting point for your search)

I've read somewhere that the zero supports the CMSIS method `NVIC_SystemReset`.

This is a method often used for M0 ARM controllers (like SAMD11).

    SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK;

-------

Here is my code "idea" (untested):

    #define BOOT_DOUBLE_TAP_ADDRESS  (0x20007FFCul)
    #define BOOT_DOUBLE_TAP_DATA  (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))
    #define DOUBLE_TAP_MAGIC 0x07738135

    // lots of code ....

    void resetWithDoubleTap()
    {
       BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC;
       NVIC_SystemReset();
    }

-------

I would be lucky, if you succeed with this. Please let us know your outcomes, either write your own answer or tell me what you've done and I will correct my answer if necessary. Good luck.


body:
For the initial settings of WiFi cerdentials and configuration on a standalone device (ESP32), I try to implement a captive portal using the `CaptivePortal` example for ESP32 `DNSServer` (see [original source][1]). I'm using Arduino IDE 1.8.13 and ESP32 core 1.0.4.

Different from the cited source, the example reads (as often seen in posts for that):

    IPAddress apIP(192, 168, 1, 1);

This works well when connecting my laptop and opening firefox, which the tells me I'ld have to sign in by opening a signin-page.

This does not work with my android phone. It always tells me "no connection to internet".

In the latest version of the ESP core as cited above, the IP address is modified to

    IPAddress apIP(8,8,4,4); // The default android DNS

This in fact works, even with android device.

I now tried different IP addresses (`192.168.4.1`, `8.8.8.8`, `142.250.186.131`, which is `connectivitycheck.gstatic.com` in real life, and some more). What did happen:

- Using an address out of the private pool (`192.168.x.y`) did lead to "No connection to the internet"
- Using any of the public addresses did open the portal page.

I updated the DNSServer library to version 1.0.5 of the core, as that allowed for debugging the dns server. Additionally, I added some Serial prints for debugging. Using 192.168.1.1, the output reads:

    dhcps: send_offer>>udp_sendto result 0
    [D][WiFiGeneric.cpp:337] _eventCallback(): Event: 18 - AP_PROBEREQRECVED
    DNS responds: 192.168.1.1 for epdg.epc.mnc002.mcc262.pub.3gppnetwork.org
    DNS responds: 192.168.1.1 for north-america.pool.ntp.org
    DNS responds: 192.168.1.1 for mtalk.google.com
    DNS responds: 192.168.1.1 for connectivitycheck.gstatic.com
    DNS responds: 192.168.1.1 for connectivitycheck.gstatic.com
    DNS responds: 192.168.1.1 for alt4-mtalk.google.com
    DNS responds: 192.168.1.1 for gstatic.com
    DNS responds: 192.168.1.1 for android.googleapis.com
    DNS responds: 192.168.1.1 for google.com

     --- Begin http request ---
    GET / HTTP/1.1
    User-Agent: Dalvik/2.1.0 (Linux; U; Android 7.0; SM-A310F Build/NRD90M)
    Host: 192.168.1.1
    Connection: Keep-Alive
    Accept-Encoding: gzip

     --- End http request ---

    DNS responds: 192.168.1.1 for connectivitycheck.gstatic.com
    DNS responds: 192.168.1.1 for connectivitycheck.gstatic.com
    DNS responds: 192.168.1.1 for android.clients.google.com
    DNS responds: 192.168.1.1 for google.com
    DNS responds: 192.168.1.1 for service.game-mode.net
    DNS responds: 192.168.1.1 for play-lh.googleusercontent.com
    DNS responds: 192.168.1.1 for play.googleapis.com
    DNS responds: 192.168.1.1 for connectivitycheck.gstatic.com
    DNS responds: 192.168.1.1 for gld.push.samsungosp.com
    DNS responds: 192.168.1.1 for googleapis.com
    DNS responds: 192.168.1.1 for ssl.google-analytics.com
    DNS responds: 192.168.1.1 for beacons.gvt2.com
    DNS responds: 192.168.1.1 for connectivitycheck.gstatic.com
    DNS responds: 192.168.1.1 for connectivitycheck.gstatic.com
    DNS responds: 192.168.1.1 for google.com
    DNS responds: 192.168.1.1 for yahoo.com

     --- Begin http request ---
    GET / HTTP/1.1
    Connection: close
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,en;q=0.4
    User-Agent: Dalvik/2.1.0 (Linux; U; Android 7.0; SM-A310F Build/NRD90M)
    Host: www.yahoo.com

     --- End http request ---

and some more of these.

Using e.g. 142.250.186.131, this reads different:

    dhcps: send_offer>>udp_sendto result 0
    [D][WiFiGeneric.cpp:337] _eventCallback(): Event: 18 - AP_PROBEREQRECVED
    DNS responds: 142.250.186.131 for epdg.epc.mnc002.mcc262.pub.3gppnetwork.org
    DNS responds: 142.250.186.131 for connectivitycheck.gstatic.com
    DNS responds: 142.250.186.131 for connectivitycheck.gstatic.com
    DNS responds: 142.250.186.131 for north-america.pool.ntp.org
    DNS responds: 142.250.186.131 for capi.samsungcloud.com
    DNS responds: 142.250.186.131 for mtalk.google.com
    DNS responds: 142.250.186.131 for alt2-mtalk.google.com

     --- Begin http request ---
    GET /generate_204 HTTP/1.1
    Host: connectivitycheck.gstatic.com
    Connection: close
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    User-Agent: Dalvik/2.1.0 (Linux; U; Android 7.0; SM-A310F Build/NRD90M
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,en;q=0.4

     --- End http request ---

    DNS responds: 142.250.186.131 for connectivitycheck.gstatic.com
    DNS responds: 142.250.186.131 for android.googleapis.com

     --- Begin http request ---
    GET / HTTP/1.1
    User-Agent: Dalvik/2.1.0 (Linux; U; Android 7.0; SM-A310F Build/NRD90M)
    Host: 142.250.186.131
    Connection: Keep-Alive
    Accept-Encoding: gzip

     --- End http request ---

    DNS responds: 142.250.186.131 for service.game-mode.net
    DNS responds: 142.250.186.131 for android.clients.google.com

     --- Begin http request ---
    GET /generate_204 HTTP/1.1
    Host: connectivitycheck.gstatic.com
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Linux; Android 7.0; SM-A310F Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    X-Requested-With: com.android.captiveportallogin
    Accept-Encoding: gzip, deflate
    Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7

     --- End http request ---

So, the HTTP requests are

    GET / HTTP/1.1
    Host: 192.168.1.1

(and some other hosts) if using private network address, and

    GET /generate_204 HTTP/1.1
    Host: connectivitycheck.gstatic.com

if using public network address.

My question:

Is there any reason that android systems act different on addresses from the private address space than from the public one? And if so, is it safe to use e.g. `8.8.4.4` for all kinds of client systems (android, ios, linux, windows, ...)?

**Edit:**

I tried `10.0.0.1` and `172.16.0.1` (the other two private network spaces), but android does not like them as well; @dandavis seems to be right. Now I use `192.9.200.1` which works well.

Why that address?

Some history: When in the late 1980s and early 1990s companies began to use IP networks in combination with SUN computers, many "network administrators" followed a documentation by SUN how to configure those networks. In that documentation, the address range `192.9.200.0/24` was used as an example; it was part of SUNs own network range. So many (if not all) of those people used this address range, not knowing that they should use other (private) addresses.

The address range 192.9.0.0/16 nowadays is owned by Oracle, but they seem not to use 192.9.200.0/24. If you search for "192.9.200.0", you may still find lots of documentation containing exactly those example addresses.

  [1]: https://github.com/espressif/arduino-esp32/blob/master/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino

title: ESP32 captive portal not working with private IP address for android

Answers: 0