body:
I created a circuit of a 25 key IR remote controller for my RuneAudio device. The device is a standalone ATmega328P-PU running at 3V (2 AAA batteries) with 8 MHz internal clock. The circuit has 5 rows and 5 columns and uses Arduino keypad library. The code is mostly a copy of Nick Gammon's code (http://www.gammon.com.au/forum/?id=11497&reply=4#reply4), with slight modification for my purpose.

Following is the circuit (R1=1K, R2=10K, R3=62 Ohm):

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

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

Following is the code I am using:

    #include <Keypad.h>
    #include <avr/sleep.h>
    #include <avr/power.h>
    #include <IRremote.h>

    const byte ROWS = 5;
    const byte COLS = 5;
    byte keynum;

    char keys[ROWS][COLS] =
    {
      {'E', 'D', 'C', 'B', 'A'},
      {'J', 'I', 'H', 'G', 'F'},
      {'O', 'N', 'M', 'L', 'K'},
      {'T', 'S', 'R', 'Q', 'P'},
      {'Y', 'X', 'W', 'V', 'U'}
    };

    byte rowPins[ROWS] = {9, 10, 11, 12, 13}; // Keypad row pins
    byte colPins[COLS] = {4, 5, 6, 7, 8};     // Keypad column pins

    unsigned long IRCode[25] =  {0xB54A38C7, 0xB54A30CF, 0xB54AE191, 0xB54ADCDD, 0xB54AD6C3, 0xB54AE5ED, 0xB54A50AF, 0xB54A9867, 0xB54AB04F, 0xB54A48B7, 0xB54AD02F, 0xB54AFCF7, 0xB54AF56C, 0xB54AEFEE, 0xB54AEAA0, 0xB54A02FD, 0xB54B176F, 0xB54B100D, 0xB54B08F6, 0xB54B031D, 0xB54A42BD, 0xB54AC23D, 0xB54A1AE5, 0xB54A7887, 0xB54A827D};

    // Number of items in an array
    #define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))

    // IR setup (NEC remote)
    const byte IRledPin = 3;
    const int NumBits = 32;

    // Define
    Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
    IRsend irsend;

    // turn off interrupts until we are ready
    ISR (PCINT0_vect)
      {
      PCICR = 0;  // cancel pin change interrupts
      } // end of ISR (PCINT0_vect)

    ISR (PCINT1_vect)
      {
      PCICR = 0;  // cancel pin change interrupts
      } // end of ISR (PCINT1_vect)

    ISR (PCINT2_vect)
      {
      PCICR = 0;  // cancel pin change interrupts
      } // end of ISR (PCINT2_vect)

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

      // Pin change interrupt masks (See list on Nick Gammons original code)
      PCMSK0 |= bit (PCINT1);   // Pin 9
      PCMSK0 |= bit (PCINT2);   // Pin 10
      PCMSK0 |= bit (PCINT3);   // Pin 11
      PCMSK0 |= bit (PCINT4);   // Pin 12
      PCMSK0 |= bit (PCINT5);   // Pin 13
      Serial.begin(9600);
    }

    void reconfigurePins ()
    {
    Serial.print("1 Reconfig pins");
    Serial.println("");
      byte i;
      for (i = 0; i < NUMITEMS (colPins); i++)
      {
        pinMode (colPins [i], OUTPUT);
        digitalWrite (colPins [i], HIGH);
      }

      for (i = 0; i < NUMITEMS (rowPins); i++)
        {
        pinMode (rowPins [i], INPUT_PULLUP);
        }   // end of for each row
    Serial.print("2 DONE Reconfig pins");
    Serial.println("");
      }  // end of reconfigurePins

    void goToSleep ()
    {
    Serial.print("3 inside SLEEP");
    Serial.println("");

      // Set up keypress detection
      byte i;
      for (i = 0; i < NUMITEMS (colPins); i++)
      {
        pinMode (colPins [i], OUTPUT);
        digitalWrite (colPins [i], LOW);
      }

      for (i = 0; i < NUMITEMS (rowPins); i++)
      {
        pinMode (rowPins [i], INPUT_PULLUP);
      }  // end of for each row

      // Check no pins pressed (otherwise wake on a key release)
      for (i = 0; i < NUMITEMS (rowPins); i++)
      {
        if (digitalRead (rowPins [i]) == LOW)
        {
      Serial.print("ROW LOW: ");
      Serial.print(rowPins [i]);
    Serial.println("");
          reconfigurePins ();
          return;
        }
      }

      // Overcome any debounce delays built into the keypad library
      delay (10);

      // At this point, pressing a key should connect the high in the row to the
      // to the low in the column and trigger a pin change
    Serial.print("4 Going to SLEEP");
    Serial.println("");

      set_sleep_mode (SLEEP_MODE_PWR_DOWN);
      sleep_enable();

    Serial.print("5 AWAKE");
    Serial.println("");

      byte old_ADCSRA = ADCSRA;
      // Disable ADC to save power
      ADCSRA = 0;

      power_all_disable ();  // turn off various modules

      PCIFR  |= bit (PCIF0) | bit (PCIF1) | bit (PCIF2);   // clear any outstanding interrupts
      PCICR  |= bit (PCIE0) | bit (PCIE1) | bit (PCIE2);   // enable pin change interrupts

      // Turn off brown-out enable in software
      MCUCR = bit (BODS) | bit (BODSE);
      MCUCR = bit (BODS);
      sleep_cpu ();

      // Cancel sleep as a precaution
      sleep_disable();
      power_all_enable ();   // enable modules again
      ADCSRA = old_ADCSRA;   // re-enable ADC conversion

      // Put keypad pins back how they are expected to be
      reconfigurePins ();
    Serial.print("6 Leaving SLEEP");
    Serial.println("");

    }

    void loop ()
    {

      byte key =  kpd.getKey();
      if (!key)
      {
    Serial.print("CALLING SLEEP");
    Serial.println("");

        // Sleep if no key is pressed
        goToSleep ();
        return;
     Serial.print("After RETURN");
    Serial.println("");

      }

      // Subtract ASCII value of first key value to obtain HEX array argument
      keynum = key - 'A';
    Serial.print("SENDING IR.....................................................................................");
    Serial.println("");

      // sendNEC(unsigned long data, int nbits);
      irsend.sendNEC(IRCode[keynum], NumBits);
    Serial.print(IRCode[keynum]);
    Serial.println("");

    }

The sketch compiles and uploads just fine. It detects key presses and sends out IR signals. But it misses around half of the key presses. I am testing on a breadboard using a single key - R1C5 (S5 in the schematic).

I must admit that despite spending a lot of time on ATmega328 datasheet and Nick's blogs on power saving, I am not able to fully understand the power saving features due to my not-so-mature skills and the complexity of overall project (Raspberry Pi based rune audio + TDA7439 based tone controller + ATmega based power switch for Pi + 2channel Audio amplifier + this IR remote).

I added a few serial prints to check what is happening. The serial outs seem to be out of sync and last message before sleep is "CALLING SLEEP" whereas I expected it to be "4 Going to SLEEP". And adding serial print mysteriously reduces the number of misses.

Following is the serial output, just after power on and a single key press:

    EP
    3 inside SLEEP
    4 Going to SLEEP
    5 AWAKE
    1 Reconfig pins
    2 DONE Reconfig pins
    6 Leaving SLEEP
    SENDING IR.....................................................................................
    3041540295
    CALLING SLEEP
    3 inside SLEEP
    ROW LOW: 9
    1 Reconfig pins
    2 DONE Reconfig

The following happens after multiple key presses:

    CALLING SLEEP
    3 inside SLEEP
    ROW LOW: 9
    1 Reconfig pins
    2 DONE Reconfig pins
    SENDING IR.....................................................................................
    3041540295
    CALLING SLEEP
    3 inside SLEEP
    ROW LOW: 9
    1 Reconfig pins
    2 DONE Reconfig pins
    CALLING SLEEP
    3 inside SLEEP
    ROW LOW: 9
    1 Reconfig pins
    2 DONE Reconfig
    CALLING SLEEP
    3 inside SLEEP
    4 Going to SLEEP
    5 AWAKE
    1 Reconfig pins
    2 DONE Reconfig pins
    6 Leaving SLEEP
    CALLING SLEEP
    3 inside SLEEP
    ROW LOW: 9
    1 Reconfig pins
    2 DONE Reconfig
    CALLING SLEEP
    3 inside SLEEP
    4 Going to SLEEP
    5 AWAKE
    1 Reconfig pins
    2 DONE Reconfig pins
    6 Leaving
    CALLING SLEEP
    3 inside SLEEP
    4 Going to SLEEP
    5 AWAKE
    1 Reconfig pins
    2 DONE Reconfig pins
    6 Leaving
    CALLING SLEEP
    3 inside SLEEP
    4 Going to SLEEP
    5 AWAKE
    1 Reconfig pins
    2 DONE Reconfig pins
    6 Leaving
    CALLING SLEEP
    3 inside SLEEP
    4 Going to SLEEP
    5 AWAKE
    1 Reconfig pins
    2 DONE Reconfig pins
    6 Leaving
    CALLING SLEEP
    3 inside SLEEP
    4 Going to SLEEP
    5 AWAKE
    1 Reconfig pins
    2 DONE Reconfig pins
    6 Leaving SLEEP
    CALLING SLEEP
    3 inside SLEEP
    ROW LOW: 9
    1 Reconfig pins
    2 DONE Reconfig pins
    SENDING IR.....................................................................................
    3041540295
    CALLING SLEEP
    3 inside SLEEP
    ROW LOW: 9
    1 Reconfig pins
    2 DONE Reconfig

It would be of great help if someone could show me the light here.

--------------------------

Ok. Replaced long serial print strings with single digits where these stand for:
1= 1 Reconfig pins
2= 2 DONE Reconfig pins
3= 3 inside SLEEP
4= ROW LOW=
5= 4 Going to SLEEP
6= 5 AWAKE
7= 6 Leaving SLEEP
8= CALLING SLEEP
.....= SENDING IR

I see where it is failing.  Now getting the following serial out:

    6
    1
    2
    7
    8
    3
    49
    1
    2
    8
    3
    49
    1
    2
    8
    3
    49
    1
    2
    8
    3
    49

So the program wakes on keypress (6), then reconfigures the pins (1,2), leaves the sleep function (7) enaters the main (8). Here `byte key =  kpd.getKey()` DOES NOT detect a keypress and calls sleep again (3). Sleep DOES detect a low row 9 (4-9).
After this it gets stuck in a loop of main and sleep functions till key press is over. For now the problem seems to be with kpd.getKey().

title: Arduino based IR remote control - Transmission issue

Answers: 1

body:
> I added a few serial prints to check what is happening. The serial outs seem to be out of sync and last message before sleep is "CALLING SLEEP" whereas I expected it to be "4 Going to SLEEP".

Printing to Serial doesn't send data to your computer. It just adds that data to a TX buffer, and then an interrupt sends each character one byte at a time.

Your prints are happening, but aren't being sent from the queue before the MCU goes to sleep.

You should add

    Serial.flush();

