body:
Hi I was wondering if a digitalRead state change detection could be saved in a variable like counter++, just like you can do with an interrupt function.

arent these two operations almost the same?

like have an external circuit with a  reed closed by a magnet, to take the place of a momentary push button,

title: ISR vs state change detection on button

Answers: 2

body:
The 2 techniques described in the question are commonly referred to as "[polling][1]" and "[interrupt][2]".  Either will work.  Polling is suggested for beginner programmers and when time is not important. Such as scanning an array of human controlled buttons. Whereas interrupts are usually reserved for when time is of the essence.  Such as synchronizing a camera's release switch with a strobe flash.

Also, consider polling as a simple to understand, easy to test sequence of events that will always happen in the expected order.  While interrupts can happen at any time and all interruptible code has to be written to tolerate being interrupted.

Often, debouncing is the more difficult problem when combining mechanical switches and microprocessors.  A good fundamental exercise is to [write your own debounce program][3].  However, an [Arduino debounce library][4] is already available.

  [1]: https://en.wikipedia.org/wiki/Polling_(computer_science)
  [2]: https://en.wikipedia.org/wiki/Interrupt
  [3]: https://playground.arduino.cc/Learning/SoftwareDebounce
  [4]: https://playground.arduino.cc/Code/Bounce

body:
The fundamental difference between polling (`digitalRead()`) and interrupts is that of time. Yes, I know we discussed time and interrupts at length in [another of your questions](https://arduino.stackexchange.com/questions/48551/arduino-isr-timing-question), but I'm not talking about recording time here.

With an interrupt you know (pretty much) *when* an input changed. With polling you can only know that it changed *sometime in the past*.  An interrupt occurs at the moment an input changes state (what that change is depends on the type of interrupt). That makes it possible for your program to remember that time (by querying `millis()` for example).

With `digitalRead()` the only way you can know if an input has changed state is if you manually remember what the old state was and compare it, so all you can know is that it's changed since last time you examined the input, and if those times are far apart all you can say is "sometime in the past X milliseconds it changed state".

If your input changes *faster* than that polling time you won't know about it. For instance, if you end up polling every 10 milliseconds, and you have a pulse on your input pin that lasts 4 milliseconds (that's an eternity in microcontroller time) but occurs part way between two polls (say from 3ms to 7ms) you'll never see it.

To put it more formally, to detect a signal of frequency *f* Hz you have to sample the input at minimum *2f* Hz (or a period of *1/(2f)* seconds. This is known as the [Nyquist-Shannon theorem](https://en.wikipedia.org/wiki/Nyquist–Shannon_sampling_theorem) and applies equally to both digital and analog sampling (digital sampling is merely 1-bit analog sampling).

With interrupts, since you're not sampling based on periodic checks, but instead using a hardware trigger to detect an edge (rising, falling, or changing), and assuming you have interrupts enabled at the time an edge arrives on the pin (some code disables interrupts, and interrupts can't trigger while another interrupt routine is running), you instantly know about it regardless of whatever else you are doing.

Interrupts are said to be *asynchronous*, whilst polling is known as *synchronous*.

Which method you should choose depends on many factors: the speed of your signals (pulses from sensors, buttons pressed by humans, etc), what else your program is doing, how critical it is that you detect an input state change, etc.  For slow signals, like a button, polling is perfectly fine. For high speed signals, like a hall-effect sensor or a reed switch triggered by a bicycle wheel mounted magnet, interrupts are more suitable.

For some signals (especially things like revolution counters, frequency counters, etc) where you have a large number of brief pulses coming in over a period of time where all you want to do is count them, there are even better options than interrupts.

The internal timer peripherals of the chip can run in a number of modes that are designed just for this scenario.  You can run a timer with the clock source as an IO pin. That means that on each incoming pulse to that IO pin the timer counts up by one. That happens completely independently of your program. You just read the current count from the timer and reset it to 0 to start counting again at a period to suit you.

Another mode is *Input Compare* mode.  This combines normal interrupts with a timer. The timer runs in the background at a pre-defined rate, and as soon as a specific input changes state (each timer has specific inputs for this) the timer is frozen an interrupt is triggered.  This gives highly accurate time measurement of incoming signals since it's not subject to the time taken to service the interrupt. The timer is frozen immediately and you can query that time when the system is able to service the interrupt.

There is no native support in Arduino for either of those timer modes, though, so you would have to either find an advanced library that configures the timers in that way for you, or read and understand the datasheet and manually configure the timers in the right way.


body:
I have ARM-USB-OCD created by OLIMEX. I am interested in can I use this to burn a bootloader to Arduino Uno. As I know Atmega 328P can be programmed using JTAG protocol which has also ARM-USB-ODC, so if it really can anyone give the circuit or something like this.
Here is my device [(ARM-USB-ODC) manual][1].

  [1]: https://www.olimex.com/Products/ARM/JTAG/_resources/ARM-USB-OCD_and_OCD_H_manual.pdf

title: Burn bootloader to Arduino Uno using ARM-USB-OCD

Answers: 1

body:
*Probably, but likely not easily*

To program an AVR chip you likely want to use the AVR ISP protocol, which is not JTAG, but like JTAG is a synchronous serial protocol with a clock, a data line in each direction, and one additional control pin compared to the several mode/status pins of JTAG.

According to your link, the `ARM-USB-OCD` is based on an FT2232C USB interface chip.

`avrdude` documentation indicates that this is an interface it knows how to use, though it will likely take some study to figure out how.

The final question would be wiring - you'll need to figure out which JTAG-style signal names map to which FTDI functional pins, and how those should best be connected to AVR ISP pins in a way which avrdude can use.  Additionally, you'd have to make sure that any buffering between the FTDI chip and the pins is compatible with your needs, both in terms of data direction and voltage level.

Note that you can easily use any ATmega328-based Arduino as an ISP programmer for a same-voltage target - not really production worthy, but if you just need to move your project along *today* it's a handy option.


body:
I tried to set up an I2C conversation between ab ATTiny85 (8MHz) and an Arduino Uno. However I always get a 255 response from my I2C slave. I am using Arduino 1.8.5.

What am I doing wrong?

**ATTiny85-Slave Code:**

    #include "TinyWireS.h"  // wrapper class for I2C slave
    routines
    #define I2C_SLAVE_ADDR  0x26 // i2c slave address (38)

    byte t=10;

    void setup() {
      TinyWireS.begin(I2C_SLAVE_ADDR);  // init I2C Slave mode
      TinyWireS.onRequest(requestEvent);
    }

    void loop() {
    }

    void requestEvent() {
      TinyWireS.send(t);
    }

**Arduino Uno-Master Code:**

     #include <Wire.h>
     #define I2C_SLAVE_ADDR  0x26 // i2c slave address (38)

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

    void loop() {
      byte num;
      // read 1 byte, from address 0x26
      Wire.requestFrom(I2C_SLAVE_ADDR, 1);
      while(Wire.available()) {
        num = Wire.read();
      }
      Serial.print("num = ");
      Serial.println(num,DEC);
    }

title: Always 255-response in I2C between ATTiny85 (8MHz) and Arduino Uno

Answers: 1

body:
It may seem that the current commit of January 2018 from the TinyWire library is corrupt. Try using an older version from 2017, for example this one: https://github.com/rambo/TinyWire/tr...72a13504bbfc4e

This solves the problem for me as well.

Source: Teensy 3.5 - I2C - ATTiny85-20PU (TinyWireS.OnRequest not triggering!) - [Post #11][1]

  [1]: https://forum.pjrc.com/threads/48887-HELP-Teensy-3-5-I2C-ATTiny85-20PU-(TinyWireS-OnRequest-not-triggering!)?s=875dc9dc416bed5e6f87c304f0044bbd&p=164800&viewfull=1#post164800


body:
v 2:1.0.5

The list of sketches disappears off the bottom of my screen and there is no scroll to reach them. This renders the IDE nearly useless.

Is there a solution?

title: List of sketches disappears off the bottom of my screen

Answers: 1

body:
That issue has been [fixed](https://github.com/arduino/Arduino/commit/49a05121d442a2af1280876887943b1a014f2adf) since the Arduino IDE 1.5.5 [release](https://github.com/arduino/Arduino/releases/tag/1.5.5), 4 years ago.

The version of the Arduino IDE you get from `apt-get install arduino` has not been able to be updated for years due to [licensing issues](https://github.com/arduino/Arduino/pull/2703). The versions available from various package managers may also be modified in ways that introduce new bugs. For this reason you should always install the official Arduino IDE version downloaded from:
https://www.arduino.cc/en/Main/Software


body:
I want to read a SMS message , find it's length and do some "substring();" operation on received SMS. My last two(2) statements do not work . How can I get correct answers? What are correct codes ?

    #include <SoftwareSerial.h>
    #include <string.h>
    #include <ctype.h>
    SoftwareSerial mySerial(2,3);

    String TelephoneNumberText="";

    void setup()
    {
      pinMode(13, OUTPUT);
      digitalWrite(13, LOW);

      mySerial.begin(9600);
      Serial.begin(9600);
      delay(100);

      mySerial.println("AT+CMGF=1\r");    //Sets the GSM Module in Text Mode
      delay(500);
    }

    void loop()
    {

     while(mySerial.available())
      {
       char s;
       s = mySerial.read();
       TelephoneNumberText = TelephoneNumberText + s;
       }

     Serial.println(TelephoneNumberText);           // this statement works

     Serial.println(TelephoneNumberText.length());  // this statement dose not works

     Serial.println(TelephoneNumberText.substring(0,3));// this statement dose not works

    } // end loop

title: SoftwareSerial + Serial.printlen() not working properly

Answers: 1

body:
Are you sure a string like this can be used?

Better anyway to not each time let a dynamic string be created, but use a fixed string e.g.

    char TelephoneNumberText[16];

Set the length of the max number, and change other string functions accordingly.


body:
I need to use `system_adc_read_fast (uint16 *adc_addr, uint16 adc_num, uint8 adc_clk_div)` to get a sampling rate close to 100ksps. And I am able to achieve that using `adc_clk_div = 32`.

However, when I print out the values stored in `adc_addr`, I always get `1024`. **Why is this?**

I have a NodeMCU v3. I have connected an electret microphone to it. +ve terminal is connected to 3.3V through 10k; GND is connected to GND. +ve terminal is connected to A0 on NodeMCU.

<!-- 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/eE55E.png)

<!-- End schematic -->

It works fine when I use `system_adc_read()` (except the sampling rate is then 10ksps which is not desirable).

**Sketch**

<!-- language:lang-cpp -->

    // Expose Espressif SDK functionality - wrapped in ifdef so that it still
    // compiles on other platforms
    #ifdef ESP8266
        extern "C" {
            #include "user_interface.h"
        }
    #endif

    ADC_MODE(ADC_TOUT);

    #define num_samples 512
    uint16_t adc_addr[num_samples]; // point to the address of ADC continuously fast sampling output
    uint16_t adc_num = num_samples; // sampling number of ADC continuously fast sampling, range [1, 65535]
    uint8_t adc_clk_div = 32; // ADC working clock = 80M/adc_clk_div, range [8, 32], the recommended value is 8

    int i = 0;
    unsigned long start = 0;
    unsigned long total = 0;
    unsigned long tim = 0;

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

    void loop() {
        // put your main code here, to run repeatedly:
        #ifdef ESP8266
            // Serial.println(system_get_sdk_version());

            wifi_set_opmode(NULL_MODE);
            system_soft_wdt_stop();
            ets_intr_lock( ); //close interrupt
            noInterrupts();

            start = micros();

            // Serial.println(system_adc_read());
            system_adc_read_fast(adc_addr, adc_num, adc_clk_div);

            unsigned int tot = micros() - start;

            interrupts();
            ets_intr_unlock(); //open interrupt
            system_soft_wdt_restart();

            tim += tot;
            total += num_samples * 1000000.0 / tot;
            i++;

            for (int j=0; j<adc_num;  j++) {
                Serial.println(adc_addr[j]);
            }

            if (i == 100) {
                // Serial.print("Sampling rate: ");
                // Serial.println(total / 100);
                // Serial.print("It lasted: ");
                // Serial.println(tim / 100);

                i = 0;
                tim = 0;
                total = 0;
            }
        #endif
    }

  [1]: https://espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf

title: ESP8266: system_adc_read_fast() always give 1024 as output

Answers: 1

body:
I created a test circuit using an AC transformer to produce a 50 cycles / second sine wave signal and tried a number of variations on the *system_adc_read_fast* sample program in the Espressif SDK manual "**2C-ESP8266_Non_OS_SDK_API_Reference__EN**".

The ESP8266 ADC returned realistic values for *adc_clk_div* = 8 and 16, but, as you found, the values returned were always 1024 when I tried 32.

I found that the ADC unit was capable of performing ADC conversions in about 6-10 microseconds...

In a test program to collect data for a 40 millisecond period (ie two complete sine waves - I used a diode to chop off the negative halves) I called the *system_adc_read_fast* function 40 times collecting 116 samples in each call (using "number of samples" = 116).

I collected all the readings in a two-dimensional array before printing any values because the Serial.print function causes long delays between calls to the ADC converter. The "gaps" in the chart represent the changes in the sine wave signal between successive calls to the ADC read function.  [![Chart of ESP8266 ADC values over a 40 millisecond period][1]][1]

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


body:
This might be a super easy question to answer. I ordered an Arduino Uno anyways for the sole purpose to understand this. Would not mind getting a jump on things before it's here.

I would like to setup the Arduino Uno to be used as a gear indicator for GM transmissions (specifically right now the GM 4l60e). Below is how it currently tells the computer/cluster what gear it's in.

This uses a range switch. Basically it's a combination of 4 wires that are grounded (low) in a specific order, the computer reads it, and displays what gear the transmission is in. There are 4 signal wires - Signal A,B,C, and P. Below is how the range switch signals it:

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

    Park    - A=low,  B=open, C=open, P=low
    Reverse - A=low,  B=low,  C=open, P=open
    Neutral - A=open, B=low,  C=open, P=low
    OverDrv - A=open, B=low,  C=low,  P=open
    Drive 3 - A=low,  B=low,  C=low,  P=low
    Drive 2 - A=low,  B=open, C=low,  P=open
    Drive 1 - A=open, B=open, C=low,  P=low

I am wondering what would be the best way to go about this? The Arduino would be powered on by ignition. Display would be an LED (9-12V) output from the Arduino to each gear on a floor mount shifter. Total of 7 LEDs.

Hopefully this is easy to understand what I am trying to do. Thanks!

title: Reading Ground/Open signal wire combonations to power specific LED's - Can it be done?

Answers: 1

body:
First of all, Arduino is a 5V device, as such to drive the 9-12V LED you will need to use one or more transistors (depending on the LEDs type, number and connection, in series or in parallel).

Also, powering the Arduino from a 9-12V is not the best option: Arduino Uno has an onboard voltage regulator, but goes up to 9V maximum and, unless you go for the original one or a reputable manufacturer (Arduino is an open source project) I wouldn't go above 6V, because non-reputable manufacturers tend to use lower specs devices, like regulators which can get too hot when powered with high voltage: consider that the regulator will have to dissipate any excess energy into heat.

Said that, and knowing nothing more than what you said about the transmission you are describing, I assume the status `open` stands for _open collector_, meaning that it is not going to draw any current, so the following circuit is what you should use:

<!-- 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/5WPHv.png)

<!-- End schematic -->

The diagram assumes you are using digital pins 5 to 8 of your Arduino in `INPUT` mode and the Arduino GND is at the same voltage level as the transmission: this might be a big assumption, depending on how you power your Arduino (not from a battery pack, to be clear).

When node `A` is in `open` state, the voltage on Arduino pin `5` will be 5V, or HIGH as Arduino reports it. When node `A` is in `low` state then the voltage on Arduino pin `5` will be 0V, or LOW in Arduino lingo.

Resistors from `R1` to `R4` are there to limit current drawn when the gearbox is in state `low`.

UPDATE: I'm assuming the gearbox shares the same ground and operates at 5V,a s the Arduino does. If that's not he case and the gearbox operates at an higher voltage or does not share the same ground, the circuit will not work and you risk damaging the Arduino and/or the gearbox.

You can find a simulation of the above circuit where you can play with the different pins [here][1].

The same occurs for the other pins, so your code will have to scan the 4 pins for their state and update your display accordingly, like:

    #define PIN_A 5
    #define PIN_B 6
    #define PIN_C 7
    #define PIN_P 8

    void setup() {
      pinMode(PIN_A, INPUT);
      pinMode(PIN_B, INPUT);
      pinMode(PIN_C, INPUT);
      pinMode(PIN_P, INPUT);
    }

    #define PARK 0;
    #define DRIVE_1 1;
    #define DRIVE_2 2;
    #define DRIVE_3 3;
    #define OVER_DRIVE 4;
    #define REVERSE 5;
    #define NEUTRAL 99;
    #define UNDEFINED 255;

    unsigned int gear = UNDEFINED;
    void loop() {
        bool A = digitalRead(PIN_A);
        bool B = digitalRead(PIN_B);
        bool C = digitalRead(PIN_C);
        bool P = digitalRead(PIN_P);

        if (!A && B && C && !P) {
          // Park - A=low, B=open, C=open, P=low
          gear = PARK;
        } else if (!A && !B && C && P) {
          // Reverse - A=low, B=low, C=open, P=open
          gear = REVERSE;
        } else if (A && !B && C && !P) {
          // Neutral - A=open, B=low, C=open, P=low
          gear = NEUTRAL;
        } else if (A && !B && !C && P) {
          // OverDrv - A=open, B=low, C=low, P=open
          gear = OVER_DRIVE;
        } else if (!A && !B && !C && !P) {
          // Drive 3 - A=low, B=low, C=low, P=low
          gear = DRIVE_3;
        } else if (!A && B && !C && P) {
          // Drive 2 - A=low, B=open, C=low, P=open
          gear = DRIVE_2;
        } else if (A && B && !C && !P) {
          // Drive 1 - A=open, B=open, C=low, P=low
          gear = DRIVE_1;
        } else {
          // none of the above
          gear = UNDEFINED;
        }
        // update your display here
    }

Please note the above code is NOT the most efficient, but I believe it's easier to read and understand than a version using bitwise operations to identify the possible combinations.

  [1]: http://tinyurl.com/ycxrp4q9


body:
I'm working on a project based on MPU6050 GY-521 board connected to my PCB (running with an ATMega328P). The code was developed in Arduino.

The PCB is the second version. The first one works fine with the same accelerometer.

But with the second version I'm facing problems because it doesn't work and I can't understand the cause.

I did the following tests:

 1. Run the code in an Arduino Nano board connected to the GY-521 MPU6050 board. Works fine.
 2. Use other PCB to dismiss possible problem while soldering process. Doesn't work.
 3. Probe with other GY-521 MPU6050 board. Doesn't work.

Finally I decided to cut some parts of the code trying to understand what part of this crash. My final test makes an LED blink while the rest part of the code ran.

    void setup() {
      Serial.begin(115200);
      Wire.begin();
    #if ARDUINO >= 157
      Wire.setClock(400000UL);
    #else
      TWBR = ((F_CPU / 400000UL) - 16) / 2;
    #endif

      i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
      i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
      i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
      i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
      while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once

      //line commented in the last test
      //while (i2cWrite(0x6B, 0x01, true));

      //line commented in the last test
      //while (i2cRead(0x75, i2cData, 1));
      if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
        Serial.print(F("Error reading sensor"));
        while (1);
      }

      delay(100); // Wait for sensor to stabilize

      //line commented in the last test
      //while (i2cRead(0x3B, i2cData, 6));
      accX = (int16_t)((i2cData[0] << 8) | i2cData[1]);
      accY = (int16_t)((i2cData[2] << 8) | i2cData[3]);
      accZ = (int16_t)((i2cData[4] << 8) | i2cData[5]);

      // It is then converted from radians to degrees
    #ifdef RESTRICT_PITCH // Eq. 25 and 26
      double roll  = atan2(accY, accZ) * RAD_TO_DEG;
      double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
    #else // Eq. 28 and 29
      double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
      double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
    #endif

      pinMode(7, OUTPUT);
      pinMode(6, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(4, OUTPUT);

    }

    void loop() {
      /* Update all the values */
      //line commented in the last test
      //while (i2cRead(0x3B, i2cData, 14));
      accX = (int16_t)((i2cData[0] << 8) | i2cData[1]);
      accY = (int16_t)((i2cData[2] << 8) | i2cData[3]);
      accZ = (int16_t)((i2cData[4] << 8) | i2cData[5]);
      tempRaw = (int16_t)((i2cData[6] << 8) | i2cData[7]);
      gyroX = (int16_t)((i2cData[8] << 8) | i2cData[9]);
      gyroY = (int16_t)((i2cData[10] << 8) | i2cData[11]);
      gyroZ = (int16_t)((i2cData[12] << 8) | i2cData[13]);;

      double dt = (double)(micros() - timer) / 1000000; // Calculate delta time
      timer = micros();

      // It is then converted from radians to degrees
    #ifdef RESTRICT_PITCH // Eq. 25 and 26
      double roll  = atan2(accY, accZ) * RAD_TO_DEG;
      double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
    #else // Eq. 28 and 29
      double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
      double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
    #endif

      double gyroXrate = gyroX / 131.0; // Convert to deg/s
      double gyroYrate = gyroY / 131.0; // Convert to deg/s
      double gyroZrate = gyroZ / 131.0; // Convert to deg/s

    #ifdef RESTRICT_PITCH
      // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
      if ((roll < -90 && kalAngleX > 90) || (roll > 90 && kalAngleX < -90)) {
        kalmanX.setAngle(roll);
        compAngleX = roll;
        kalAngleX = roll;
        gyroXangle = roll;
      } else
        kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter

      if (abs(kalAngleX) > 90)
        gyroYrate = -gyroYrate; // Invert rate, so it fits the restriced accelerometer reading
      kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt);
    #else
      // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
      if ((pitch < -90 && kalAngleY > 90) || (pitch > 90 && kalAngleY < -90)) {
        kalmanY.setAngle(pitch);
        compAngleY = pitch;
        kalAngleY = pitch;
        gyroYangle = pitch;
      } else
        kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt); // Calculate the angle using a Kalman filter

      if (abs(kalAngleY) > 90)
        gyroXrate = -gyroXrate; // Invert rate, so it fits the restriced accelerometer reading
      kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter
    #endif

      gyroXangle += gyroXrate * dt; // Calculate gyro angle without any filter
      gyroYangle += gyroYrate * dt;
      //  gyroXangle += kalmanX.getRate() * dt; // Calculate gyro angle using the unbiased rate
      //  gyroYangle += kalmanY.getRate() * dt;

      compAngleX = 0.93 * (compAngleX + gyroXrate * dt) + 0.07 * roll; // Calculate the angle using a Complimentary filter
      compAngleY = 0.93 * (compAngleY + gyroYrate * dt) + 0.07 * pitch;

      // Reset the gyro angle when it has drifted too much
      if (gyroXangle < -180 || gyroXangle > 180)
        gyroXangle = kalAngleX;
      if (gyroYangle < -180 || gyroYangle > 180)
        gyroYangle = kalAngleY;

      // leer el valor analogo que entra
      // filtrarlo
      // determinar si se enciende el led
      sensorValue = analogRead(sensorPin);
      filBattery = myFilterBattery.getFilteredValue(sensorValue);
      if (filBattery < 750) // hacer la prueba con este nuevo valor
      {
        digitalWrite(3, HIGH);
      }
      else
      {
        digitalWrite(3, LOW);
      }
      digitalWrite(5, HIGH);
      delay(500);
      digitalWrite(5, LOW);
      delay(500);
    }