before actually going to sleep to ensure that all data from the TX buffer has been sent. That way your messages will actually be meaningful.

Also if you send more than 64 bytes of data through Serial in a short space of time it will block and wait for some data to be sent out of the TX buffer. The buffer is only 64 bytes in size, so if there is no room left it has to wait for the interrupt.  That waiting slows your entire sketch down and can affect the way the sketch operates.  A bit like quantum physics - the act of observing the operation of the sketch changes the operation of the sketch.


body:
I'm really new at electronics and wiring, so please be kind. Coding is my stuff, but I'm trying to learn something here.

I'm working with a project to store the movements of a skateboard through a MPU 9235 and the idea is to save the output of the sensor to a MicroSD.

I have both components and acquired a LiPO 3.7v 400mAh to take everything off the protoboard and attach at the bottom of the skateboard.

The code is working, everything code wise is working ok, but I'm strugging to understand how to power both MicroSD module and MPU9235, since both have the VCC pin (VDD in some versions).

The current connections are replicated in Fritzing. Only replacing Arduino Uno for an Arduino Nano, and the MPU 6050 from the picture for a MPU9235.

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

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

My first thought was to connect the LiPo battery into VIN and GND pins of Nano. From there I believe that I can wire up the 3V3 output directly to VCC from MPU9235.

But what about the MicroSD module?

How would I power its VCC pin since I have no 3V3 pin left? I read that it's not right to use a digital pin as power output.

How can I connect two components that needs power from external source?

title: How to connect both MicroSD module and MPU9235 power in an arduino

Answers: 1

body:
VIN takes 6-12v and it sends it through the on board regulator - so that is the best way to power the nano.

If you take a wire from the 3v3 pin and split it (solder two wires to one) then you will have two 3v3 feeds to wire to your two devices.  This will be the same as you have to do for the Gnd connections, back to the Nano.

Does that make sense? (if not I'll try and draw you something).


body:
What are the differences in serial communication between PC <---> Arduino UNO (ATMEGA328p) and PC <---> Arduino Leonardo (ATMEGA32u4)?

I am asking because of a problem related to using these two Arduino boards for data logging in the following way:

 1. PC sends a specific char string to Arduino, via serial port, to initialize datalogging
 2. Arduino measures data, let's say a fixed number of ADC readings
 3. Arduino stops measuring, sends data back to the PC over serial port
 4. Arduino waits until new serial data are received before logging new data

If I send/receive data via the Arduino IDE serial monitor, this procedure works on both boards.  However, I want a separate GUI program (Qt) to handle the serial communication, where one clicks a button to send the data in step 1, and plot the data from step 3 on a graph.

I wrote a simple Qt GUI where a button is clicked, and the measured data are printed to the GUI screen.  Observations while testing it:

 - **Arduino UNO as datalogger**: Arduino is plugged into USB socket of PC, then I launch the GUI, then click button to start data acquisition.  The data are shown.  Program appears to work fine.
 - **Arduino Leonardo as datalogger**: Arduino is plugged into USB socket of PC, then I launch the GUI, then click button to start data acquisition.  The data are not received, program hangs.

Then

 - **Arduino Leonardo as datalogger**: Arduino is plugged into USB socket of PC, **Open Arduino IDE serial monitor, send command to acquire data**.  Then close Arduino IDE serial monitor, launch the GUI, click button to start data acquisition.  The GUI program now works.

Long story, but basically there appears to be a difference when using the two Arduino boards with external programs to do serial communication.  Can someone outline the differences and why Leonardo needs the "jump start" I described above using Arduino serial monitor?  Ultimately I want to fix the problem and avoid that hack.

Reluctant to post Qt code on Arduino stack exchange, but here is how I start the serial port:
<!-- language-all: lang-cpp -->

    ui->setupUi(this);
    microcontroller_is_available = false;
    microcontroller_port_name = "false";
    microcontroller = new QSerialPort(this);
    qDebug() << "Number of available ports: " << QSerialPortInfo::availablePorts().length();
    foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
        qDebug() << "Has product ID " << serialPortInfo.hasProductIdentifier();
        if(serialPortInfo.hasProductIdentifier()){qDebug() << "Product ID: " << serialPortInfo.productIdentifier();}
        qDebug() << "Has vendor ID " << serialPortInfo.hasVendorIdentifier();
        if(serialPortInfo.hasVendorIdentifier()){qDebug() << "Vendor ID: " << serialPortInfo.vendorIdentifier();}
    }

    foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) {
       if(serialPortInfo.hasVendorIdentifier() && serialPortInfo.hasProductIdentifier()){
           if(serialPortInfo.vendorIdentifier() == micro_vendor_id){
               if(serialPortInfo.productIdentifier() == micro_product_id){
                  microcontroller_port_name = serialPortInfo.portName();
                  microcontroller_is_available = true;
               }
           }
       }
    }

    if(microcontroller_is_available){  // open and configure serialport
        microcontroller->setPortName(microcontroller_port_name);
        microcontroller->open(QSerialPort::ReadWrite);
        microcontroller->setBaudRate(QSerialPort::Baud115200);
        microcontroller->setDataBits(QSerialPort::Data8);
        microcontroller->setParity(QSerialPort::NoParity);
        microcontroller->setStopBits(QSerialPort::OneStop);
        microcontroller->setFlowControl(QSerialPort::NoFlowControl);
    }
    else{QMessageBox::warning(this, "Port error", "Cannot connect DAQ.");}

Setup part of my Arduino code:

    void setup(){
      DDRB  |= B11111111;  // (654210 outputs, miso input)
      PORTB &= ~_BV(RF_AMPL);
      DDRD  |= B1100010;
      PORTD |= (_BV(SRAM_HOLD) | _BV(SRAM_SS1));
      ADCSRA=0;
      SPCR = B01010000;           // SPI init (could get away with 11010000 on 328p but not 32u4)
      SPSR = B00000001;
      PORTD &= ~_BV(SRAM_SS1);     // Slave init
      SPDR=WRMR;  while(!(SPSR & (1<<SPIF)));
      SPDR=SEQUENTIAL_MODE; while(!(SPSR & (1<<SPIF)));
      PORTD |= _BV(SRAM_SS1);
      __builtin_avr_delay_cycles(160);
      PORTD &= ~_BV(SRAM_SS1);
      SPDR=RDMR; while(!(SPSR & (1<<SPIF)));
      SPDR=0x00; while(!(SPSR & (1<<SPIF)));
      PORTD |= (_BV(SRAM_HOLD) | _BV(SRAM_SS1));
      state1=0;
      count=0;
      pulse_count=0;
      serial_counter=0;
      Serial.begin(115200);  while(!Serial){}
    }

title: Do serial ports on Arduino UNO / Leonardo initialize differently?

Answers: 2

body:
Yes, there are differences.

* The Uno has an ATMega16U2 as a USB to UART bridge.  When you open the serial port the ATMega16U2 signals to the ATMega328p to reset and start your sketch from the beginning.
* The Leonardo has an ATMega32U4 as the main MCU which is directly connected to the USB port.  When you open the serial port you connect to your program wherever it happens to be at the time.

The key thing there is that when you open the Uno's port the board reboots and your sketch restarts. When you open the Leonardo's port the board *doesn't* reset and your sketch is wherever your sketch happens to be.

So: you have to ensure that your sketch doesn't rely on things in setup() or early on in its execution for making the serial connection work.

body:
I solved this by resetting the Arduino (open serial port at 1200 baud, then close serial port) when launching the Qt program.

Here is the relevant part of the Qt program:

            microcontroller->setPortName(microcontroller_port_name);
            microcontroller->open(QSerialPort::ReadWrite);
            microcontroller->setBaudRate(QSerialPort::Baud1200);
            microcontroller->setDataBits(QSerialPort::Data8);
            microcontroller->setParity(QSerialPort::NoParity);
            microcontroller->setStopBits(QSerialPort::OneStop);
            microcontroller->setFlowControl(QSerialPort::HardwareControl);

            qDebug() << "open 1200 baud";
            Sleep(10);
            microcontroller->close();
            Sleep(10);

            microcontroller->open(QSerialPort::ReadWrite);
            microcontroller->setBaudRate(QSerialPort::Baud115200);
            microcontroller->setDataBits(QSerialPort::Data8);
            microcontroller->setParity(QSerialPort::NoParity);
            microcontroller->setStopBits(QSerialPort::OneStop);
            microcontroller->setFlowControl(QSerialPort::HardwareControl);

Now whenever I launch the Qt program, the Arduino is ready to accept serial data.


body:
I have searched everywhere, but can you please help me to get this Byte into int, there are alot of examples on the internet, but not for a beginer like me

CODE:

    int Button[] = {2, 4, 7 };

    byte E = sizeof(Button);

    int I = (int) E;

    void setup() {

      Serial.begin(9600);

      Serial.print (I); // has to be 3, currently 61

      }

    void loop() {

     }

I don't know why the byte E doen't convert to a int in int I by using the  (int)E command, what would also be convinient would be to read the amount of elements directly  as an int .
(you might wonder, why I want to do this, it is beacause, I am writing a program with multiple buttons, so I just want to add another pin to the array and not have to change the "I" int( the I int is used for loops))

title: How to change byte to int? - Arduino

Answers: 2

body:
The code works correctly. The function `sizeof()` returns the number of bytes in a variable, not the number of elements. Your array is of type `int`, which consists of 2 bytes each. So in sum you get 6 bytes for the whole array.

What you want to do (calculating the number of elements in the array) is to divide the number of bytes in the array by the number of bytes for one element:

    int I = sizeof(Button)/sizeof(Button[0]);

The conversion from `byte` to `int` worked correctly, but you really don't need it. You can calculate things with both types the same way. The only difference is the value range. Since a negative element number doesn't make sense and you surely don't want to define more than 255 buttons, you can choose yourself, what you want to use. Using `byte` would save you one byte of memory.

body:
`sizeof` returns the size in bytes. int is two bytes in 8-bit AVR mcu. an array of 3 ints has 6 bytes.

return type of `sizeof` is `size_t` which in 8-bit AVR is same as unsigned int


body:
I am using the SoftAP feature of the ESP to create a central node, and connecting five or six clients in the final application. However, I don't know if i can connect that many clients.

One of the core files on GitHub, `esp_wifi_types.h` shows two conflicting lines:

    #line 215, as a member of the 'wifi_ap_config_t' struct
    uint8_t max_connection; /**< Max number of stations allowed to connect in, default 4, max 4 */

    #line 254
    #define ESP_WIFI_MAX_CONN_NUM (10) /**< max number of stations which can connect to ESP32 soft-AP */

So is it four or ten? Or something else? Any advice by somebody who's tried this would be appreciated.

[esp_wifi_types.h on GitHub][1]

  [1]: https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/esp32/esp_wifi_types.h "esp_wifi_types.h on GitHub"

title: ESP32 AP max connections: 4 or 10?

Answers: 1

body:
The answer is as clear as any other EspressIf configuration data, it is 4 or maybe 5, or 8, or 12, 16 or even 20 (the same as a ESP8266!)