With this code the LED blinks fine, but the commented lines are critical to MPU6050 setup and operation.

If someone can help me to understand what happen to my PCB, I'll be grateful.

Thanks in advance

title: Problem with PCB running an Arduino program to manage a GY-521 MPU6050 accelerometer

Answers: 1

body:
You have explained that PCB v1 works, and PCB v2 does not work. Therefore, it seems likely the problem is in your PCB design and not in the code.

In your code sample which blinks an LED on PCB v2, but does not communicate with the MPU6050, it seems that you have removed the I²C function calls. Therefore *if* removing those function calls is what allows your code to run, and *if* the "working" code used on PCB v1 does not run successfully on PCB v2, then it's logical that you have somehow broken your I²C bus on PCB v2.

I suggest you start by comparing your PCB v1 and v2 designs *carefully*, focussing especially on the I²C bus and the connections to the MPU6050.


body:
Okay probably not the first time this has been asked, but really, I search all over the internet and was not able to find this.
I want to drive LEDs on the output on some of my pins. Is it required to put a pull-up resistor or current limiter resistor on these? or can I just plug the LED into the output, and the other end of the LED to +vcc? Are there example schematics someplace that will show this?
thoughts? suggestions?
thanks.

title: using pull-up resistors with A-star 32u4 on putput pins?

Answers: 1

body:
You always should use a resistor.

Simply the following schematic should be used.

The resistor value can be calculated as follows:

(V + Vfwd = I * R) => R = (V + Vfwd) / I

V is 5.0 V
Vfwd is the forward voltage of the LED (this differs per type/color/brand)
I is normally max. around 20 mA (but can be briefly more if the LED does not continuously lights)

Normally R is between 100 and 500 R, but can differ if you want to add multiple LEDs.

<!-- 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/iEF1Q.png)

<!-- End schematic -->


body:
Is it possible to connect to an SSID that does not require a password?
My project using ESP8266-01 modules will sometimes be used in non-password protected guest networks.

title: ESP8266 on WiFi without password, possible?

Answers: 1

body:
Yes, it works! You can use:

    WiFi.begin(ssid, NULL)

or even leave the passphrase empty, because it is optional:

    WiFi.begin(ssid)

Reference: https://www.arduino.cc/en/Reference/WiFiBegin


body:
I have an Atmega328p on a board that I want to program using an Arduino programmer. I've got the programmer working to program other Arduino's over ICSP header, but when trying to use the same settings to avrdude to read/set the fuses of the bare MCU with oscillator I get the following:

    ❯❯❯ avrdude -v -p atmega328p -b 19200 -P /dev/cu.wchusbserial213240 -c stk500v1                                                                                ⏎ master

    avrdude: Version 6.3, compiled on Sep 18 2017 at 20:31:51
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "/usr/local/Cellar/avrdude/6.3/etc/avrdude.conf"
             User configuration file is "/Users/viktor/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

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

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

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

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.08s

    avrdude: Device signature = 0x000000 (retrying)

    Reading | ################################################## | 100% 0.08s

    avrdude: Device signature = 0x000000 (retrying)

    Reading | ################################################## | 100% 0.08s

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

    avrdude done.  Thank you.

I've checked the soldering as good as I can and it seems to be right. I have a 10K pullup on reset, an oscillator with caps. I'm suspecting I might have fried the MCU when soldering or something - is there anything simple I can check?

* All PWR connections check out
* I've checked the oscillator with a scope and it isn't oscillating, but I'm thinking that is normal since it's a bare chip that I'm trying to set the fuses to use the external crystal? The oscillator is at least connected correctly.

title: Errors trying to set fuses on bare Atmega328p

Answers: 1

body: It turned out it was a bit of bad soldering on the MCU. This same msg you'll get if just leaving the ICSP floating.


body:
So am doing a project which involves the reading of voltage and current generated by Solar Panel. Now I learnt that Arduino cant Read Voltage directly above 5V. To read above that you need to add a voltage divider circuit in between. But that's the great solution for a solar panel around 20W.
Now what if i want to read voltages of n number of solar panels which are in a farm in which each solar panel generated around 300-400 W .
1)Will adding voltage divider help?
2) What is the limit of Arduino of Voltage Divider?
3) What registers i would have to use for such big voltage divider?

title: Arduino Voltage Divider

Answers: 2

body:
> 1) Will adding voltage divider help?

Yes.

> 2) What is the limit of Arduino of Voltage Divider?

The Arduino has no relevance here. You can build voltage dividers to convert thousands or millions of volts down to 5V if you need to.

> 3) What registers i would have to use for such big voltage divider?

I guess you mean "resistors" here, not "registers"...

Resistors that give no more than 5V out at the peak voltage of the solar panels, and have a high enough voltage tolerance for the maximum voltage across any one resistor.

body:
> 1)Will adding voltage divider help?

You will need _n_ voltage dividers, one for each solar panel.

> 2) What is the limit of Arduino of Voltage Divider?

There is a limit on the equivalent Thévenin resistance of the voltage
source connected to the Arduino analog inputs. It should be no larger
that 10 kΩ, otherwise you risk cross-talk between the channels.

If the solar panels have a low output resistance, then the equivalent
Thévenin resistance is the resistance resulting from setting the two
resistors of the divider _in parallel_. Setting the smallest resistance
to 10 kΩ will ensure you meet the condition while at the same time
keeping the consumed current quite low.

There is also a limit on the number of solar panels that you can
independently monitor: 16, which is the number of analog inputs on the
Mega.

> [...] each solar panel generate[s] around 300-400 W

The power generated is irrelevant: only the voltage is a concern. Your
dividers must output no more than 5 V.


body:
i was trying to send some data to a webpage via esp8266wifi module connected to arduino uno. My sketch contains a header file <ESP8266WiFi.h>.After searching online I could get the library Arduino-master.zip from github. I extracted the files and put it in inside the directory arduino->hardware->arduino->avr->libraries.but even then it was showing me the error message like this:

 fatal error: ESP8266WiFi.h: No such file or directory

 #include <ESP8266WiFi.h>

                         ^

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Uno.

How can I remove this error. please refrain from technical words as i am new to this language. Thank you.

**EDIT**: After adding esp8266WiFi.h in the library i got out from that error message .But it showed me a new one

C:\Program Files (x86)\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFiType.h:26:19: fatal error: queue.h: No such file or directory

 #include <queue.h>

                   ^

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Uno.

I dont know how to come out of this error. some websites give a solution but it didn't worked for me.

title: #include<ESP8266WiFi.h> showing error message

Answers: 2

body: That library is part of the ESP8266 core. It's not for the Arduino, but for programming the ESP8266 as a standalone unit without an Arduino connected to it.

body:
ESP8266WiFi part of the project Arduino Core here: https://github.com/esp8266/Arduino Arduino Core provides support for the ESP8266 to be used with Arduino IDE through the boards manager facility. So its libraries are for the ESP8266 not the Uno.

If you are interested in communicating with the ESP8266 over serial using its AT+ command firmware then you just send them as strings over serial.

    Serial1.println("AT+GMR");
    while(Serial1.available() == 0) {
      delay(1);
    }
    while(Serial1.available() > 0) {
      Serial.write(Serial1.read());
    }


body: Say a home IoT application to monitor water levels in basement at 4 or 5 different places and transmit that data back to a single Arduino board to be then interfaced with a GUI to do home monitoring?

title: Is there any way for one Arduino board to communicate with multiple sensors?

Answers: 2

body:
Yes you can ... however, how you transmit the sensor data? If wireless, you need some RF communication, and possibly a microcontroller like Arduino (or ESP) within each sensor module.

With nRF24L01 (2.4GHz) you can use 6 'slaves' (sensor modules in your case) to send data to the master (monitoring module).

Do things one by one:

- First make one sensor module
- Than make the master to receive data
- Than make the GUI screen
- Than make the other five sensor modules

body: Yes this could be done using SPI (with separate slave select wires), i2c or daisy chained UART providing a wired solution.


body:
I don't have a correct serial port from the resource I'm working from - Getting Started with Arduino by Massimo Banzi and Micheal Shiloh. I'm using the Arduino Uno. I'm a complete noob to Arduino. In this image below, from the resource I'm working from, it specifies to use either of the ports: `/dev/cu.usbmodemfa141` or `/dev/tty.usbmodem`.

*Getting started with Arduino by Massimo Banzi and Michael Shiloh* - Figure 3-2 shows a list of available serial ports.

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

I only have two available: `/dev/cu.SSDC` and `/dev/cu.Bluetooth-Incoming-port`.

How do I get the 'correct' serial port? Correct being: `/dev/cu.usbmodemfa141` or `/dev/tty.usbmodem`.

Here's some possibly useful information:

I'm using Mac OS - which I'm new to - Sierra version 10.13.2.

I only have two ports on the computer a USB type - C and a headphone jack. So I have an 'adapter' that allows me to 'daisy chain' the USB - B and USB - A for the Arduino cable into the port of my computer. If any additional information is required, feel free to ask for it and I'll try and get back to you ASAP. Thanks.

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

title: How does one get the correct serial port?

Answers: 2

body:
I had the same problem and had even fewer options under my Tools > Port menu. Looked at the user forums but most answers did not work for me. After watching a [YouTube video][1], I fixed the problem by following its suggestion of installing the CH34X driver. There are some other suggested drivers if you search for some other related StackOverflow and StackExchange posts, but I did not test them (once the Mac-Arduino communication worked, I did not want to spend more time on this) and nor can I explain why this solution works.

I wrote [a short article on this][2] for myself. If you are interested, please take a quick look.

Best luck! :)

  [1]: https://www.youtube.com/watch?v=wyocdvAKo64&list=PLDSK_xvHetGobwkRPhNYEDzo7bdKa17lL
  [2]: https://medium.com/@shandou/a-chronicle-of-my-getting-started-with-arduino-journey-b9a2f7f20712

body: Sorry guys I solved it. It was really simple I just needed to plug the device in and it then detected the device and port name.


body:
If I do following:

    pinMode(MYPIN, OUTPUT)
    digitalWrite(MYPIN, LOW)

What will happen? Will this effectively ground _MYPIN_ or output some low voltage?

title: Is output pin set to LOW grounded

Answers: 1

body:
This will effectively connect the pin to ground. Note that the connection is
made by a transistor that has a finite resistance. This output resistance is
not really specified, but from the curves on the “typical characteristics”
section of the datasheet you can infer that the _typical_ value is about
26 Ω.