To clarify, it seems that around 2015 the maximum was 4 connections, but it is possible to recompile the SDK to support up to 16 connections.  There doesn't seem to be a #define of flag that will let a programmer control this.

These links may guide you to a proper solution:
https://github.com/esp8266/Arduino/issues/570
 or https://myesp8266.blogspot.com/2016/11/esp32-increase-maximum-number-of-sockets.html


body:
I'm using an L298N to control the two motors of a robot car, and I also have a servo controlling the HC-SR04. The motors and sensor work fine together, and the servo and sensor work fine together. But when I put them in the code together, only the servo works. Code is

    #include <Servo.h>

    // motor one
    int enA = 9;    //enable PWM for right motor
    int rightFwd = 7;    //right forward
    int rightBack = 6;    //right backward
    // motor two
    int enB = 10;   //enable PWM for left motor
    int leftFwd = 5;    //left forward
    int leftBack = 4;    //left backward

    //ultrasonic sensor
    int trig = 2;
    int echo = 3;

    //servo for looking left and right
    //int servoPin = 8;

    int runSpeed = 255;
    int distance;
    int leftDistance;
    int rightDistance;
    //int servoCenter = 100;
    //int lookAngle = 60;

    //Servo servoMotor;

    void setup()
    {
      Serial.begin(9600);
      pinMode(enA, OUTPUT);
      pinMode(enB, OUTPUT);
      pinMode(rightFwd, OUTPUT);
      pinMode(rightBack, OUTPUT);
      pinMode(leftFwd, OUTPUT);
      pinMode(leftBack, OUTPUT);
      pinMode(trig, OUTPUT);
      pinMode(echo, INPUT);
    //  pinMode(servoPin, OUTPUT);

    //  servoMotor.attach(servoPin);
    //  servoMotor.write(servoCenter);
    }

    void loop()
    {
      test();
    }

    void goForward()
    {
      Serial.println("Going forward");
      analogWrite(enA, runSpeed*3/4);
      analogWrite(enB, runSpeed*3/4);
      digitalWrite(leftBack,LOW);
      digitalWrite(leftFwd,HIGH);
      digitalWrite(rightBack,LOW);
      digitalWrite(rightFwd,HIGH);
    }

    void goBackward()
    {
      Serial.println("Going backward");
      analogWrite(enA, runSpeed*3/4);
      analogWrite(enB, runSpeed*3/4);
      digitalWrite(leftBack,HIGH);
      digitalWrite(leftFwd,LOW);
      digitalWrite(rightBack,HIGH);
      digitalWrite(rightFwd,LOW);
    }

    void turnLeft()
    {
      Serial.println("Turning left");
      analogWrite(enA, runSpeed*3/4);
      analogWrite(enB, runSpeed*3/4);
      digitalWrite(leftBack,HIGH);
      digitalWrite(leftFwd,LOW);
      digitalWrite(rightBack,LOW);
      digitalWrite(rightFwd,HIGH);
    }

    void turnRight()
    {
      Serial.println("Turning right");
      analogWrite(enA, runSpeed*3/4);
      analogWrite(enB, runSpeed*3/4);
      digitalWrite(leftBack,LOW);
      digitalWrite(leftFwd,HIGH);
      digitalWrite(rightBack,HIGH);
      digitalWrite(rightFwd,LOW);
    }

    void allStop()
    {
      Serial.println("Stopping");
      digitalWrite(leftBack,LOW);
      digitalWrite(leftFwd,LOW);
      digitalWrite(rightBack,LOW);
      digitalWrite(rightFwd,LOW);
    }

    int getDistance()
    {
      //  Getting the distance from the sensor
      long duration, distance;
      digitalWrite(trig,HIGH);
      delayMicroseconds(1000);
      digitalWrite(trig, LOW);
      duration=pulseIn(echo, HIGH);
      distance =(duration/2)/29.1;
      Serial.print(distance);
      Serial.println("CM");
      delay(10);
      return distance;
    }

    //int lookRight()
    //{
    //  Serial.println("Looking right\n");
    //  servoMotor.write(50);
    //  delay(500);
    //  int distance = getDistance();
    //  delay(100);
    //  servoMotor.write(servoCenter - lookAngle);
    //  delay(100);
    //  servoMotor.write(servoCenter);
    //  return distance;
    //}
    //
    //int lookLeft()
    //{
    //  Serial.println("Looking left\n");
    //  servoMotor.write(servoCenter + lookAngle);
    //  delay(500);
    //  int distance = getDistance();
    //  delay(100);
    //  servoMotor.write(servoCenter);
    //  return distance;
    //  delay(100);
    //}

    void test()
    {
      getDistance();
      goForward();
      delay(1000);
      allStop();
      delay(1000);
      goBackward();
      delay(1000);
      allStop();
      delay(1000);
      turnLeft();
      delay(1000);
      allStop();
      delay(1000);
      turnRight();
      delay(1000);
      allStop();
      delay(1000);
    //  lookLeft();
    //  lookRight();
    }

I've commented out the servo parts; as it is, the motors and the sensor perform the test perfectly. Uncommenting the servo parts makes the servo and sensor work, but the motors stop.

I see from [here][1] that

> On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins.

I'm using 9 and 10 as the enA and enB pins respectively for the PWM of the motors, and the servo is on pin 8.

I built up the code from scratch, testing each function as I went, and it's all good apart from this problem. How can I fix this?

  [1]: https://arduino.stackexchange.com/questions/13709/servo-motors-wont-work-with-motor-controller

title: Controlling motors and servo with L298N

Answers: 1

body:
The comment you have found which is also on the Servo library page https://www.arduino.cc/en/Reference/servo and is the core of your problem.

On an Uno, you will have to change the PWM pins to 3,5,6 or 11 as the timer which provides the PWM for pins 9 and 10 is now being used for the Servo library.

This is probably the easiest option, especially if you are using an L298 module, as you should be able to just swap the leads.

Alternatively, there may be an alternative Servo library available which does not use that timer (a quick Google showed some candidates, but I have not tested).