The only hard specification states that the `OUTPUT` `LOW` voltage
should be no larger than 0.9 V, as long as the pin is not sinking
more than 20 mA. C.f. the table “DC characteristics” of the
[ATmega2560
datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf#page=355).


body:
I'm doing a program that receives data from a web page every so often, but only receives the data once and then receives everything blank. I need help to receive the data every time indefinitely. I am using arduino uno with arduino etherner shield

My code:

    #include <SPI.h>
    #include <Ethernet.h>

    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

    IPAddress ip(192, 168, 0, 177);
    EthernetClient client;

    int REDLed= 2;
    int GREENLed= 3;
    int BLUELed= 4;

    void setup()
    {
      pinMode(REDLed, OUTPUT);
      pinMode(GREENLed, OUTPUT);
      pinMode(GREENLed, OUTPUT);
      Ethernet.begin(mac, ip);
      Serial.begin(9600);
      Serial.println("power up" );
      delay(3000);
    }

    void loop()
    {
      Serial.println("SubmitHttpRequest - started" );
      SubmitHttpRequest();
      Serial.println("SubmitHttpRequest - finished" );
      delay(10000);
    }

    void SubmitHttpRequest()
    {
      if (client.connect(server, 80))
      {
        Serial.println("connected");
        client.println("GET /arduino/getstate.php?color=All HTTP/1.1");
        client.println("Host: cybertodo.mx");
        client.println("Connection: close");
        client.println();
      }
      else
      {
        Serial.println("connection failed");
      }
      delay(100);
      changeLed();
    }

    void changeLed()
    {
      String content = "";
      Serial.println(client.available());
      while(client.available()!=0)
      {
        content = content + String(char (client.read()));
      }
      Serial.println(content);
      if(content.substring(30,31)== "1")
      {
        digitalWrite(REDLed, HIGH);
      }
      else if (content.substring(30,31)== "0")
      {
        digitalWrite(REDLed, LOW);
      }

      if(content.substring(31,32)== "1")
      {
        digitalWrite(GREENLed, HIGH);
      }
      else if (content.substring(31,32)== "0")
      {
        digitalWrite(GREENLed, LOW);
      }

      if(content.substring(32,33)== "1")
      {
        digitalWrite(BLUELed, HIGH);
      }
      else if (content.substring(32,33)== "0")
      {
        digitalWrite(BLUELed, LOW);
      }
      content = "";
    }

title: http request in time intervals

Answers: 1

body:
Immediately after making the request when reading client.available() will be 0 since no data was received yet so:

      while(client.available()!=0)
      {
        content = content + String(char (client.read()));
      }

Will never actually run. Try something like:

    unsigned long last = millis();
    String content = "";

    while(client.connected()) {
      int len = client.available();
      if(len > 0) {
        last = millis();

        char buff[len];
        for(int i = 0; i < len; i++) {
          buff[i] = client.read();
        }
        content += String(buff);

      } else {
        if(millis() - last > 2000) {
          client.stop();
          return;
        }
        delay(1);
      }
    }

Also note if you use Connection: close on the client then you must close the connection. This example doesn't do that until 2 seconds have passed. To do this properly you'd need to also add header parsing to your client and close the connection once the amount specified in Content-Length is received.


body:
I have a buffer which contains *16000 PCM* samples of *8Khz 8-bit mono*. I am trying to play it using *12 bit MCP4725 DAC*. I have tried using `micros()` to control the write interval for the DAC. Here's my code:

    uint8_t soundData[16000] = { 234,206,79,255,249,....,210,222 }; // 8Khz 8-bit mono
    long previousMicros = 0; // Sorry for missing this out!!

    void setup() {

    Serial.begin(115200);
    Wire.begin(D2, D1);
    delay(100); // delay 100 ms
    Serial.flush();
    delay(1000);

    }

    void value_write(uint16_t temp){

      Wire.beginTransmission(0x62);
      Wire.write(64);
      Wire.write(temp >> 4);        // the 8 most significant bits...
      Wire.write((temp & 15) << 4); // the 4 least significant bits...
      Wire.endTransmission();

    }

    void loop() {

      unsigned long currentMicros = micros();

    // 125 uS sampling for 8KHz signal
    if(currentMicros - previousMicros > 125) {
      Serial.print("Index: ");
      Serial.println(indx);
      uint16_t temp = map(soundData[indx++], 0, 255, 0, 4095);

      value_write(temp);
    }

    }

The write should logically be completed within *2 seconds* but takes way more time. Any help regarding successfully writing the *PCM values to the DAC* at *8000Hz* is greatly appreciated.

title: DAC to play audio samples

Answers: 2

body: In your code, you never set or update `previousMicros` value.

body:
One sample takes 38 I2C clock cycles to write. That's:

    1 START
    7 Address
    1 R/W
    1 ACK
    8 Byte
    1 ACK
    8 Byte
    1 ACK
    8 Byte
    1 ACK
    1 STOP

At the default 100kHz clock speed that's 100,000/38 = 2631.58 samples per second *absolute maximum*.

You can increase the clock speed to 400kHz, which would allow you 400,000 / 38 = 10526 samples per second *absolute maximum*.  That would just about be do-able.

I am unsure what the ESP8266 can support, but the DAC also supports "High Speed" mode - 3.4MHz I2C.  If the ESP8266 supports that you can then run at 3,400,000 / 38 = 89474 samples per second, which is better still.

There's also the matter of the `map()` function which is just nasty in this situation. You can just bit-shift.

So besides just removing the Serial commands (which will slow things down massively) you should also:

1. Change the I2C clock to *at least* 400kHz
2. Change `map()` to `soundData[indx++] << 4`
3. Consider using a timer to trigger the sending of the samples

But, with all that said. an I2C DAC is really not suited to audio playback. I2C is just too slow and clunky for audio. You'd be better off with an SPI DAC which can run much much faster than I2C. Better still you should investigate I2S on the ESP8266. This is designed specifically for audio, although it's much harder to set up owing to the increased number of special clocks you need to provide ("master" clock, "bit" clock and "l/r" clock). Also the DACs (also known as CODECs) tend to be at least 16 bit or even higher, and capable of proper audio sampling frequencies, like 44100ksps and above.


body:
I have a header & cpp file located in Arduino\libraries\Parentfolder\Header&Cpp. Arduino IDE recognizes my lib (the class is color coded & Sketch->include library->MyLibrary shows in the dropdown menu and #includes properly).

Problem: Arduino IDE gives `undefined reference to MyClass . . .` error in my sketch for every reference of the class including function calls. The function fully in other IDEs as header/cpps so I don't think pasting the cody is necessary -- what could I be missing? I've read a million Stack Exchange posts with similar error/watched a million YouTube guides on writing Arduino libs and I can't seem to find the differentiating factors that would make my code *not* work for Arduino IDE.

tl;dr what are the reasons that a working c++ library (self-made) would not work with Arduino IDE?

/e

    Queue.h
    #ifndef Queue_h
    #define Queue_h

    #include "Arduino.h"

    template <typename T>
    class Queue
    {
      public:
        typedef struct node
        {
          T data;
          node * next = nullptr;
        } * nodePtr;

        nodePtr head; // = nullptr;
        nodePtr tail; // = nullptr;
        nodePtr curr; // = nullptr;
        nodePtr temp; // = nullptr;

        unsigned int counter;

        Queue();
        void push(T);
        T& peek();
        T pop();
        int size();
        bool isEmpty();
        void clear();
    };

    #endif

Queue.cpp

    #include "Arduino.h"
    #include "Queue.h"

    template <typename T>
    Queue<T>::Queue()
    {
        nodePtr head = nullptr;
        nodePtr tail = nullptr;
        nodePtr curr = nullptr;
        nodePtr temp = nullptr;

        counter = 0;
    }

    template <typename T>
    void Queue<T>::push(T data)
    {
      if (head == nullptr)
      {
        head = new node;
        head->data = data;
        tail = head;
      }
      else
      {
        temp = head;
        head = new node;
        head->data = data;
        head->next = temp;
      }
      counter ++;
    }

    template <typename T>
    T& Queue<T>::peek()
    {
      if (head == nullptr)
      {
        return 0;
      }
      return head->data;

    }

    template <typename T>
    T Queue<T>::pop()
    {
      // Empty
      if (head == nullptr)
      {
        return 0;
      }

      // Head = tail
      if (head == tail)
      {
        T data = head->data;
        delete head;
        return data;
      }

      // Size > 1
      curr = head;
      while (curr->next != tail)
      {
        curr = curr->next;
      }
      T data = curr->next->data;
      tail = curr;
      curr = curr->next;
      delete curr;
      counter --;
      return data;
    }

    template <typename T>
    int Queue<T>::size()
    {
      return counter;
    }

    template <typename T>
    bool Queue<T>::isEmpty()
    {
      if (counter ==0)
      {
        return true;
      }
      return false;
    }

    template <typename T>
    void Queue<T>::clear()
    {
      while (head->data != nullptr)
      {
        temp = head->next;
        delete head;
        head = temp;
      }
      if (head == nullptr)
      {
        return;
      }
      delete head;
      return;
    }

.ino

    . . .
    Queue<float> avgQueue;
    . . .

error

    . . . In function `__static_initialization_and_destruction_0':
    . . . undefined reference to `Queue<float>::Queue()'

***SOLVED:***

Combining the .cpp contents in the .h and removing the .cpp worked.

title: Problems recycling c++ lib with templated class for Arduino

Answers: 1

body:
***SOLVED:***

Putting the .cpp contents in the .h and removing the .cpp from the lib folder entirely worked.


body:
I'm trying to make my own home wireless security system.  I will be using probably 3 AA batteries to power these devices.  My problem is that I need to know if the batteries will be enough to power the devices for at least 6 months.
Below are the details of all the devices I will be using:

1. Mini Nano V3.0 ATmega328P Microcontroller Board w/USB Cable For Arduino
2. Makerfire Arduino NRF24L01+ 2.4GHz Wireless RF Transceiver Module
3. uxcell MC 38 Mount Wired Door Window Sensor Magnetic Reed Switch Recessed

Below are some project requirements that might be useful:

1. For the Nano, I want to put it to sleep using delay(2000) in the loop() function.  The Nano will be the one checking the window sensor.
2. I will be using a project enclosure of about 4X4 inches.

If this will not be possible maybe someone knows of other devices that use less power that will be more suitable for this project? I would prefer something easy to use like Arduino Nano with USB so I can easily program it.

EDIT: sorry but I just like to add that from the main HUB component, I would like to check the status of the window sensor if it is open/closed.  This will be useful if there is an open window/door around the house when going to sleep. Probably the Nano will broadcast its current window sensor status to the main HUB program. Thanks.

title: Battery life calculation using Nano, NRF24L01+ and window magnetic reed switch

Answers: 3

body:
You should use interrupts for the reed switch and then put the microcontrolller into sleep for a keep alive interval. Your master device should check that the sensor is still active and set off the alarm if its not. You would also want to allow for a battery low condition that might disable the alarm for convince. This still should keep the power consumption low.

The nano is roughly 1mA @ 3.3v while the CPU is running and 72uA when its in sleep. Discounting power consumption in the alarm condition triggered by the interrupt using an interval of 9 seconds using delay or interrupt timers then average consumption then about a second to wake up and send a keep alive over the RF. (0.000072 * 9 + 0.001 * 1) / 10 = 0.0001648 amps. (average over 10 second duty cycle)

My guesstimate of your RF power consumption without knowing what kind of protocol would be somewhere around 128 bytes per transmission taking about 90ms. (0.0001 * 9910 + 0.015 * 90) / 10,000 = 0.0002341 amps.

Total of their averages is: 0.0003989 or 398.9uA.

Alkaline AA cells vary widely. So instead based on some Ni-MH with 2400mAh per cell and 1.2v

3 cells would be 3.6v so you'll "get" most of the mAhs out of the batteries.

2400mAh = 2400000uAh

2400000uAh / 398.9uA ~= 6016.54 hours or 250 days or 8 months.

Power consumption were intentional overestimates. You should be able to make it last a lot longer.

https://www.avrprogrammers.com/howto/atmega328-power
http://harizanov.com/2013/05/nrf24l01-power-consumption-footprint/

body: It only seems to do one thing: activate an alarm if the reed switch changes.  Power the system _through_ the reed switch. It will have zero standby current and the battery will last the shelf life. That said, you might be able to use an RF module w/o even a MCU, though not that particular one...

body: You should use a reed switch that is both NC and NO. Then power only the disconnected part of the switch and listen to pin changes and put everything into sleep. This can improve your power consumption. See the answers postet here: [Low Power Pin Change Detection](https://arduino.stackexchange.com/questions/34067/low-power-pin-change-detection-attiny)


body:
I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears **repeatedly** adding `float position + float speed` in a struct ends up borking the whole thing.

The purpose of the code is to animate at most `MAX_PARTICLES` particles ("pixels") traveling at random speeds across the LED stripe.

The array named `particles` stores the current list of particles being managed. Each particle in the array is stored as a struct, as defined at the beginning of the code. Particles are added to the array using function `addParticle()` at the very end of the code. Particles which reach the end of the stripe are killed in the second part of the `loop()` function (after `FastLED.show()`).

Here's the code:

    #define FASTLED_INTERNAL // Eliminates a compiler warning
    #include <FastLED.h>
    #include <colorutils.h>
    #define NUM_LEDS 149
    #define DATA_PIN 6
    #define MAX_PARTICLES 5 // This uses up the memory, mostly
    CRGB leds[NUM_LEDS];

    struct particle {
      float position;
      CRGB color;
      float speed;
      int id;
    };
    typedef struct particle Particle;
    Particle particles[MAX_PARTICLES];
    int numParticles = 0;
    int maxId = 0;

    // Gramma correction tables (Defalt Gamma = 2.8)
    const uint8_t PROGMEM gammaR[] = {
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,
        2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,
        5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,
        9,  9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14,
       15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
       23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33,
       33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 46,
       46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
       62, 63, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 80,
       81, 83, 84, 85, 87, 88, 89, 91, 92, 94, 95, 97, 98, 99,101,102,
      104,105,107,109,110,112,113,115,116,118,120,121,123,125,127,128,
      130,132,134,135,137,139,141,143,145,146,148,150,152,154,156,158,
      160,162,164,166,168,170,172,174,177,179,181,183,185,187,190,192,
      194,196,199,201,203,206,208,210,213,215,218,220,223,225,227,230 };

    const uint8_t PROGMEM gammaG[] = {
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,
        2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,
        5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9, 10,
       10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
       17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
       25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
       37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
       51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
       69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
       90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
      115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
      144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
      177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
      215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };

    const uint8_t PROGMEM gammaB[] = {
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,
        2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,
        4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  7,  7,  7,  8,
        8,  8,  8,  9,  9,  9, 10, 10, 10, 10, 11, 11, 12, 12, 12, 13,
       13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19,
       20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28,
       29, 30, 30, 31, 32, 32, 33, 34, 34, 35, 36, 37, 37, 38, 39, 40,
       40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53,
       54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 70,
       71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 83, 84, 85, 86, 88, 89,
       90, 92, 93, 94, 96, 97, 98,100,101,103,104,106,107,109,110,112,
      113,115,116,118,119,121,122,124,126,127,129,131,132,134,136,137,
      139,141,143,144,146,148,150,152,153,155,157,159,161,163,165,167,
      169,171,173,175,177,179,181,183,185,187,189,191,193,196,198,200 };

    void setup() {
      FastLED.addLeds<WS2812B, DATA_PIN, BGR>(leds, NUM_LEDS);
      randomSeed(analogRead(0));
      Serial.begin(115200);
    }

    void loop() {
      if (numParticles < MAX_PARTICLES && random(10)>8) {
        addParticle();
      }

      for (int i=0; i<numParticles; i++) {
        // Antialiasing
        int basePosition = floor(particles[i].position);
        byte percentOnePos = round(255 * (particles[i].position-basePosition));
        byte percentBasePos = 255 - percentOnePos;
        CRGB color0 = particles[i].color % percentOnePos;
        CRGB color1 = particles[i].color % percentBasePos;

        leds[basePosition] += color0;
        leds[basePosition+1] += color1;
      }

      // Apply gamma correction
      for (int i=0; i<NUM_LEDS; i++) {
        //leds[i] = applyGamma_video(leds[i], 2.2);
        // *** applyGamma_video(2.2) pros and cons:
        // PROs: smoother color transitions
        // CONs: much slower; much worse color calibration
        // TODO: pre-render custom, color calibrated gamma tables

        leds[i].red = pgm_read_byte(&gammaR[leds[i].red]);
        leds[i].green = pgm_read_byte(&gammaG[leds[i].green]);
        leds[i].blue = pgm_read_byte(&gammaB[leds[i].blue]);
      }

      FastLED.show();

      for (int i=0; i<numParticles; i++) {
        int basePosition = floor(particles[i].position);
        leds[basePosition] = CRGB::Black;
        leds[basePosition+1] = CRGB::Black;
        particles[i].position += particles[i].speed;
        if (particles[i].position > (NUM_LEDS+1)) { // We want to render it fading out
          for (int j = i; j<numParticles-1; j++) {
            particles[j] = particles[j+1];
          }
          numParticles--;
          i--; // We want the for() cycle to process the particle we shifted down
        }
      }
      debugParticles();
    }

    void debugParticles()
    {
      for (int i = 0; i<MAX_PARTICLES; i++) {
        if (i>0) {
          Serial.print(", ");
        }

        Serial.print(i);
        Serial.print(",");
        Serial.print(particles[i].id);
        Serial.print(",");
        Serial.print(particles[i].position);
      }
      Serial.println("");
    }

    void addParticle()
    {
      particles[numParticles].color = CHSV(random8(),255,150);
      particles[numParticles].position = 0;
      particles[numParticles].speed = (0.0+random(10))/100+0.01;
      particles[numParticles].id = maxId++;
      numParticles++;
    }

For debugging purposes, each unique particle ever created has a unique ID. The debugging output contains the following fields:

- [0] the array index for the first entry in the array (always 0)
- [1] the unique ID of the particle stored in the first record of the array
- [2] the position of the particle stored in the first record of the array
- [3] the array index for the second entry in the array (always 1)
- [4] the unique ID of the particle stored in the second record of the array
- [5] the position of the particle stored in the second record of the array
- (and so on – three fields for each record in the particles array)

Finally, here's an interesting excerpt from the output, after ~1,500 records:

    0 0 30.36 1 1 30.28 2 2 147.70 3 3 59.04 4 4 73.15
    0 0 30.38 1 1 30.30 2 2 147.80 3 3 59.08 4 4 73.20
    0 0 30.40 1 1 30.32 2 2 147.90 3 3 59.12 4 4 73.25
    0 0 30.42 1 1 30.34 2 2 148.00 3 3 59.16 4 4 73.30
    0 0 30.44 1 1 30.36 2 2 148.10 3 3 59.20 4 4 73.35
    0 0 8.00 1 1 30.38 2 2 148.20 3 3 59.24 4 4 73.40
    0 0 8.00 1 1 30.40 2 2 148.30 3 3 59.28 4 4 73.45
    0 0 8.00 1 1 30.42 2 2 148.40 3 3 59.32 4 4 73.50
    0 0 8.00 1 1 30.44 2 2 148.50 3 3 59.36 4 4 73.55
    0 0 8.00 1 1 30.46 2 2 148.60 3 3 59.40 4 4 73.60
    0 0 8.00 1 1 30.48 2 2 148.70 3 3 59.44 4 4 73.65
    0 0 8.00 1 1 30.50 2 2 148.80 3 3 59.48 4 4 73.70
    0 0 8.00 1 1 30.52 2 2 148.90 3 3 59.52 4 4 73.75
    0 0 8.00 1 1 30.54 2 2 149.00 3 3 59.56 4 4 73.80
    0 0 8.00 1 1 30.56 2 2 149.10 3 3 59.60 4 4 73.85
    0 1 0.00 1 2 149.20 2 3 59.64 3 4 73.90 4 4 73.85
    0 1 0.00 1 2 149.30 2 3 59.68 3 4 73.95 4 4 73.85
    0 1 0.00 1 2 149.40 2 3 59.72 3 4 74.00 4 4 73.85

Notice how in all but the last three lines, the array index and the particle ID are still in sync (0=>0, 1=>1, 2=>2, 3=>3, 4=>4), which means no particles have died yet (new particles would have larger IDs). I'm trying to say that no particle re-assignment magic has happened yet – for now, we're just running the boring code which moves particles along the strip.

And yet, on the sixth line in the output, the first particle's position becomes mangled – notice how on the first five lines the first particle's position has steadily increased by 0.02 (presumably that particle's speed) up to 30.44, whereas on the sixth line it inexplicably becomes 8.00 (other times I experimented, it becomes 32.00). Not only that, but that 8.00 (the particle's position) never increases again, and three lines from the bottom the code also decides to kill the first particle altogether (notice that the second column becomes 1, which means the first record in the particles array now stores the particle with unique ID 1, instead of unique ID 0).

I have no idea what I'm doing wrong – I've been experimenting with this over and over, killing off all the bugs and warnings I could find, and still no luck.

title: FastLED + structs + PROGMEM strange behavior

Answers: 1

body:
As you are keeping the particles over the position 149 (because of fading), I'd expect overwritting the memory after the space allocated for the `leds` variable.

According to the log it started somewhere around position 148, which is earlier, but in your code is this:

    int basePosition = floor(particles[i].position);
    leds[basePosition] += color0;
    leds[basePosition+1] += color1;

So if you have position 148, you are already changing something after the array. It might add zero values in the color1 (for `148.0` and `148.1`) so it didn't changed anything but later the value gets nonzero and changes a wrong memory.


body:
I have a simple HTML file that I have uploaded as sketch data using the ESP8266 sketch data upload tool in arduino IDE. The file is 7k in size.

In the set up, I refer to the following function to read the file:

    String readTemplatefile(){
      String retval ="";
      File fr = SPIFFS.open("/templatecfg.htm", "r");

      if(!SPIFFS.exists("/templatecfg.htm")){

        Serial.println("Template file not available ");
        }
        while (fr.available()){
            retval += char(fr.read());
          }

    fr.close();
    Serial.println("Template file = ");
    Serial.println(retval);
    return retval;
    }

I always get 'Template file not found'. I have

    SPIFFS.begin();

at the beginning of the setup function

My board is an ESP8266EX. I have wondered if it the flash size settings in the IDE that could cause this not to be found. Can anyone offer any advice on this issue. I have tried lots of different combinations of Flash size and SPIFF sizes without any luck.

Thanks in advance to any help.

title: ESP8266 SPIFFS file not found

Answers: 2

body:
@dandavis Yes, I had SPIFFS.begin() in my setup routine.

I ran a sample sketch and was able to see the a file on the device, so I routed round the code some more and found than an included library was ending SPIFFS after it had performed a file read. This was the issue. Thanks all for your consideration, but the code I had was fine, just the included library was mis-behaving.

body: SPIFFS will always claim to successfully open a file that begins with a slash even if that file does not exist.  Remove the leading slash.


body:
I'm trying to run the AzureIoTProtocol_MQTT/esp8266 example, but I get linker errors:

> Archiving built core (caching) in:
> /var/folders/fj/y3vtrz597kv4885q1b_5qypr0000gn/T/arduino_cache_934614/core/core_esp8266_esp8266_d1_mini_CpuFrequency_80,UploadSpeed_921600,FlashSize_4M3M_e1e103f2055a19e071ac9522162e1787.a
> libraries/AzureIoTHub/sdk/agenttypesystem.c.o: In function `sscanfd':
> /Users/jonas/Documents/Arduino/libraries/AzureIoTHub/src/sdk/agenttypesystem.c:2826:
> undefined reference to `strtoull'
> libraries/AzureIoTHub/sdk/agenttypesystem.c.o: In function
> `sscanfllu':
> /Users/jonas/Documents/Arduino/libraries/AzureIoTHub/src/sdk/agenttypesystem.c:2826:
> undefined reference to `strtoull'
> libraries/AzureIoTHub/sdk/agenttypesystem.c.o:(.text.CreateAgentDataType_From_String+0xac):
> undefined reference to `strtof'
> libraries/AzureIoTHub/sdk/agenttypesystem.c.o: In function
> `CreateAgentDataType_From_String':
> /Users/jonas/Documents/Arduino/libraries/AzureIoTHub/src/sdk/agenttypesystem.c:3571:
> undefined reference to `strtof' collect2: error: ld returned 1 exit
> status

The issue can be broken down to the call to `strtof` function call. I get the same error with only this very simple code snippet:

    #include <stdlib.h>

    void setup() {
      char szOrbits[] = "686.97";
      float f;
      f = strtof (szOrbits, NULL);
    }

    void loop() {
    }

Tested environment: Mac OS X 10.13.2 with Arduino 1.8.3 AND Windows 10 with Arduino 1.8.5.

title: Undefined reference to stdlib (strtof) while compiling

Answers: 2

body:
Its because the "strtof" function resides in "stdlib.h",
"Stdio.h" deals with i/o tasks.

Since you din't include you get that undefined reference error.
Correct that and compile again. Hopefully the error shall be resolved, else reply in the comments.

>## Update1:
After digging around standard gcc stdlib definitions and avr-gcc definitions found out that the above solution works for a gcc and not avr-gcc especially the 8-bit ones which the arduino IDE compiles for uno and the works as expected for 32bit processors like of Due.

> Cite:
>
>1. https://www.arduino.cc/reference/en/language/variables/data-types/double/
>2. https://www.arduino.cc/reference/en/language/variables/data-types/float/

## Reason:
The size of the double and float is the same, ie: 4 bytes
and even if you use double its actually the float itself and wont gain any precision advantage.

##Solution:
Since the size of the double and the float is same there is not point in having two function definition doing the same job.
so

 1. **Use "strtod"  instead of "strtof"** or
 2. Define a macro **#define strtof(A, B) strtod(A, B)** in the begning of your sketch so that the "strtod" handles the functioning of the "strtof".

body:
Its because you haven't added the core of esp8266 to the arduino IDE.
you are defaulting it to the "UNO" board and compiling it.
so you get that error for which i have explanation

here: https://arduino.stackexchange.com/a/48719/3557

solution for your problem is simple added the esp8266 core and select the right board and compile again.

Cite: https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/installing-the-esp8266-arduino-addon

Follow above link and install the esp8266 core.


body:
I am new to Arduino programming and I'm really fascinated with its working. Is there a way to know if an Arduino is getting switched off or being reset? Like a function would be called before the Arduino gets switched off.

I want to detect this event *to preserve a value*, where a user resets his Arduino, or switches it off. Is it possible?

title: Lifecycle hook in Arduino to know if Arduino is reset or powered down

Answers: 2

body:
You can read the `MCUSR` status register to determine the source of the reset.

Sources can be the Watchdog timer, brownout (too low a voltage), reset (button), or power-cycle.

body:
> EEPROM has a limit of 100,000 write/erase cycles, so we cant do more than that

You have 1k bytes of EEPROM and they survive a minimum of 100,000 writes. So that's 102,400,000 writes you could potentially do, if you are saving one byte. Even at one write a second that would be around 3 years.

However the EEPROM page size is 4 bytes, so that is actually 25,600,000 writes you could get away with (of 4 bytes at a time). Still, that is quite a lot of writes.

A while back I tested one of my chip's EEPROM and found that it greatly exceeded the 100,000 writes specified before it starting misreading the data back.

Also, if you refrain from writing if the value hasn't changed (hopefully that's a lot of the time?) then you could probably extend the life to 100 years.

---

> Like a function would be called before the Arduino gets switched off.

No, that's impossible. How would it possibly know it is about to be switched off? Once it is switched off, functions are hardly going to be able to run.

---

  > Is there a way to know if an Arduino is getting switched off or being reset?

Once you hit Reset the processor starts again. It doesn't run any functions "just before" or "just after" being reset (using the original variables). That would mean that the reset doesn't actually reset it.

---

If you are designing some gadget that lets you configure it (eg. with a volume control) then simply save the new setting to EEPROM when it is changed. This is hardly going to happen 24 hours a day.


body: Using an ESP8266 I can get the RSSI of the Wifi network using `Wifi.getNetworkInfo()` or `Wifi.RSSI()`. But is there a way to know the actual connection speed in Mbps, after joining successfully a WiFi network?

title: Can I get the current connection speed with ESP8266?

Answers: 1

body:
Wifi modules decide on link speed based on signal strength. So you can estimate the link speed with signal strength, which you can get with `WiFi.RSSI(network)`.

[The datasheet](https://www.itead.cc/wiki/ESP8266_Serial_WIFI_Module) of ESP8266 contains a table mapping RSSI to link speed under "Sensitivity":

- -98 dBm: 1 Mbps
- -93 dBm: 6 Mbps
- -91 dBm: 11 Mbps
- -75 dBm: 54Mbps
- -71 dBm: 65Mbps, 72.2Mbps

Whenever these values are "minimum", "maximum" or "typical" remains unclear. These dBm limits are also quite low, which means the link speed will probably be capped by the other communication peer (your router). [Here](http://bpastudio.csudh.edu/fac/lpress/471/hout/wireless/wifipower.htm)'s the same table for a random D-link router, DI-624.


body: I'm new to Arduino and coding but I build wooden clocks.  The biggest problem is timing the clock to the correct beats per min when adjusting pendulum length.  I'm thinking Arduino and an IR sensor?? to detect when the pendulum breaks the beam, then displaying the beats per min real time would be possible.  If not real time then just beats in a variable time period, ie 1 min or 2 or 5 or 10 min.  I've looked for this type of code and circuit but haven't been able to find one.  Any help would sincerely be appreciated.

title: Code for determining beats per min when timing a wooden clock

Answers: 2

body:
I'd suggest to have the Arduino send a message to the PC when a 'tick' occurs. Then have the PC do the calculations over a larger number of ticks. You can even have the PC measure it's drift using NTP (PC clocks also aren't extremely accurate, but better that the crystal on the Arduino).

The procedure that I used, I found at https://www.logre.eu/wiki/Horloge_analogique_24h/en#Quartz_calibration I ran it for a few hours. Which might also be useful in your case to see if the swing is consistent.

I used this to calibrate my Arduino clock to within a few seconds per year,

body:
If the accuracy you require is about 1%, that should be doable with any
Arduino. Much higher accuracies would be hard to achieve because most
Arduinos are clocked off a ceramic resonator, and these have a frequency
tolerance of about 0.5%.

Given that your signal is very slow, the simplest approach may be to
poll the pin connected to the sensor and record the time (using
`micros()`) of the low → high transition. Then you can compute the
beat frequency as the inverse of the time between consecutive
transitions.

There is, however, the possibility that the sensor is not exactly in
the middle of the swing. Then, for better accuracy, I would measure the
time taken by _two_ beats, i.e. a full swing. This way the pssible
asymmetry will not affect the accuracy.


body:
I am currently working in void loop() and have setup a distance meter that constantly checks the distance.

Once the distance threshold is met, a function is called. Now I only need this function to be called ONCE. But because the distance meter is constantly scanning (which I need), the function is also being repeatedly called. I tried making some sort of timer but I can't figure it out. Can someone please have a look at this?

    if (distance <= 150){
        personPresent();
        }

      if(distance > 150){
        personAbsent();
          }

I need certain events within the if statement to occur only once. E.g., I want to register when there is a personPresent and have that event not fire repeatedly.

In this case, personPresent() is attached to a GPIO pin which triggers a buzzer sound. As it is now, the buzzer keeps on ringing as long as distance is less then 150. I need the buzzer to make a sound only ONCE and then not buzz for at least 5 minutes.

title: How do I create a constant loop with an event that only occurs once?

Answers: 3

body:
    static boolean didItAlready = false;

    if(distance > 50 && !didItAlready){
         doIt();
         didItAlready = true;
    }

You simply need a variable to keep track of whether or not it has been done.  If and when you want to do the action again then set your variable back to false.

body:
What you want is not to check the distance but to check that the distance condition changed.

    static boolean present = false;

Inside loop:

    if (present == false && distance <= 150){
        personPresent();
        present = true;
    } else if(present == true && distance > 150) {
        personAbsent();
        present = false;
    }

body:
You just need a global variable to track whether it is done or not like this...

    //  other Codes

    bool State=0;

    void setup(){

    // other Codes...

    }

    void loop(){

    if(distance <= 150 && State==0){

    personPresent(); // This function should get executed only once
    State=1;

    }else if(distance>150 && State==1){

    personAbsent(); // This sould also get executed once
    State=0;

    }

    }

The global boolean variable ''' State ''' will keep track of how and when the functions need to be executed once, whenever conditions are met. And the boolean variable changes everytime (distance AND Sate) the conditions are met triggering those functions once per bool update.


body:
I was working on a project build initialy from the Arduino IDE to program an attiny84a (without a bootloader) using the board from https://github.com/damellis/attiny

I got an atmel-ice recently and I was trying to debug the arduino sketch using it.

I installed AtmelStudio (because I know it has an GUI debugger) and found VisualMicro that should help me to compile arduino sketch.
Unfortunatly as soon as a set the project to debug I got a compilation error :

    'Serial' was not declared in this scope

(I don't have this error in Release mode).

My code doesn't use any serial (because I don't have any pin left), so this was wierd. I still tried to add the SoftwareSerial.h include (just in case) without success.

So I created an empty (I mean with only an empty setup() and loop() methods) and it throw the same error.

I tried to setup different versions of arduino IDE into VisualMicro (1.6.13, 1.8.1, 1.8.5 and 1.9 build 34) without success.

Then after a couple of hours I found the .cpp source generated by VisualMicro and it try to use the member "Serial" for some debugging reason.

I would like an easy way to integrate with arduino (all those library and easy to install library) and to be able to debug as well, what can I look for or do?

Thank

title: VisualMicro Can't compile in debug ('Serial' was not declared in this scope) for attiny84a

Answers: 2

body:
    'Serial' was not declared in this scope

This error is not surprising when compiling for ATtiny84 because in Arduino `Serial` refers to the hardware serial port and ATtiny84 [doesn't have one](https://www.microchip.com/wwwproducts/en/ATtiny84).

But you didn't use `Serial` in your sketch so why should you get this error? The answer is this magical debug feature of Visual Micro that you desire. It turns out that on AVR microcontrollers such as your ATtiny84 all this actually consists of is Visual Micro automatically inserting various Serial.print() statements into your code, just as we always do manually to debug our code in the good old Arduino IDE:

http://www.visualmicro.com/page/User-Guide.aspx?doc=Debugging-Explained.html

So in fact your sketch is attempting to use `Serial` without your knowledge or being able to see it! If you turn off debugging you should no longer get that error.

Visual Micro does allow you to change the debugging output to software serial:

http://www.visualmicro.com/page/User-Guide.aspx?doc=Debugging-With-Different-Ports.html

but since you say you have no pins available that may not be any help.

body:
I found how to disable the vMicro debugging, in AtmelStudio open the "vMicro" menu then click the "Debugger" item and make sure the option "Atmel Studio Debugger" is checked.

1) Change the optimization flag to a usefull state (-Og or -O0) in order to NOT have "Unknown identifier" or "Optimized away" when looking at variable.

I tried:

- Put -Og in the project property "Extra flags" (vMicro)
- Before my code I added

        #pragma GCC push_options
        #pragma GCC optimize ("Og")

    then at the end of my code

       #pragma GCC pop_option

**ANSWER:** I probably fuckup in the rebuild because only the line below is enough (in the .cpp file):

        #pragma GCC optimize ("Og")

- Replaced -Os in playform.txt (in this case it didn't work at all)

I saw a size changes in my binary (except for the last point), but when running the simulator I still couldn't see any value.

2) Couldn't start a debugging session
(When I try to change the debugging device it always crash AtmelStudio, I think it is because the target IC is force to ATSAM3X8E by the vMicro plugin which isn't supported on my computer, and because it isn't supported I can't change the target IC to attiny84a...)

**ANSWER:** When creating the project vMicro read the current board selected (yes before you even can select it) to detect if it has to create a 32 bits or 8 bits project

Also you **MUST** create a project with an .ino (even if it is empty) as the same name as the project in order to be able to compile.


body:
    #include <Keypad.h>

    int myNum[4];

    const byte ROWS = 4;
    const byte COLS = 4;
    char keys[ROWS][COLS] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };
    byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 8,7,6,5
    byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad 4,3,2,1
    Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

    void loop() {
      Serial.println("Enter four-digit num -");  // request for input
      for (int i = 0; i < 4;){
        if(keypad.getKey()!= NO_KEY) {
          myNum[i] = keypad.getKey();
          i = i+1;
        }
      }
      Serial.print("Entered number is = ");
      Serial.print(myNum[0]);
      Serial.print(myNum[1]);
      Serial.print(myNum[2]);
      Serial.println(myNum[3]);
      delay(500);
    }

I want that when I press a 4-digit number on the keypad it should be shown in the serial monitor. This code gives 0000 when I press any key on keypad.

title: Input 4-digit number using 4*4 keypad and show in serial monitor

Answers: 2

body:
`keypad.getKey()` is non-blocking as you can read [here][1]: it will return a value immediately, even if no key is pressed.  You have a `for` loop which will increment `i` each time, and you also increment it yourself. So what's happening is that your code is immediately making four readings, all of which are no-key-pressed so it doesn't store them, and then printing whatever happens to be in the `myNum` buffer.

Instead, you need to wait each time until a key is pressed, and only then move to the next digit. There are of course many ways you could do this.  I hope this is clear:

    #include <Keypad.h>

    int myNum[4];

    const byte ROWS = 4;
    const byte COLS = 4;
    char keys[ROWS][COLS] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };
    byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 8,7,6,5
    byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad 4,3,2,1
    Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

    void loop() {
      Serial.println("Enter four-digit num -");  // request for input

      for (int i = 0; i < 4; ++i){
        while((myNum[i] = keypad.getKey())==NO_KEY) {
          delay(1); // Just wait for a key
        }
        // Wait for the key to be released
        while(keypad.getKey() != NO_KEY) {
          delay(1);
        }

      }

      Serial.print("Entered number is = ");
      Serial.print(myNum[0]);
      Serial.print(myNum[1]);
      Serial.print(myNum[2]);
      Serial.println(myNum[3]);
      delay(500);
    }

  [1]: https://playground.arduino.cc/Code/Keypad

body:
    #include <Keypad.h>

    char myNum[4];

    const byte ROWS = 4;
    const byte COLS = 4;
    char keys[ROWS][COLS] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };
    byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 8,7,6,5
    byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad 4,3,2,1
    Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

    void loop() {
      Serial.println("Enter four-digit num -");  // request for input

      for (char i = 0; i < 4; ++i){
        while((myNum[i] = keypad.getKey())==NO_KEY) {
          delay(1); // Just wait for a key
        }
        // Wait for the key to be released
        while(keypad.getKey() != NO_KEY) {
          delay(1);
        }

      }

      Serial.print("Entered number is = ");
      Serial.print(myNum[0]);
      Serial.print(myNum[1]);
      Serial.print(myNum[2]);
      Serial.println(myNum[3]);
      delay(500);
    }


body:
I have designed a board based on an ATmega2560 chip and I burned the bootloader by following [this tutorial][1].

Now I am able to load Blinky and other programs using an FTDI cable. But the issue I am facing right now is the controller runs Blinky fine if I leave the FTDI connected there. If I disconnect the FTDI cable and power-cycle the board it is not running Blinky. If I connect the FTDI, right away it starts blinking.

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

It looks like something is wrong with my RESET pin connection? Here is what my RESET circuitry looks like:

- I also have tried by removing D1 diode but no luck !

  [1]: https://www.gammon.com.au/bootloader
  [2]: https://i.stack.imgur.com/tF78W.png

title: ATmega 2560 with Arduino bootloader running issue

Answers: 2

body:
The issue was there was some noise on RX Pin of the chip and because of that when it is powered on in bootloader it was stuck at that place. And it was working good with FTDI because RX gets proper connection with my FTDI.

Solution:- Connect 10K pull-down on RX pin resolved this problem.

body: Or get rid of C6, I have never used that in a design.


body:
I would like to purchase this [dual H-bridge module][1]. I plan on connecting it to an Arduino Uno. In the products [datasheet][2] the specified power supply (Vd) is 6.5-12V, and the voltage for the motor control pins is 2.3V HIGH and -0.3V LOW.

**My question** is whether this product is compatible with the standard 5V of Arduino Uno for both the power supply and logic; i.e. can I connect the Vd to the 5V terminal of the Arduino and the control pins to the digital terminals?

If not, what modifications do I need in order to use this H-bridge with an Arduino?

*Note:* Originally I bought [this][3] cheap module and connected the motor control pins to the Arduino, but each output returned a different output voltage!

  [1]: https://www.digikey.com/products/en?mpart=DRI0002&v=1738
  [2]: https://media.digikey.com/pdf/Data Sheets/DFRobot PDFs/DRI0002_Web.pdf
  [3]: https://www.aliexpress.com/item/Free-shipping-1pcs-lot-Special-promotions-2pcs-lot-L298N-motor-driver-board-module-stepper-motor-smart/1872427142.html?spm=a2g0s.9042311.0.0.DWm0WZ

title: L298 module - unusual power specs

Answers: 1

body:
That's a very poor datasheet. I think it's using equals signs where it means less-or-equal, so:

> High level: 2.3V = Vin = Vss

Intends to say that Vin between 2.3 and Vss will be considered high, and

> Low:-0.3V = Vin = 1.5V

Intends to say that Vin between -0.3 and 1.5V will be considered low.

"Vss" in the high level definition is confusing, because in the rest of the datasheet, "VD" is used for the logic voltage and "VS" is used for the motor; you'd expect the upper limit to be the logic voltage.

**The diagram at the end of the datasheet shows how it can be used with an Arduino.** A 7.5V source is going into the Vin pin (instead of the barrel jack, which is unusual). There's a protection diode on the power input which incurs a ~1V voltage drop, so the Arduino Vin pin should be outputting 6.5V, which drives the board. The digital outs from the Arduino, when driven high, are at 5V, well above the 2.3V threshold given on the datasheet.

I'd recommend powering the Arduino through the barrel jack with a 7.5V or 9V supply to drive the logic side of the board. (Powering through the USB port will put 5V or less on the Vin pin.)

You'll want a more robust supply for the motor side, because the Arduino can't deliver very much current.


body:
I need to monitor a battery plugged to an ATmega running on standalone mode.

I use the "ATmega on a breadboard (8 MHz internal clock)" bootloader.
[More info here][1]

When the ATmega is powered with 5V the sketch outputs good values : arround 5100 mV.

But when I power it with 3.3V the sketch gives strange values : arround 178619 mV.

Here is my code [Inspired from here][2]

    void setup()
    {
      Serial.begin(9600);
      Serial.println(F("Internal Voltage Sensor"));
    }

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

    long readVcc()
    {
      long voltage=0;
      uint8_t wADC;

      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      ADCSRA |= _BV(ADEN);  // enable the ADC

      delay(20); // Wait for Vref to settle

      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA,ADSC)); // measuring

      // Reading register "ADCW" takes care of how to read ADCL first and ADCH then.
      wADC = ADCW;

      voltage = 11253000L / wADC; // Calculate Vcc (in mV); 1125.3 = 1.1*1023*1000
      return voltage; // Vcc in millivolts
    }

I don't understand what's going on. The returned value with Vcc=3.3V should be lower than with VCC=5V. Something like 3300 mV !

  [1]: https://forum.mysensors.org/topic/3018/tutorial-how-to-burn-1mhz-8mhz-bootloader-using-arduino-ide-1-6-5-r5
  [2]: https://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/

title: Vcc measurement with internal 1.1V reference fails on 3.3V powered Atmega328

Answers: 1

body:
Thanks for your answers!
Jot gave the solution: wADC must be a uint16_t.

Here is the corrected code :

 void setup()
 {
   Serial.begin(9600);
   Serial.println(F("Internal Voltage Sensor"));
 }

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

 long readVcc()
 {
   long voltage=0;
   uint16_t wADC;

   // Read 1.1V reference against AVcc
   // set the reference to Vcc and the measurement to the internal 1.1V reference
   ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
   ADCSRA |= _BV(ADEN);  // enable the ADC

   delay(20); // Wait for Vref to settle

   ADCSRA |= _BV(ADSC); // Start conversion
   while (bit_is_set(ADCSRA,ADSC)); // measuring

   // Reading register "ADCW" takes care of how to read ADCL first and ADCH then.
   wADC = ADCW;

   voltage = 1125300L / wADC; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
   return voltage; // Vcc in millivolts
 }


body:
I have 3 Arduino boards, let's call them be A, B, C. I'm connecting A with a bluetooth module and I'm getting the input from the bluetooth module.
Now I want to send output from A using the digital pins and I want the output of A to be the inputs of B and C. The output sent from A will be based on voice input from the bluetooth module. The inputs of B and C will provide output signals to L293D and L298N motor drives. I have only one bluetooth module. Is this possible? Please let me know, it's urgent. I'm working on a project.

title: Arduino connection with Arduino

Answers: 1

body:
If you can connect ABC with wires, then it is easy - I use Wire library to send a lot of messages to net of many Arduinos.

Also other protocols are avaiable, like SPI, software serial, ... or if the communication is extremely easy (like just On/Off), then digitalWrite()/digitalRead() would work really easy.

I see the voice input to be more difficult in Arduino-size computers (voice recognition is not easy), but maybe you can process the voice before sending BT (on PC/tablet/phone/...) and then the BT would transfer only simple commands and it would be no problem at all.

If there is something I missed, you may write more, where you see the main problem.