body:
im working on project which include using of motors and a float switch
im getting an error message which expected '}' at end of input .
i cant find where should i correct it, btw im putting a float switch at the first of the coding (which on top) and im getting and error, but when i remove the float switch function coding, its running well without any error. so how can i put this switch to it become functional? here is the coding;

    int motorPin = 4; // pin that turns on the motor
    int blinkPin = 9; // pin that turns on the LED
    int lamp1 = 5;// lampu pape
    int motorklorin = 3;// isi klorin
    int switch1 = 2;// switch float
    void setup()
    {
      pinMode(motorPin, OUTPUT);
      pinMode(blinkPin, OUTPUT); // set pin 13 to an output so we can use it to turn on the LED
      pinMode(lamp1, OUTPUT);
      pinMode(motorklorin, OUTPUT); // MOTOR UNTUK ISI KLORIN
      pinMode(switch1, INPUT_PULLUP);// PELAMPONG
    }

    void loop()
    {
    if(digitalRead(switch1) == HIGH)
    {
      digitalWrite(motorklorin, LOW);
    }
    else
    {
      digitalWrite(motorklorin, HIGH);
      delay(2000);
      }
    {
      digitalWrite(motorPin, HIGH); // turn on the motor
      digitalWrite(blinkPin, HIGH); // turn on the LED
      digitalWrite(lamp1, HIGH);// on lampu
      delay(2000);        // multiply by 1000 to translate seconds to milliseconds

      digitalWrite(motorPin, LOW);  // turn off the motor
      digitalWrite(blinkPin, LOW);  // turn off the LED
      digitalWrite(lamp1, HIGH);// motor 1 jalan (air start turun)
      delay(2000);        // multiply by 60000 to translate minutes to milliseconds

      digitalWrite(motorPin, HIGH); // turn on the motor (motorisi balik air jalan)
      digitalWrite(blinkPin, HIGH); // turn on the LED
      digitalWrite(lamp1, LOW);// on lampu
      delay(5000);        // multiply by 1000 to translate seconds to milliseconds

      digitalWrite(motorPin, HIGH);  // turn off the motor
      digitalWrite(blinkPin,HIGH);  // turn off the LED
      digitalWrite(lamp1, HIGH);// OFF LAMPU semua motor stop
      delay(1000);        // multiply by 60000 to translate minutes to milliseconds
      }

title: cant find what is error on my code

Answers: 2

body: There is an extra `{` right after your `else{}` statement.  Delete this and the code should compile.

body:
I cover this error and how to diagnose it [in a blog post](https://majenko.co.uk/blog/expected-end-input-error).  Here it is quoted for posterity:

----

A common problem, and one that can cause a new programmer to pull their hair out.

However, it's a problem that always has a simple solution, and with the right tricks it's also easy to find where the problem lies.

Let's take the following little code snippet, which throws up this exact error:

    byte i = 0;

    void doSomething() {
      digitalWrite(3, LOW);
    }

    void doSomethingElse() {
      digitalWrite(13, HIGH);
    }

    void setup() {
      // put your setup code here, to run once:
      pinMode(13, OUTPUT);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if (i == 1) {
        doSomething();
      i++;
    }

At first glance that all looks perfectly good. But you compile, and you get:

    /home/matt/Arduino/ErrorTest/ErrorTest.ino: In function 'void loop()':
    ErrorTest:21: error: expected '}' at end of input
     }
     ^
    exit status 1
    expected '}' at end of input

Line 21, of course, is the last line of the file. And the error is pretty explicit - it expects a } at the end of the file. However, there is plainly one there already. So what is it on about?

Simply put, there aren't *enough* } to balance out the number of { in the file. For every { there *must* be a } to go with it. On this little file it's easy to just go through and count them all. Add one for a { and subtract one for a }. If the answer is not 0 then there's something wrong. But it can take careful looking to see where the missing one should be, and even I have spent hours going cross-eyed trying to find the location in a big project.

There is one little trick, though, that can help you: Auto Format. The Auto Format facility in both the Arduino IDE and UECIDE (and many other IDEs as well) will sort out your indenting for you according to the presence of (amongst other things) { and }.  If the brackets don't match up the formatting would end up wrong.

So let's pass this little program through the auto formatting and see what happens:

    byte i = 0;

    void doSomething() {
      digitalWrite(3, LOW);
    }

    void doSomethingElse() {
      digitalWrite(13, HIGH);
    }

    void setup() {
      // put your setup code here, to run once:
      pinMode(13, OUTPUT);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if (i == 1) {
        doSomething();
        i++;
      }

As you can see the loop() function's indenting has changed. And if your eyes are sharp enough you'll already see what was wrong. The "if", which had an opening bracket, didn't have a closing one. The "i++" was supposed to be outside the "if" (as can be seen by the original indenting), but actually it wasn't, and the end of the function was really the end of the "if", leaving the function unfinished.

So fixing it is now really easy. By auto formatting we can see where the imbalance occurs, and fix it:

    void loop() {
      // put your main code here, to run repeatedly:
      if (i == 1) {
        doSomething();
      }
      i++;
    }

And now it compiles. But of course that little snippet doesn't actually do anything useful...


body:
I am making a low power rf remote that just has 3 buttons and sends rf signals accordingly.

I've been trying to make pin interrupts work when it's in deep sleep but it's a huge hassle. And then I thought of this:

[![Schematic][1]][1]

Is it a bad idea to do this?

I could imagine if you were too fast, you would shut the RF transmitter off while it's sending something, but that shouldn't be an issue because the user would notice nothing changed and will learn to press the button longer.

But the transmitter might also transmit too fast for a user to interrupt it.

And I don't know if debouncing is an issue here. I could just put a capacitor after the buttons.

Of course the code would be something like analogRead which button is pressed and then emit rf signals.

So my question is, is this bad practice and will this kill my battery/attiny/rf emitter?

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

title: Is this a good way of making a low power attiny? Unpower instead of sleeping

Answers: 0


body:
I am experimenting with [CIRC-03][1] but the DC motor won't start spinning with `motorAcceleration();` unless I give it a push. Also, it makes a little noise when it stands still.  It does spin, however, with one of the first two functions (`motorOnThenOff(); motorOnThenOffWithSpeed()`). I've tried adding the 220 µF capacitor but that doesn't change a thing.

Could someone offer me a solution to this problem?

  [1]: http://www.oomlout.com/oom.php/products/ardx/circ-03

title: CIRC-03 Spin Motor Spin

Answers: 0


body:
I would like to know what is the procedure for adding a custom board to the Arduino IDE?

My custom board is similar to the Arduino Zero. Instead of using the ATSAMD21G18, my board is based around the ATSAMC21G18. I also have the Atmel/Microchip SAMC21 Xplained development board.

I have found some open source code where the author has adapted/forked the Arduino SAMD21 code and made it work for the SAMC21 Xplained board ([here][1]). The author has stuck to the [Arduino hardware folder structure][2] and has added the SAMC21 Xplained to the `board.txt` file.

As a test, when I install the Arduino SAMD21 from the Arduino Board Manager, I noticed that it installed the hardware files in the following directory:

     %LOCALAPPDATA%\Arduino15\packages\arduino\hardware\samd\1.6.19\

I have read that to add hardware files to the board manager I need to create a `.json` file with the appropriate details. [More information here][3]. However, as far as I can tell, this requires me to zip the SAMC21 hardware files into a [tarball][4] and provide a URL to that tarball. I also need to generate and insert a SHA in the `.json` file.

Am I on the right path with the `.json` file?

Or should I just download the SAMC21 hardware files and place them in the `%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\samd\` folder next to the `1.6.19` folder?

My last resort would be to just copy the files into the existing SAMD21 hardware folder?

----------

I have looked into the following Arduino SE questions but they do not answer the question satisfactorily.

- [upload.tool not used in custom boards.txt?][5]
- [Arduino Due custom platform for school and library installation][6] (I would prefer not to use the Arduino IDE in portable mode.)

  [1]: https://github.com/prices/ArduinoCore-samd
  [2]: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
  [3]: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.6.x-package_index.json-format-specification
  [4]: http://computing.help.inf.ed.ac.uk/FAQ/whats-tarball-or-how-do-i-unpack-or-create-tgz-or-targz-file
  [5]: https://arduino.stackexchange.com/q/43997/19409
  [6]: https://arduino.stackexchange.com/q/45979/19409

title: Adding a custom board to the Arduino IDE

Answers: 1

body:
The simplest clean way to add your board [using an existing core][1] is to add the variant to your sketches folder's hardware subfolder. Only boards.txt and files for the board variant are added.

In your sketches folder create a 'hardware' folder. In this folder create a folder with the name of your boards package and a subfolder with the architecture name and a subfolder for variant and a name of the variant. for example `hardware/my_boards/samd/variants/samc21x`

In your variant folder (`variants/samc21x`) put the files for your variant based on variant files of the closet variant in the referenced hardware package. In your case perhaps a mkrzero would be a good example.

In your package's root (`hardware/my_boards/samd/`) add boards.txt file with entries for your board.

For boards.txt take the options for a similar board in referenced package. Change the names and settings and [prefix][1] `build.core` value with the name of the vendor of the referenced package. For arduino/samd it would be `arduino:`. For example `samc21x.build.core=arduino:arduino`

My custom and customized boards definitions [https://github.com/jandrassy/my_boards][3]

  [1]: https://arduino.github.io/arduino-cli/latest/platform-specification/#referencing-another-core-variant-or-tool
  [3]: https://github.com/jandrassy/my_boards


body:
I'm using a SIM800C module, and usually it works fine, but lately it has started giving the error "+CPIN: NOT READY" with ERROR CODE : +CME ERROR: 10(SIM NOT INSERTED). As soon as I get this message, the voltage on SIM_VDD drops to 0V. The problem is intermittent (i.e. it happens only sometimes).

I have read all related posts on here. Here is some info on my setup:
-Schematics is designed according to SIM800C documentation.
-I use 6-pin SIM connector.
-Adding decoupling caps on SIM_VDD, on input power, and on VBAT (for SIM900) does not help.
-Signal strength is fine (about CSQ=20).
-I tried reinserting different SIM cards, nothing helped

The "+CPIN: NOT READY" is sent at different times, however, often quite soon after power on.After removing battery & attaching it again, starts working again. why this issue is occuring..?

title: SIM800C, CPIN: NOT READY (ERROR CODE : +CME ERROR: 10)

Answers: 2

body:
The antenna is too close to the module. You probably used the spiral antenna. Try using the PCB antenna with long (10cm) cable.
Had the same problem, solved with the antenna.

body: Definitely related to poor antenna matching. This is complex stuff and should preferably be fixed by changing antenna matching (e.g. by a matching circuit or simply trying out a different antenna). I have also seen that it helps to wait until you get the unsolicited modem response "Call Ready". Until you get this message, it can disturb the modem to receive any AT command.


body:
I am having trouble with my digital sound sensor.  My goal: Clap 2 times and a led goes on. So I wrote this code. I don't know if it is correct or not. This happens: If I clap, from the serial monitor I don't get one HIGH, but a few (I tried changing the sensitivity of the soundsensor, but it doesn't help), but in my code I have some conditions where only 1 HIGH at a time is allowed. Thus, I don't know if my code is incorrect, or my sensor isn't working well.  Can you guys help me please? This is my code:

    int soundPin = 13;             // Digital soundPin
    int ledPin = 7;
    int claps = 0;                 // The amount of times I clapped
    int readingState ;             // The first reading from the soundPin
    int readingState2 ;            // The second reading from the soundPin
    int soundDetectionTime ;       // The time after the first clap
    int soundDetectionTime2 ;      // The time after the second clap
    int timeBetweenSounds = 1000;  // The time between the sounds I want. There
                                      is an If-statement further on.

    void setup(){
      pinMode(soundPin, INPUT);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);
    }

    void loop(){
      readingState = digitalRead(soundPin);    // The first reading form the
                                                  soundPin (digital pin)

      Serial.println(readingState);

      if (readingState == HIGH){               // If the reading from the
                                                 soundPin is HIGH, then start
                                                 timing. Also claps value
                                                 increased by 1 and the
                                                 second reading is happening.
        soundDetectionTime = millis();
        claps++ ;
        readingState2 = digitalRead(soundPin);

          if (readingState2 == HIGH){          // If the above statement is
                                                  true, then this if-statement
                                                  is executed. If the second
                                                  reading is HIGH,
                                                  soundDetectionTime two will
                                                  start counting
        soundDetectionTime2 = millis();    // Also the claps get increased by 1,
                                              so now claps = 2.
            claps++;
       }
       }

       if ((soundDetectionTime - soundDetectionTime2) > timeBetweenSounds &&
    claps==2){                            // If there is 1 second between the
                                             two readings and if I clapped
                                             twice, then LED is HIGH.
        digitalWrite(ledPin, HIGH);
       }
       }

UPDATE: I managed to get two HIGHs seperate from each other and the led is now on. So the problem must be the sensor giving me too much HIGHs if I clap once, like: 0,0,0,0,1,1,1,0,0. What do you guys think?

title: Digital Sound sensor

Answers: 2

body:
Your logic is flawed; you don't have any delay between readingState and readingState2 other than a serial.Print() which you shouldn't rely on for a delay.

You need to keep track of state in your loop. You need to capture the time of the first input, see it go low, then record the time of the second input. N.b. time between instructions is blindingly fast even on 'slow' proccessors.

something like:

    // edit: just gonna refactor a bit
    // edit: added debounce
    unsigned long start, end, time;
    int state = 0;
    ...
    #define BOUNCE 10
    int dbounce(unsigned long time, unsigned long start, unsigned long len)
    {
        return (time - start) > len;
    }
    ...
    void loop()
    {
      pin = digitalRead(soundPin);
      time = millis();
      switch(state)
      {
      case 0:
          if (pin == HIGH)
          {
            start = millis();
            state = 1;
          }
          break;
      case 1:
          if dbounce(time,start,BOUNCE)
              break; // one way to debounce
          if( pin == LOW)
              state = 2;
          break;
      case 2:
          if(pin == HIGH)
          {
             end = millis();
             state = 3;
          }
          break;
      case 3:
          if(dbounce(end,start,1000))
          {
             // do stuff
          }
          state = 4;
          break;
      case 4:
          if((pin == LOW) && dbounce(time,end,BOUNCE)) //another way to debounce
             state = 0; // start over
          break;
      }
    }

body:
Here is a "stripped down version" of a sketch I used to replicate the Clap On, Clap Off lamp switch we had in the 1980's.  It works with the KY-038 sound sensor module you currently have. You will need to install the [VirtualDelay][1] Library.

The sound sensor module is very sensitive. A quarter turn of the potentiometer around the "sweet spot" makes a huge difference. Too sensitive, and the digital output is constantly high. If it's not sensitive enough, then you have to physically "tap" the microphone to get a high/low transition out of it.

Please note: This sketch uses delay() which is "blocking code" and it's use is usually not recommended.

    #include "avdweb_VirtualDelay.h"
    byte clapCounter = 0;
    const byte soundSensorPin = 2;
    const unsigned long loopDelay = 1;
    const unsigned long clapCounterDelay = 400;
    unsigned long clapCounterTimerDuration = 1000;
    unsigned long previousMillis = 0;

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

    void loop(){

      // Timer object.
      static VirtualDelay clapCounterTimer;

      // Get the current time.
      unsigned long currentMillis = millis();

      // Check for a clapping sound (1 ms works good). If too much time
      // elapses here, you could miss the "beginning" of the clap.
      if(myTimer1(loopDelay, currentMillis) == 1){

        // Clap detected.
        if(digitalRead(soundSensorPin) == 1){

          clapCounter += 1;

          // When the first the clap is detected, start a timer
          // to reset the clap counter to 0 after 1 second.
          if(clapCounter == 1){
            clapCounterTimer.start(clapCounterTimerDuration);
          }

          // Delay execution of the loop. 400 ms works good.
          delay(clapCounterDelay);

          // If a second clap is detected, toggle the LED ON/OFF.
          if(clapCounter > 1){
            digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
          }

        }
      }

      // Reset the clap counter to 0 after 1 second. If
      // you don't do this, you could clap once, wait a
      // minute, then clap again and the LED will change state.
      if(clapCounterTimer.elapsed()){
        clapCounter = 0;
      }

    }

    // Clap loop timer.
    byte myTimer1(unsigned long loopDelay, unsigned long currentMillis){
      if(currentMillis - previousMillis >= loopDelay){previousMillis += loopDelay;return 1;}
      else{return 0;}
    }

**EDIT:** To answer your question regarding the multiple High to Low transitions from the module's digital output, you can use a DSO to look at the relationship between the analog and digital signals it produces.

In the following image, the digital signal (yellow trace) and the analog signal (blue trace) are superimposed over each other. The white dashed line (E), is set to 2.8 VDC which is **approximately** the analog output pin's voltage with ambient room noise. Once you clap in front of the microphone, this wave form is generated.

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

The entire clap lasts about 5.6 ms and the module gives you 18 High to Low transitions on it's digital output pin. When the analog voltage **drops below** a certain voltage, the digital output goes High. When the analog voltage **goes above** that voltage, the digital output goes Low.

The problem is, the sound of a person clapping generates a noisy signal and the sound sensor module does not know the difference between noise and the sound you want to trigger it.

Instead of using `delay()` like I did, you could increment a "clap counter"  to equal "1" on the first Low to High transition of the digital output pin. Next, start a non-blocking `millis()` timer that waits before you read the digital output pin again. If digital out is High after 400 ms, it's your second clap so change the LED state. A second `millis()` timer could reset the "clap counter" to 0 after 1 second.

  [1]: https://github.com/avandalen/VirtualDelay
  [2]: https://i.stack.imgur.com/XvJt8.png


body:
I'm trying to measure shutter speeds on old cameras. This essentially consists of:

 1. Shining a torch at one end of the camera
 2. putting the photoresistor at the other end
 3. trigger the shutter which temporarily lets in the light from the torch (boosting the photoresistor values temporarily)
 4. Recording the duration of the increased spike in light levels

What I have currently records light levels but the variation is massive and typically incorrect in that they change depending on how close the torch is to the shutter and typically records values between 400 and 900 ms which is far too long (should be about 50ms).

This is the key code I have so far:

    if (shutterbot.opened())
    {
        /* Measure length of time it is opened until closure */
        unsigned long previousMillis = millis();

        while(true)
        {
            unsigned long currentMillis = millis();
            unsigned long time_elapsed = currentMillis - previousMillis;

            if (shutterbot.closed())
            {
                finished = true;
                /* Report back to user */
                Serial.println("Shutter speed is: ");
                Serial.println(time_elapsed);
                break;
            }
        }
  }

The open and close methods in the shutterbot class are:

 /* If light is 10% higher, set it to start recording */
 int Shutterbot::opened()
 {
     if (light_level() > 400)
     {
  return true;
     }
     else
     {
  return false;
     }
 }

 /*
   If light drops to below 10% higher, set it to stop
   recording
  */
  int Shutterbot::closed()
  {
      if (light_level() < 400)
      {
   return true;
      }
      else
      {
   return false;
      }
 }

The full project code is [here][1] and just needs a photoresistor module and an arduino uno to test. I'm not sure I've provided enough information so if there are any questions, please let me know. Any help is greatly appreciated and thanks for reading.

  [1]: https://github.com/vivithemage/shutterbot

title: Measuring lenght of time light levels peak using photoresistor

Answers: 1

body:
It is unlikely a [photo resistor][1] can be used to time an event with sub second granularity.  This is because the electrons in such a device have many conductive states which they migrate into when exposed to light and out of when left in the dark.  It takes time for the electrons to drift into and out of these conductive bands.  In some cases it may take a good portion of a second. As described in the 2nd paragraph in the [Design Considerations][2] section of the above wikipedia page:

> Photoresistors also exhibit a certain degree of latency between
> exposure to light and the subsequent decrease in resistance, usually
> around 10 milliseconds. The lag time when going from lit to dark
> environments is even greater, often as long as one second. This
> property makes them unsuitable for sensing rapidly flashing lights,
> but is sometimes used to smooth the response of audio signal
> compression.

  [1]: https://en.wikipedia.org/wiki/Photoresistor
  [2]: https://en.wikipedia.org/wiki/Photoresistor#Design_considerations


body:
I'm using NodeMCU with 5v relay module. my problem is that when the output of NodeMCU is high the relay is off.
Which means that the relay module work in an inverted way so how can I treat this issue while when the output is high the relay become on?

title: 5v relay module

Answers: 2

body:
Software solution:

The easiest way is to drive the pin inverted by the NodeMCU, so set it LOW when you want the relay to be activated, otherwise set it HIGH.

Example:

    void setup()
    {
      pinMode(13, OUTPUT);          // sets the digital pin 13 as output
      digitalWrite(13, HIGH);       // switches OFF the relay
    }

    void loop()
    {
      digitalWrite(13, LOW);        // switches ON the relay
      delay(1000);                  // waits for a second
      digitalWrite(13, HIGH);       // switches OFF the relay
      delay(1000);                  // waits for a second
    }

Hardware solution:

A hardware solution is to use an inverter IC, but since you use a microcontroller it would be only cost space, time and money.

body:
try changing the connection in relay module[![enter image description here][1]][1]

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

  [1]: https://i.stack.imgur.com/iaMwH.png
  [2]: https://i.stack.imgur.com/RLdzi.png
u can see that there are three pins in a relay. when you connect the output from the NodeMCU between the common and the NC(normally closed) pin of relay,  makes the switch close and current flows (when the relay is not powered.) try connecting the output in between common and NO(normally opened). when you connect your output between common and NO the current will only flow when the relay is powered up.


body:
I'm trying to use the sketch bellow to work with my [WeMos D1 mini][1] (ESP8266 Arduino platform) together with Rotary Encoder [KY-040][2] or [MJKDZ][3], and it's not working for some reason, but the same sketch is working great on the Arduino Uno (with different pin assignment - 2, 3, 4).

Can someone explain to me what is the issue with the sketch?

    const int PinA = 14; // Used for generating interrupts using CLK signal
    const int PinB = 12; // Used for reading DT signal
    const int PinSW = 13; // Used for the push button switch

    int lCnt = 0; // Keep track of last rotary value
    volatile int vPos = 0; // Updated by the ISR (Interrupt Service Routine)

    void isr_event ()  {
      static unsigned long lIsrTmr = 0; // Last Interrupt time
      unsigned long IsrTmr = millis(); // Interrupt time

      // If interrupts come faster than 5ms, assume it's a bounce and ignore
      if (IsrTmr - lIsrTmr > 5) {
        if (digitalRead(PinB) == LOW)
        {
          vPos++ ; // Could be +5 or +10
        }
        else {
          vPos-- ; // Could be -5 or -10
        }

        // Restrict value from 0 to +100
        vPos = min(10, max(0, vPos));

        // Keep track of when we were here last (no more than every 5ms)
        lIsrTmr = IsrTmr;
      }
    }

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

      // Rotary pulses are INPUTs
      pinMode(PinA, INPUT);
      pinMode(PinB, INPUT);

      pinMode(PinSW, INPUT_PULLUP); // Switch is floating so use the in-built PULLUP so we don't need a resistor

      attachInterrupt(digitalPinToInterrupt(PinA), isr_event, LOW); // Attach the routine to service the interrupts

      Serial.println(F("Starting..."));  // Ready to go!
    }

    void loop()
    {

      // Is someone pressing the rotary switch?
      if ((!digitalRead(PinSW))) {
        vPos = 0;
        while (!digitalRead(PinSW))
          delay(10);
      }

      // If the current rotary switch position has changed then update everything
      if (vPos != lCnt) {
        // Write out to serial monitor the value and direction
        Serial.println(vPos);
        // Keep track of this new value
        lCnt = vPos ;
      }
    }

  [1]: https://cdn.instructables.com/FG7/9S89/INUV37ZY/FG79S89INUV37ZY.LARGE.jpg
  [2]: https://images-na.ssl-images-amazon.com/images/I/6193po2kMUL._SX425_.jpg
  [3]: https://ae01.alicdn.com/kf/HTB1TmD2SpXXXXXKXVXXq6xXFXXXN.jpg

title: ESP8266 Arduino and Rotary Encoder

Answers: 1

body: The ESP8266 doesn't know what a "LOW" interrupt is.  You will have to change your code to use FALLING, RISING or CHANGE interrupts only.


body:
This is my code for a timer. My goal is to increment the `count` at every 1 sec.

    unsigned int count = 0;
    int wait = 1000;

    void setup()
    {
      Serial.begin(9600);
    }
    void loop()
    {
      long current = millis();
      if((millis() - current) == wait)
      {
        count++;
      }
      Serial.println(count);
    }

but the serial monitor is only showing zeroes. what to do?

title: Serial.print only showing "0"

Answers: 1

body: `millis() - current` will always be `0` because `current` is always set to the value of `millis()` right before you compare it.  So it will never equal `wait` (0 is not 1000), so `count` never increments.


body: Do I have to connect RX and TX of SIM900A with any pins (say TX, RX of Arduino) for network purpose? Shouldn't the network status LED blink slower after connecting the power sources with SIM900A?

title: Testing network of SIM900A

Answers: 1

body:
To answer your questions in turn:

 - It is not necessary to connect to the Arduino solely for the purpose of making a GSM network connection.

 - When the SIM900A is powered on, the Status LED will blink once every second.

 - When the GSM connection has been established the Status LED of the SIM900A will blink every 3 seconds.

Follow this guide, from [Tutorial to interface GSM SIM900A with Arduino][1]:

> ###Initial startup of SIM900
>
>  1. Insert your SIM card to GSM module and lock it.
>  2. Power up the SIM900A by connecting it to Arduino's 5V and GND pins
>  3. Connect the Antenna
>  4. Now wait for some time (say 1 minute) and make note of the blinking rate of ‘status LED’ or ‘network LED’ (D6).
>     The GSM module will take some time to establish connection with mobile network
>  5. Once the connection is established successfully, the *status/network LED will blink continuously every 3 seconds*. You may try making a call to the mobile number of the sim card inside GSM
> module. If you hear a ring back, the GSM module has successfully
> established network connection.
>
> ###Connection to Arduino
>
> The SIM900A has the following pins:
>
>  - `3VR`;
>  - `3VT`;
>  - `5VR`;
>  - `5VT`;
>  - `VCC`, and;
>  - `GND`.
>
> For serial communication between the Arduino and SIM900A module. you
> have to connect:
>
>  - SIM900A `5VT` to Arduino `D9` and;
>  - SIM900A `5VR` to Arduino `D10`
>
> ###Basic Communication
>
>  1. To change SMS sending mode: `AT+CMGF=1`
>
>         mySerial.println("AT+CMGF=1");
>
>  2. To read SMS in text mode: `AT+CNMI=2,2,0,0,0`
>
>         mySerial.println("AT+CNMI=2,2,0,0,0");
>
>  3. To make a call: `ATD+60XXXXXXXXX` (replace X with number you want to call, change +60 to your country code)
>
>         mySerial.println("ATD+60XXXXXXXXX;");
>
>  4. To disconnect/hangup call: `ATH`
>
>         mySerial.println("ATH");
>
>  5. To redial: `ATDL`
>
>         mySerial.println("ATDL");
>
>  6. To receive a phone call: `ATA`
>
>         mySerial.println("ATA");

  [1]: http://www.instructables.com/id/GSM-SIM900A-With-Arduino/


body:
I've recently achieved connecting my board, an ESP8266 to my local WiFi, but I've had to hardcode the credentials to the code, just like in 99% of the tutorials online. My code looks somewhat like this:

    #include <Arduino.h>
    #include <ESP8266WiFi.h>
    #include <ESP8266WiFiMulti.h>
    #include <ESP8266HTTPClient.h>

    #define USE_SERIAL Serial

    ESP8266WiFiMulti WiFiMulti;

    void setup() {

        USE_SERIAL.begin(115200);

        WiFi.mode(WIFI_STA);
        WiFiMulti.addAP("SSID", "Password");

    }

    void loop() {
        // Some more code
    }

The thing is, I would like to know if there is some way to parametrize the credentials so I don't have to recompile and upload the code to the board everytime my WiFi password changes.

One of my ideas was to connect all the boards to a local router without actual connection to the internet and have a server in that same LAN manage the sensitive information, not the boards. That would allow me to manage credentials properly. Does this even make sense?

title: Connecting an ESP8266 to WiFi without hardcoding the credentials

Answers: 1

body:
The common way to do this is to put the ESP8266 into AP (Access Point) mode and then serve a web page with the configuration interface.

To make it even easier, you can create a captive portal so that the user doesn't need to open a specific IP address in their browser. The captive portal will cause the configuration page to be loaded no matter what address they open.

A popular Arduino library that makes this all very easy is WiFiManager:

https://github.com/tzapu/WiFiManager


body:
I am using two Arduino Unos, NRF24L01+ transceivers, and a few components as per this site on which I am following the second tutorial on this page: [Arduino Wireless Communication – NRF24L01 Tutorial][1].

I am using the exact code from the page as well - and have set everything up as per the diagrams, however everything stops working after a short amount of time. Usually between 15 and 30 seconds, everything stays powered but it seems like the transceivers stop communicating. A reset of the *Transmitting* board (the one with the potentiometer) will fix the problem until it again stops 15 or 30 seconds later.

Any idea what might be going on?

  [1]: https://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/

title: Arduino and RF24 library: communication stops after short amount of time

Answers: 4

body:
Your question does not provide much information to go on.  Setting up as given in the tutorial is a good start, but does not guarantee that there will be no problems.  It can still either be a problem due to hardware or firmware.

Firmware problems:

 - The radio data may be getting corrupted after some time, which shows up as a failed radio transaction
 - You inadvertently change the register settings of the radio

Hardware problems:

 - There is noise interference on the radio channel you are using due to the urban environment (wifi, etc).  Does the system work any better on a different channel?
 - The radio drains too much power and browns out, then will revert to default settings on the IC rather than the ones set by your Arduino sketch.

body:
There are few possible reasons:

First: If you soldered a capacitor it's capacity may bee too big , then if brownout appear radio module will not recover from it because of your big sized capacitor.

Second: it could be wrong config. use RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX but not MIN because it is not correctly supported by all RF24 modules.

Third: it could be brownout which is causing arduino board to fail (not the radio module). Then use alternative power source for radio module. But don't forget to leave ground cable of radio module connected to arduino (for data).

body:
I had the same problem and so far I have not been able to find the reason why this happens.

Anyways my temporary solution was to make arduino go to sleep and wake up. The moment the board goes to sleep and reboots everything works great again.

Execute this code every now and then

    #include <avr/wdt.h>

    ....

    // enable the watchdog timer. This will wake up the board after 120ms
    wdt_enable(WDTO_120MS);

    // go to deep sleep
    if (true)
    {
      SMCR |= (1 << 2); // power down mode
      SMCR |= 1;        // enable sleep;
      __asm__ __volatile__("sleep");
    }

I know this is not a solution but it is better than nothing like in my case.

Edit (Solution that worked for me)
----------------------

For some reason if I remove the millis() function the code keeps working.

        unsigned int end = millis() + 2500;
        for(int i=0; i<2000; i++) // New code
        // while (millis() < end)  // Old code stops working after 2 minutes ....
        {

I perform a task for 2.5 seconds that is why I was using the millis function...

body:
I had a similar issue. I got my NRF24L01+ working for an entire day, but then it suddenly broke and I could not fix it. From my online research, there seem to be a lot of reliability issues with NRF24L01+. Eventually, I implemented my plan Z: switch NRF24L01+ for a HC-05 bluetooth module (which is really easy!!), check out:
https://www.instructables.com/How-to-Connect-HC-05-to-Windows-1011-Mac-Apple-Com/
If you continue to trouble, I suggest just use HC-05, which would save you a lot headache and time.

However, the UART on HC-05 transmits data a lot slower than the SPI on NRF24L01, but I did not need the speed, so the switch was a great decision for me.


body:
I have these files:

 - `Project.ino`
 - `Sensor.h`
 - `Sensor.cpp`
 - `IMU/L3G.h`
 - `IMU/L3G.cpp`

`Sensor.h`

    #ifndef Sensor_h
    #define Sensor_h

    #include <EEPROM.h>
    #include "IMU/L3G.h"

    #define CUTOFF_FREQ 30
    #define FREQ 400

    class Sensor {
    public:
     Sensor();
     ~Sensor();
        void Init(void);

    pivate:
        L3G gyro;
    };
    #endif

`Sensor.cpp`

    #include "Sensor.h"

    Sensor::Sensor()
    {

    }
    Sensor::~Sensor()
    {

    }

    void Sensor::Init(void)
    {
      if (!gyro.init())
      {
        Serial.println("Failed to autodetect gyro type!");
        while (1);
      }
      gyro.enableDefault();
    }

`Project.ino`

    #include <i2c_t3.h>
    #include <EEPROM.h>
    #include <Servo.h>
    #include "Sensor.h"

    Sensor sensor = Sensor();

    void setup() {

      sensor.Init();
    }

I got this error

    /var/folders/8q/rbt7zf3d28b3k9t6d24k5sn00000gn/T/arduino_build_748953/sketch/Sensor.cpp.o: In function `Sensor::Init()':
    /var/folders/8q/rbt7zf3d28b3k9t6d24k5sn00000gn/T/arduino_build_748953/sketch/Sensor.cpp:15: undefined reference to `L3G::init(unsigned char, unsigned char)'
    /var/folders/8q/rbt7zf3d28b3k9t6d24k5sn00000gn/T/arduino_build_748953/sketch/Sensor.cpp:20: undefined reference to `L3G::enableDefault()'

So, what is wrong?

title: C++ Undefined reference to 'Class:Function()'

Answers: 1

body:
As [Juraj rightly points out][1], you have a typo, which should give you the following compile time error:

    In file included from sketch/Sensor.cpp:1:0:
    Sensor.h:17: error: 'pivate' does not name a type
     pivate:
     ^

Here is the correct code for `Sensor.h`

    #ifndef Sensor_h
    #define Sensor_h

    #include <EEPROM.h>
    #include "IMU/L3G.h"

    #define CUTOFF_FREQ 30
    #define FREQ 400

    class Sensor {
    public:
        Sensor();
        ~Sensor();
        void Init(void);

    private:
        L3G gyro;
    };
    #endif

Using Arduino IDE 1.8.5 with Teensyduino 1.42 with:

 - https://github.com/pololu/l3g-arduino
 - https://github.com/nox771/i2c_t3

However, once the typo has been corrected, as above, then I too can reproduce your problem (sort of), with these link errors:

    /var/folders/kp/xv3y9k114yq2_64pf8zwh76h0000gp/T/arduino_build_136680/sketch/Sensor.cpp.o: In function `Sensor::Sensor()':
    /var/folders/kp/xv3y9k114yq2_64pf8zwh76h0000gp/T/arduino_build_136680/sketch/Sensor.cpp:3: undefined reference to `L3G::L3G()'
    /var/folders/kp/xv3y9k114yq2_64pf8zwh76h0000gp/T/arduino_build_136680/sketch/Sensor.cpp.o: In function `Sensor::Init()':
    /var/folders/kp/xv3y9k114yq2_64pf8zwh76h0000gp/T/arduino_build_136680/sketch/Sensor.cpp:14: undefined reference to `L3G::init(L3G::deviceType, L3G::sa0State)'
    /var/folders/kp/xv3y9k114yq2_64pf8zwh76h0000gp/T/arduino_build_136680/sketch/Sensor.cpp:19: undefined reference to `L3G::enableDefault()'
    /var/folders/kp/xv3y9k114yq2_64pf8zwh76h0000gp/T/arduino_build_136680/core/core.a(main.cpp.o): In function `main':
    /Volumes/Home/Users/user/Local_Apps/Arduino/Arduino1.8.5-Teensy.app/Contents/Java/hardware/teensy/avr/cores/teensy3/main.cpp:53: undefined reference to `loop'
    collect2: error: ld returned 1 exit status
    Multiple libraries were found for "Servo.h"
     Used: /Volumes/Home/Users/user/Local_Apps/Arduino/Arduino1.8.5-Teensy.app/Contents/Java/hardware/teensy/avr/libraries/Servo
     Not used: /Volumes/Home/Users/user/Local_Apps/Arduino/Arduino1.8.5-Teensy.app/Contents/Java/libraries/Servo
    Error compiling for board Teensy 3.5.

You are probably getting this error, because you have placed the files `L3G.cpp` and `L3G.h` in a folder called `IMU` in the same folder as your `.ino` file. This causes the undefined error, as, while the IDE sees the declaration in the `L3G.h` file, the IDE can not find the definition in the `L3G.cpp` file.

This is easy to resolve.

If you download the `l3g-arduino-master.zip` file from https://github.com/pololu/l3g-arduino, and from within the Arduino IDE you then add the zipped up L3G library to the Arduino library, using `Sketch ► Include Library ► Add. ZIP Library...` and then change the line

    #include "IMU/L3G.h"

to

    #include <L3G.h>

Then it should compile and link without a problem

  [1]: https://arduino.stackexchange.com/questions/54529/c-undefined-reference-to-classfunction#comment114446_54529


body:
I tried to build project to detect alcohol with Arduino Uno and an MQ-3 Alcohol sensor.

I already have the `R0` value, but I faced problem here: I don't know how to convert it to PPM or BAC. I already tried some code from tutorial for convert it to BAC but when I gave the sensor alcohol the code gives me a value of `0.00`, and I don't know why.

Here is the code to find `R0` value:

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

    void loop()
    {
        float sensor_volt;
        float RS; //  Get the value of RS via in a clear air
        float R0;  // Get the value of R0 via in Alcohol
        float sensorValue;

        for(int i = 0 ; i < 100 ; i++)
        {
            sensorValue = sensorValue + analogRead(A0);
        }

        sensorValue = sensorValue/100.0;     //get average of reading
        sensor_volt = sensorValue/1024*5.0;
        RS = (5.0-sensor_volt)/sensor_volt; //
        R0 = RS/60.0; // 60 is found using interpolation
        Serial.print("R0 = ");
        Serial.println(R0);
        delay(1000);
    }

Here is the code to determine `BAC`:

    float R0= 0.28;
    void setup() {
      Serial.begin(9600);
    }

    void loop() {
      float sensor_volt;
        float RS_gas; // Get value of RS in a GAS
        float ratio; // Get ratio RS_GAS/RS_air
        float BAC;
        int sensorValue = analogRead(A0);
        sensor_volt=(float)sensorValue/1024*5.0;
        RS_gas = (5.0-sensor_volt)/sensor_volt; // omit *RL

       /*-Replace the name "R0" with the value of R0 in the demo of First Test -*/
        ratio = RS_gas/R0;  // ratio = RS/R0
        float a = pow(ratio, 2);
        float b = ratio/10;
        BAC = (0.1896*a) - (8.6178*b) + 1.0792 ;  //BAC in mg/L
        Serial.print("BAC = ");
        Serial.println(BAC*0.0001);  //convert to g/dL
        Serial.print("\n\n");
        delay(1000);
    }

I would to know what's wrong with the code, and if you know how to convert the `R0` values to PPM, please tell me.

title: How to get PPM value from MQ-3?

Answers: 1

body:
A series of `if()` statements and some simple division should be able to provide you with your PPM results.

From the datasheet, [Alcohol Gas Sensor（Model：MQ-3)][1], figure 5 shows the *sensitivity curve*:

[![Sensitivity curve][2]][2]

It can be seen here

[![Sensitivity curve - three regions][3]][3]

that there are three regions that the curve can be broken into:

 1. The relationship is linearly proportional between 2.25 V and 3.25 V
 2. Between 3.25 V and 3.8 V there is a curve
 3. The relationship is linearly proportional between 3.8 V to 4.25 V

The slope of the straight line regions described in points 1 and 3 can be represented by the use of a constant and the PPM value by a simple division of the voltage by the constant.

The curve from the second part could be:

 - approximated by a straight line (thus, once again, using a constant), for simplicity, or;
 - more accurately, using a lookup table.

Using a straight line approximation for the curve (shown in lurid green), the graph becomes:

[![Straight line approximation][4]][4]

To determine the constant for the three lines simply take two points on each line and use:

> (y2 - y1) / (x2 - x1)

So for region one, assuming (by approximation, 3 V corresponds to 100 ppm and 2.5 V corresponds to 85 ppm (my eye sight may be slightly off here), the slope is

    (3 - 2.5)/(100-80) = 0.5/20 = 0.025

You can calculate the constants for regions two and three in a similar manner (if using a straight line approximation for region two).

Therefore the code would be alomg the lines of

    const double kRegionOne = 0.025;   // region one constant
    const double kRegionTwo = ???;     // region two constant
    const double kRegionThree = ???;   // region three constant

    int ppm;                           // ppm result

    /*
     * your code here
     * ...
     */

    if ((sensor_volt < 3.25) && (sensor_volt >= 2.25)) {
      ppm = sensor_volt/kRegionOne;    // we are in region 1
    } else if ((sensor_volt < 3.8) && (sensor_volt >= 3.25)) {
      ppm = sensor_volt/kRegionTwo;    // we are in region 2
    } else if (sensor_volt >= 3.8) {
      ppm = sensor_volt/kRegionThree;  // we are in region 3
    }

If you wish to be more accurate then use a lookup table for region two, as jsotola states in [their comment][5].

  [1]: https://cdn.sparkfun.com/datasheets/Sensors/Biometric/MQ-3 ver1.3 - Manual.pdf
  [2]: https://i.stack.imgur.com/52cJZ.png "Sensitivity curve"
  [3]: https://i.stack.imgur.com/rooVI.png "Sensitivity curve - three regions"
  [4]: https://i.stack.imgur.com/mXNFs.png "Straight line approximation"
  [5]: https://arduino.stackexchange.com/questions/54534/how-to-get-ppm-value-from-mq-3/54543#comment114452_54534


body:
I am trying to get my Arduino to send data to my computer using Node.js Serial port. Everything compiles, my Arduino is working well and sending data in the serial monitor, but the program always goes into `myPort.on('close')`, and I can't figure out why.

    //import serial port js package
    const SerialPort = require('serialport');

    //opening a port
    var myPort = new SerialPort("/dev/ttyS2", {
      baudRate: 9600,
      //parser: SerialPort.parsers.raw
    });

    //how to pass the readline
    const Readline = SerialPort.parsers.Readline;
    const parser = new Readline();
    myPort.pipe(parser);

    myPort.on("open", onPortOpen);
    myPort.on("data" , onData);
    myPort.on("close" , onClose);
    myPort.on("error" , onError);

    function onPortOpen(){
        console.log("Port open");
    }

    function onData(data){
        console.log("data transfer completed..");
        console.log(data);
    }
    function onError(){
        console.log("Error. something went wrong..")
    }
    function onClose(){
        console.log("Port is closed. Communication terminated");
    }

Would anyone know what are the potential reasons? I double checked my port and it really is `COM3`, therefore, `/dev/ttyS2` for Windows 10.

title: SerialPort Node.js stuck in 'Error'

Answers: 1

body:
I see two issues in your code. I cannot say for sure they are related to
the problem you experience, but anyway:

1. The `Readline` parser's line terminator defaults to `"\n"`, whereas
   Arduino's `Serial.println()` uses `"\r\n"`. In order to get the line
   terminators match, you should invoke the `Readline` constructor with
   `{ delimiter: "\r\n" }` as an argument.

2. Piping the flow through the parser returns a new stream. You should
   watch for data events on _that_ stream rather the original port.

Thus I suggest you try:

<!-- language: lang-javascript -->

    const parser = new Readline({ delimiter: "\r\n" });
    const parsedStream = myPort.pipe(parser);

    myPort.on("open", onPortOpen);
    parsedStream.on("data" , onData);
    ...


body:
I have written two (1 second) delay programs.

The first program as follows:

    void setup()
    {
    Serial.begin(9600);
    TCCR1A = 0;
    TCCR1B |= (1<<CS12);
    TCCR1B &= ~(1<<CS11);
    TCCR1B &= ~(1<<CS10);
    TCNT1 = 3036;
    TIMSK1 |= (1<<TOIE1);
    }

    ISR(TIMER1_OVF_vect)
    {
      Serial.println(millis());
      TCNT1 = 3036;
    }
    void loop()
    {
    }

Whose output is as follows:

    999  // 1 sec
    1999 // 2 sec
    3000
    3999
    5000
    6000
    7001
    8000
    9000
    10001
    .
    .
    .
    58012
    59013
    60013
    61012
    62013 //60 sec

It has an error of around `13 ms` at 1 minute and at 1 hour it will be `780 ms` and in one day it will be around `19 seconds`.

The second program is as follows:

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

    void loop() {
      Serial.println(millis());
      delay(1000);
    }

Whose output is near about as same as the first one's.

Is there any way to decrease the error and make it more precise? So that I can use it in my Arduino based stopwatch?

title: How to make 1 second delay more accurate?

Answers: 3

body:
Your biggest problem is that you don't know what a second is.  You have no reliable time-base to measure time against.

`millis()` is not accurate. You can't rely on that giving you a precise time - otherwise, something as simple as:

    uint32_t secs = 0;

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

    void loop() {
        if (millis() / 1000 > secs) {
            secs = millis() / 1000;
            Serial.println(millis());
        }
    }

would give you a precise 1000 millisecond "delay". However, all that gives you is a precise "Arduino 1000 millisecond" delay.  That is - it triggers on the rollover between 1000 millisecond blocks where 1 millisecond is whatever the Arduino's `millis()` function thinks 1 millisecond is.

While it may *appear* to be accurate, in that it would give you round numbers "1000, 2000, 3000, 4000" etc, compare that to an external clock and you would find it's actually drifting just as bad (if not worse) than your existing methods.

The problem is, since what you are measuring the drift against is itself drifting, your measurements are completely meaningless.

If you require an exact 1-second pulse with near zero drift you will have to use an external clock source. The most accurate would be GPS. Many GPS modules have the ability to output a 1-second pulse which is synchronised to the GPS clock.

An RTC module would improve accuracy somewhat as well - again most of those have a 1Hz square wave output that can be used to synchronise things - however, even those aren't 100% accurate and rely on the accuracy of the attached crystal.  They're more accurate than the Arduino's ceramic resonator, though.

body:
Majenko is perfectly right: you cannot expect much accuracy from an
Arduino clocked by a ceramic resonator. Typical drift is of the order of
1,000 ppm, and is affected by temperature and aging. You can,
however, get a delay which is pretty close to the CPU's idea of one
second. In other words, you can get something that is really close to a
perfect period of 16,000,000 CPU cycles. If that is what you want,
your best bet is to use a timer.

In your overflow ISR, you wrote:

> `Serial.println(millis());`

There are two issues here. The first is the use of `Serial.println()`
within an ISR. This should normally avoided: since `Serial` relies on
interrupts, using it with interrupts disabled can lock your program if
you ever fill the output buffer. In this particular instance, it happens
to be safe, because at this rate you are never going to fill the output
buffer anyway. However, while it can be OK to do that in a small test
program like yours, I would advise you against doing it in production
code.

The other issue is the use of `millis()`. This function does not provide
true millisecond resolution: it is a counter that is updated every
1024 µs. Every now a then it is updated by 2 ms at once in
order to compensate for the drift. Thus, you should think of `millis()`
as being good to within ±2 ms. If you need anything better, use
`micros()`.

> `TCNT1 = 3036;`

This should be avoided. Dispatching an interrupt takes time, and this
time depends on whether there is already an interrupt handler (or other
critical section) running. If the timer happens to increment after the
interrupt fires but before you have time to execute the line above, then
you miss a timer tic. It has been suggested to you to move this line
before the `Serial.println()`. That would certainly reduce the risk, but
it will not completely prevent it.

The right thing to do is to _never_ reset a timer if you want it to have
time continuity. Instead, set it to CTC mode (clear timer on compare
match) and let it reset itself when it reaches a value of your choosing.
In this case, you would have it repeatedly count from 0 to 62,499
instead of from 3,036 to 65,535.

Here is a modified version of your program illustrating the points
above:

<!-- language: lang-c++ -->

    void setup()
    {
        Serial.begin(9600);
        TCCR1A = 0;            // undo the Arduino's timer configuration
        TCCR1B = 0;            // ditto
        TCNT1  = 0;            // reset timer
        OCR1A  = 62500 - 1;    // period = 62500 clock tics
        TCCR1B = _BV(WGM12)    // CTC mode, TOP = OCR1A
               | _BV(CS12);    // clock at F_CPU/256
        TIMSK1 = _BV(OCIE1A);  // interrupt on output compare A
    }

    ISR(TIMER1_COMPA_vect)
    {
        // OK in test code, don't do this in production code.
        Serial.println(micros());
    }

    void loop(){}

The output is as follows;

<!-- language: lang-none -->

    1000048
    2000048
    3000048
    ...
    58000048
    59000048
    60000048  // 60 seconds

body:
I never would have thought this day would come, but I disagree with @Majenko and @EdgarBonet.

The source of your clock is important. **If** the Arduino resonator is accurate enough, then you can use millis(). If you want more accuracy, then you can use a rtc like the ds3231. The ds3231 is temperature compensated for more accuracy. If you want something even better then you can use gps or a internet time server or even a long wave radio signal time server.

When you need a 1 second timer as the basis for a clock or stopwatch, then you can start by using millis() which is based upon the 16MHz resonator. The millis() is compensated with a offset, it will not drift. It runs 100% perfect with the same accuracy as the resonator. Use the [blink without delay example][1] and change the increment of previousMillis to this:

    if (currentMillis - previousMillis >= interval) {
      // increment the previousMillis with the interval
      previousMillis += interval;

That way the one second interval will stay in sync with the time, even when there is a big delay now and then in the sketch.

You will not get more accuracy by using a internal timer.

Some Arduino clones have a crystal instead of a resonator. If you use one of those clones with a crystal and use millis as I mentioned above, then your timing is as accurate as the crystal. When you build a clock with that, it might run a few minutes per year out of sync with the real time.

  [1]: https://www.arduino.cc/en/tutorial/BlinkWithoutDelay


body:
I am building an ESP8266 device that uses RFID but need to conserve battery power.

The ESP is a Wemos D1 Mini and the RFID module is a RC522 (still waiting for it to arrive), which needs 3.3 V. I'm powering the ESP with a battery shield and 3.3 V.

But I don't want to connect the RFID module directly to the battery shield because it will be sucking voltage constantly. Instead, I want to be able to control its power using the ESP.

So I thought the easiest would be simply to connect the RC522's 3v3 line to one of the ESP's available GPIO pins, set it to output, and when I need  RFID, set the GPIO pin high, to turn on the RFID module.

Is this an acceptable solution, or do I need to wire in a transistor and capacitor somewhere?

title: Power RFID module using GPIO

Answers: 1

body:
No, this is not an acceptable solution.  The RC522 needs in excess of 100mA to operate, and an ESP8266's GPIO pin can only supply 12mA maximum.  You will damage the ESP8266.

You need to use a P-channel MOSFET with the gate pulled HIGH as a high side switch.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/aSHdI.png)

<!-- End schematic -->

Set the GPIO to LOW to turn on the MOSFET. Set it HIGH or to INPUT to turn off the MOSFET.

----

Note 1: Set the communication IO pins to INPUT before powering off otherwise they could back-power the target device through the ESD diodes in the IO pins.


body:
I've connected SD card module to `Arduino UNO`. I want to use `PIN 10` for `PWM DC motor control` and because of that, I've connected `CS pin` directly to another pin (A3).

SD card is working properly, but after calling `SD.begin(A3)`, it set `PIN 10` to `HIGH`!
Immediately after `SD.begin(A3)` and set that pin to `LOW`, but meanwhile the motor took a small rotation.

I've digged into `SD.cpp` and `Sd2Card.cpp`, but couldn't find where this problem occured!

Any help appreciated....

**The Solution:**<br/>
Simply call `SD.begin(-1)` and it doesn't touch `PIN10`. Hope helps somebody else!

title: Arduino UNO And SD Card Custom csPin

Answers: 1

body:
Pin 10 is special. It's the *hardware* chip select pin for SPI.  It is integral to the SPI peripheral in the chip.

That pin *must* be an OUTPUT for SPI to operate as master, or INPUT for it to operate as a slave.

It's a stupid design decision by Atmel if you ask me, but there you go.  So basically trying to use SPI at the same time as PWM on pin 10 is "undefined" and to be avoided.

Use a different pin for PWM or if you need more than there are PWM pins available then consider an external PWM control chip.

----

Just probing around to get more detail on exactly how it all works, this is what I have found:

* `digitalWrite()` explicitly disables PWM on a pin.
* The direction of pin 10 defines the SPI operation as master or slave.
* `analogWrite()` sets `pinMode(OUTPUT)`.
* The SD library calls `pinMode(OUTPUT)` and `digitalWrite(HIGH)` on pin 10.

This means that:

* `SD.begin()` will terminate any existing PWM on pin 10.
* Using PWM on pin 10 will force the pin to output rendering SPI slave mode impossible

You *should* be able to use PWM on pin 10 if, and only if:

* You use `analogWrite()` *after* using `SD.begin()`, and
* You never want to use SPI slave mode.


body:
Now there are many ways to reply with a webpage content to a user who is accessing the web server,
But Keeping in mind to use as less space as possible,
I was trying something new, Since i didnt got compilation error, I am a little confused as to what might be the error,

in `void data()` I am storing the html page and saving it in ROM,

    void data()
    {
      if(SPIFFS.exists("/login.html"))
      {
        Serial.println();
      }
      else{
        SPIFFS.begin();
        File f=SPIFFS.open("/login.html","w");
        String s="<title>AP</title>
Welcome to AP page
\n";
        s+="<form name=\"/myform\" action=\"/login\" method=\"POST\">\n";
        s+="<input type=\"text\" name=\"username\" placeholder=\"username\">
\n";
        s+="<input type=\"password\" name=\"password\" placeholder=\"password\">
\n";
        s+="<input type=\"submit\" value=\"login\"></form>";
        f.println(s);
        f.close();
      }

    }

Please correct the above lines if I wrote it wrong,
After that,
I wrote some lines in `void setup()`

    WiFi.mode(WIFI_AP_STA);//Only Access point
      WiFi.softAP(ssid, password);  //Start HOTspot removing password will disable security

      IPAddress myIP = WiFi.softAPIP(); //Get IP address
      Serial.print("HotSpt IP:");
      Serial.println(myIP);

      server.on("/", HTTP_GET, handleRoot);      //Which routine to handle at root location
      server.on("/",HTTP_POST,handlelogin);
      server.onNotFound(handleerror);

      server.begin();

Now  I am calling `void handleRoot()`
I want to send the page that I wrote and saved in the `/login.html` file.

so for that,

    void handleRoot()
      {
        SPIFFS.begin();
        File f=SPIFFS.open("/login.html","r");
        server.send(200, "text/html",f.readStringUntil('EOF'));
      }

Now once I do this and execute and load the program in ESP01, it shows me nothing,
I have also tried sending `(String)f`, anything else I write is giving me an error,
This is compiling fine, but when I connect to the AP and open 192.168.4.1 in the browser i am not seeing anything,
But when I wrote `server.send(200,"text/html",(String)f)`
I was getting 0, Any idea on what mistake I am making.

title: Replying with a html page in HTTP Web Server using esp01 and ArduinoIDE

Answers: 1

body:
Small update, I used the same code for ESP8266 NodeMCU.

Sorry If I am posting this with wrong device number. But I tried that same code and uploaded it to ESP8266, it worked, and I am getting the AP webpage, that I am storing and sending the file. I will post it as an answer as I need to post an image.

The is the page that I get when using the HTML that I wrote:

> [![Webpage][1]][1]

So, this happened. I am confused as to why it didn't work with ESP01, plus I have to load the code every time I plug in the ESP01.

  [1]: https://i.stack.imgur.com/OvEWF.png "Webpage"


body:
I am trying to connect CATALEX MicroSD Card adaptor to new NodeMCU V3 and PIN configuration are as below,

    NodeMCU  ---------> SD Card
    GPIO13 (D7) ------> MOSI
    GPIO12 (D6) ------> MISO
    GPIO14 (D5) ------> SCK
    GPIO15 (D8) ------> CS
    VCC (3.3V) -------> VCC
    GND --------------> GND

Tested above setup with QuickStart program from SdFat library in Arduino IDE. But it gives error output as below,

    SPI pins:
    MISO: 12
    MOSI: 13
    SCK:  14
    SS:   15

    SD chip select is the key hardware option.
    Common values are:
    Arduino Ethernet shield, pin 4
    Sparkfun SD shield, pin 8
    Adafruit SD shields and modules, pin 10

    Enter the chip select pin number: 15

    Disabling SPI device on pin 10
    Can't access SD card. Do not reformat.
    No card, wrong chip select pin, or SPI problem?
    SD errorCode: 0X20,0XFF

    SD initialization failed.
    Do not reformat the card!
    Is the card correctly inserted?
    Is chipSelect set to the correct value?
    Does another SPI device need to be disabled?
    Is there a wiring/soldering problem?

    errorCode: 0x20, errorData: 0xff

> chipSelect is 15.

Also, I am using SanDisk 16GB Micro SDHC class 4 Memory Card.

I have tried googling with the error but did not find solution. Please help me.

title: NodeMCU V3 + SD Card with Arduino IDE Not working

Answers: 2

body: SD cards work on 3.3 V, so the adapter has 5 V to 3.3 conversion for power and signal, to connect SD card reader to a 5 V MCU. You can't connect this SD card  adapter to an 3.3 V MCU like the esp8266.

body:
If you are giving power to nodemcu through USB cable. SD card VCC can be connected to the VIN pin of nodemcu ESP8266. I faced the same problem

**NodeMCU V3 + SD Card with Arduino IDE Not working**

but after connecting VCC of SD Card to VIN pin of nodemcu. it worked.

Thanks for the helping me Mr. Juraj


body:
I'm a begginer with Arduino and this may be a basic question but I'm facing an issue.

I'm using a [HTU21D][1] sensor with an ESP32. This sensor use I2C communication. Inside the Arduino library, there is this function to start to collect data:
<!-- language-all: lang-cpp -->

    //Start I2C communication
    void HTU21D::begin(TwoWire &wirePort)
    {
      _i2cPort = &wirePort; //Grab which port the user wants us to use

      _i2cPort->begin();
    }

As you can see, we can set in this function which port we want to use. Perfect. But my probleme is that I don't know how to use the type TwoWire. I checked some documentation but I was still unable to find a solution. I want to use GPIO_16 as SDA and GPIO_17 as SCL.
So I tried something like that without result: `htu21d.begin(Wire(16, 17));`

**How to set SDA and SCL pin in TwoWire type ? (in my case GPIO_16 and GPIO_17)**

  [1]: https://learn.sparkfun.com/tutorials/htu21d-humidity-sensor-hookup-guide

title: How to choose alternate I2C pins on ESP32?

Answers: 2

body:
I was able to resolve my issue thanks to Juraj comment.
I did :

    Wire.begin(16, 17);
    htu21d.begin(Wire);

body:
Here is the example of how you can change esp8266 i2c pins. I used it for my ESP8266 and bme280, but the same for Arduino and other sensors.

    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BME280.h>

    void setup() {
      Wire.pins(12,2); //new SDA SCL pins (D6 and D4 for esp8266)

      Serial.begin(115200);
      delay(100);

      bme.begin(0x76, &Wire); //here is the address for my bme280 and instance of TwoWire object
    }

For my ESP8266 I tried to use GPIO0 for SDA and GPIO2 for SCL, but no luck. Probably because GPIO0 is a Flash pin. Changing SDA to GPIO12 (or D6 pin) helped me.