body:
I am interested in calculating the amp/hour output of a solar panel using an Arduino. I am confident I can get the voltage (with a voltage divider) & the amperage (with an ACS712). My question is about the math of calculating Amp*hour.

**Here is my plan:**

 1. My plan is to pull the voltage and amperage every second.
 2. I would then add this amp*second value to a variable. I would also increment another variable for each second.
 3. I would then be able to get an average or total of Amp*seconds from these 2 variables. I could also divide the amp*second by 3600 if I wanted Amp*Hour.

**Is it too much a stretch to poll the amperage every second and call it amp/second? How can I make this more accurate?**

title: Calculating Amp/Hrs of a solar panel

Answers: 3

body:
You want a device called a "coulomb counter". Such a device measures the total current  that flows through it.

I've seen some for Arduino. I believe SparkFun sells one. From a quick search it looks like theirs might be too low voltage for a large solar panel though.

body:
## How to make your own coulomb counter (Amp\*hours [Ahr] meter, or Watts\*hours [Whr] energy meter) with an Arduino

## Quick summary:

Jump straight down to the "Full coulomb counter example in code" section if you just want the final answer.

## Details

There are a lot of misunderstandings here, but here is the gist of it.

What you want to do is a perfect application of an Arduino. No need to buy a coulomb counter, instead, you should **make one** with your Arduino.

> I would then add this amp/second value to a variable.

First correction, it's an **amp\*second**, NOT an amp/second. You are multiplying amps by the number of seconds that current value existed.

amp\*seconds / 3600 = amp\*hours. Read about that here: https://en.wikipedia.org/wiki/Ampere_hour. Multiply that by the _voltage_ over that same time period and you've got amps\*hours\*volts = (amps\*volts)\*hours = Watts\*hours = units of *energy*! Remember, your house electricity it purchased in units of kilowatt hours, which is kilowatts\*hours, or kWhr. And in engineering units a [**joule**](https://en.wikipedia.org/wiki/Joule) is  the standard unit of energy, and it is simply Watts\*seconds. So, you can convert kWhr to joules like this, where units are in square brackets `[]`.

    Joules = kWhr * 1000 [Whr/kWhr] * 3600 [sec/hr] = [Watts*sec] = [Joules]

So, 1 kWhr x 1000 x 3600 = 3600000 Joules = 3600kJ

> I would also increment another variable for each second.

That doesn't make any sense. Don't do that. You've already captured the seconds by adding your new bit of amps\*seconds to your old sum of it.

DO account for voltage too! What you're really after is *energy*, which can be expressed in units of joules or kWhr, as already described above.

> Is it too much a stretch to **poll** the amperage every second and call it **amp\*second**?

(my corrections in bold)

No, absolutely not! That's *exactly* what an amp\*second is! It's the current, amps, times the number of seconds that current existed. That's a coulomb counter!

### A. Making the coulomb counter as good as possible

> How can I make this more accurate?

This is the part where the engineer and programmer (you) determines the quality of the result.

1. Don't assume 1 second elapsed because you *told it to*. *Measure it* for each and every measurement!
1. The smaller the time interval, the more accurate, since it allows you to capture the small current fluctuations, so use a *smaller time slice* than 1 second. I'd start with 10ms.
1. Measure voltage AND current AND actual time elapsed on this loop as close to the same time as possible.
1. Do NOT use blocking techniques, such as `delay()` or `delayMicroseconds()`.
1. What you're doing when you're multiplying a new amp reading x seconds, and adding it to the previous sum is called [*numerical integration*][1]. You're simply numerically integrating, or summing, the area under the Amp (y-axis)-time (x-axis) curve, or, if you're doing what I'm saying to do intead: the Watt (y-axis)-time (x-axis) curve, where the area under the curve is the total energy collected. **Don't do rectangular integration, do *trapezoidal* integration following the *trapezoidal rule*! It's more accurate!**
1. Calibrate your clock! An Arduino's clock can be off by a couple percent. Figure out how much it's off by comparing its clock output over, say, 10 minutes, and comparing it to a better clock source, say...an internet time server displaying the atomic clock in Colorado or wherever it is. Then, multiply each measurement by a scaling factor to fix it!
1. On the same lines as above, ideally you'd also compensate in real-time for temperature, as the clock frequency drifts with temperature.
1. Calibrate the voltage measurement.
1. Calibrate the current measurement.

### B. Extra: when is trapezoidal integration most beneficial?

You might call the following list my **"5 hypotheses about the benefits of trapezoidal integration".**

The merits of trapezoidal integration can be argued, and it's probably not as important as I originally made it sound, but it is *super easy* to implement, so why not!? Also, it is _most important_ when:

1. The time sampling rate is *super low*.
1. The rate of change of readings (ie: their derivative, or slope) is *super high*.
1. The readings consistently have a rising slope (rectangular integration _under_estimates the area in this case) OR a consistently falling slope (rectangular integration _over_estimates in this case).
1. When you care about real-time readings *in this instant*, not just overall trends or averages. This is because trapezoidal integration instantly removes overestimation and underestimation error which can accumulate over short periods but then "de-accumulates", or is negated, over long periods, when the opposite slope occurs in the data.
1. [_This may apply only when there is jitter in the sample rate--see [@Edgar Bonet's comment here](https://arduino.stackexchange.com/questions/75932/calculating-amp-hrs-of-a-solar-panel/75937#comment166387_75937)_] When the readings consistently rise at a different rate than they fall, as this results in asymmetric accumulation of error. This means that the rectangular integration error accumulated by the values rising distance `delta_y` will NOT be fully negated by error in the opposite direction when the values fall distance `delta_y`. Therefore, even over long periods, rather than seeing the error negated, it will accumulate more and more over time. [Note: I'd need to analytically/numerically play with this hypothesis for a while to prove it conclusively to myself, but I'm pretty sure it is correct].

## Full coulomb counter example in code:

This code is now in my [eRCaGuy_hello_world](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world) repo here: [coulomb_counter_with_cooperative_multitasking_macro.ino](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/arduino/coulomb_counter_with_cooperative_multitasking_macro/coulomb_counter_with_cooperative_multitasking_macro.ino).

Here's a full coulomb counter example in code. You just need to implement a few functions to read samples and do calibrations is all.

I'm borrowing the timestamp-based cooperative multitasking part of this code from [my answer about cooperative multitasking here][2], so go check it out for more information on that.

As written, this code compiles, but I haven't wired anything up or tested it. Here's the compilation output:
> Sketch uses 3750 bytes (12%) of program storage space. Maximum is 30720 bytes.
> Global variables use 262 bytes (12%) of dynamic memory, leaving 1786 bytes for local variables. Maximum is 2048 bytes.

**[coulomb_counter_with_cooperative_multitasking_macro.ino](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/arduino/coulomb_counter_with_cooperative_multitasking_macro/coulomb_counter_with_cooperative_multitasking_macro.ino):**

Jump to the bottom for the `setup()` and `loop()` functions. They are both really short.

```cpp
/// Coulomb counter example
/// By Gabriel Staples
/// See: https://arduino.stackexchange.com/questions/75932/calculating-amp-hrs-of-a-solar-panel/75937#75937

/// @brief      A function-like macro to get a certain set of events to run at a desired, fixed
///             interval period or frequency.
/// @details    This is a timestamp-based time polling technique frequently used in bare-metal
///             programming as a basic means of achieving cooperative multi-tasking. Note
///             that getting the timing details right is difficult, hence one reason this macro
///             is so useful. The other reason is that this maro significantly reduces the number of
///             lines of code you need to write to introduce a new timestamp-based cooperative
///             task. The technique used herein achieves a perfect desired period (or freq)
///             on average, as it centers the jitter inherent in any polling technique around
///             the desired time delta set-point, rather than always lagging as many other
///             approaches do.
///
///             USAGE EX:
///             ```
///             // Create a task timer to run at 500 Hz (every 2000 us, or 2 ms; 1/0.002 sec = 500 Hz)
///             const uint32_t PERIOD_US = 2000; // 2000 us pd --> 500 Hz freq
///             bool time_to_run;
///             uint32_t actual_period_us;
///             CREATE_TASK_TIMER(PERIOD_US, time_to_run, actual_period_us);
///             if (time_to_run)
///             {
///                 run_task_2();
///
///                 // OR, if `run_task_2()` needs the actual period that just occurred, for
///                 // whatever reason, you may pass it in to your `run_task_2()` function:
///                 run_task_2(actual_period_us);
///
///                 // OR, just do all your code right here instead of in `run_task_2()`
///             }
///             ```
///
///             Source: Gabriel Staples
///             https://stackoverflow.com/questions/50028821/best-way-to-read-from-a-sensors-that-doesnt-have-interrupt-pin-and-require-some/50032992#50032992
/// @param[in]  period_desired_us  (uint32_t) The desired delta time period, in microseconds;
///                             note: pd = 1/freq; the type must be `uint32_t`.
/// @param[out] time_to_run     (bool) A `bool` whose scope will enter *into* the brace-based scope block
///                             below; used as an *output* flag to the caller: this variable will
///                             be set to true if it is time to run your code, according to the
///                             timestamps, and will be set to false otherwise.
/// @param[out] actual_period_us  (uint32_t) The actual period, in us, since the last time it was
///                             time to run--ie: since the last time `time_to_run` was set to true.
/// @return     NA--this is not a true function
#define CREATE_TASK_TIMER(period_desired_us, time_to_run, actual_period_us)                                            \
{ /* Use scoping braces to allow multiple calls of this macro all in one outer scope while */                          \
  /* allowing each variable created below to be treated as unique to its own scope */                                  \
    time_to_run = false;                                                                                \
                                                                                \
    /* set the desired run pd / freq */                                                                                \
    const uint32_t PERIOD_DESIRED_US = period_desired_us;                                                              \
    static uint32_t t_start_us = micros();                                                                             \
    uint32_t t_now_us = micros();                                                                                \
    uint32_t period_us = t_now_us - t_start_us;                                                                        \
    actual_period_us = period_us;                                                                                \
                                                                                \
    /* See if it's time to run this Task */                                                                            \
    if (period_us >= PERIOD_DESIRED_US)                                                                                \
    {                                                                                \
        /* 1. Add PERIOD_DESIRED_US to t_start_us rather than setting t_start_us to t_now_us (which many */            \
        /* people do) in order to ***avoid introducing artificial jitter into the timing!*** */                        \
        t_start_us += PERIOD_DESIRED_US;                                                                               \
        /* 2. Handle edge case where it's already time to run again because just completing one of the main */         \
        /* "scheduler" loops in the main() function takes longer than PERIOD_DESIRED_US; in other words, here */       \
        /* we are seeing that t_start_us is lagging too far behind (more than one PERIOD_DESIRED_US time width */      \
        /* from t_now_us), so we are "fast-forwarding" t_start_us up to the point where it is exactly */               \
        /* 1 PERIOD_DESIRED_US time width back now, thereby causing this task to instantly run again the */            \
        /* next time it is called (trying as hard as we can to run at the specified frequency) while */                \
        /* at the same time protecting t_start_us from lagging farther and farther behind, as that would */            \
        /* eventually cause buggy and incorrect behavior when the (unsigned) timestamps start to roll over */          \
        /* back to zero. */                                                                                \
        period_us = t_now_us - t_start_us; /* calculate new time delta with newly-updated t_start_us */                \
        if (period_us >= PERIOD_DESIRED_US)                                                                            \
        {                                                                                \
            t_start_us = t_now_us - PERIOD_DESIRED_US;                                                                 \
        }                                                                                \
                                                                                \
        time_to_run = true;                                                                                \
    }                                                                                \
}

// Convert microseconds to seconds
#define US_TO_SEC(us) ((us)/1000000UL)
// Convert Joules to KWh (Kilowatt*hours)
#define JOULES_TO_KWHRS(joules) ((joules)/3600/1000)

/// @brief      Obtain a corrected time measurement from a raw time measurement.
/// @details    Assuming you have done experiments to determine your microcontroller (mcu)
///             clock's error, you can correct for it with this function. Pass in a time
///             measurement the mcu has timed directly, and get back a corrected value.
/// @param[in]  raw_sec     A raw time measurement, in seconds
/// @return     A corrected time measurement, in seconds
float do_time_correction(float raw_sec)
{
    // You determine the correct calibration constant. Perhaps it is 0.9813, or perhaps it is
    // 1.19.... You will need to determine this for each individual mcu.
    constexpr float TIME_CORRECTION_CONST = 1.0; // default: 1.0
    float corrected_sec = raw_sec*TIME_CORRECTION_CONST;
    return corrected_sec;
}

/// @brief      Obtain a new instantaneous (at this moment) current reading, in Amps
/// @param      None
/// @return     Current, in Amps
float get_current()
{
    // you implement this
}

/// @brief      Obtain a new instantaneous (at this moment) voltage reading, in Volts
/// @param      None
/// @return     Voltage, in Volts
float get_voltage()
{
    // you implement this
}

/// @brief      Run the coulomb counter task to sum the total energy received from the solar panels
/// @param[out] total_energy_joules_p  (optional) A pointer to a float to receive back the total
///                         energy value acquired, in Joules (Watts*sec). Pass in `nullptr` to not
///                         receive back this value. Note that the previously-cached value is
///                         passed out in the event it's not time to calculate a new value.
///                         The return value of this function will indicate whether a new value
///                         or cached value is passed out here.
/// @param[in]  reset_sum   (optional) pass in true to reset the internally-stored "total energy
///                         acquired" value during this call (prior to performing the latest
///                         power_watts_avg calculation, if it is time for that).
/// @return     true if a new total_energy_joules value was just calculated and passed back via the
///             pointer above, or false if an old, cached value was passed out instead since it
///             wasn't time to obtain and calculate a new value.
bool run_coulomb_counter(float* total_energy_joules_p = nullptr, bool reset_sum = false)
{
    // Set this task to run at 100 Hz
    constexpr uint32_t PERIOD_DESIRED_US = 10000; // 10000us = 10ms, or 100Hz run freq

    static float total_energy_joules = 0;

    if (reset_sum)
    {
        total_energy_joules = 0;
    }

    bool time_to_run = false;
    uint32_t actual_period_us;
    CREATE_TASK_TIMER(PERIOD_DESIRED_US, time_to_run, actual_period_us);
    if (time_to_run)
    {
        // Time to obtain new samples and perform some numerical integration to obtain the total
        // energy received.

        // the previous power calculation, in watts; required for trapezoidal integration
        static float power_watts_old = 0;

        // take new samples, & calculate power from those samples
        float current_amps = get_current();
        float voltage = get_voltage();
        float power_watts = current_amps*voltage;

        float actual_period_sec = US_TO_SEC((float)actual_period_us);
        actual_period_sec = do_time_correction(actual_period_sec);

        // Perform trapezoidal integration to obtain the "area under the curve", which is equal to
        // the energy in joules. Imagine a plot where the y-axis is power and the x-axis is time. If
        // you split the x-axis up into segments of width PERIOD_DESIRED_US, then the trapezoidal
        // area under the curve, within each of those time segments, is equal to time_delta x
        // (power_old + power)/2. This is the energy (Joules) obtained during that time period.
        float power_watts_avg = (power_watts + power_watts_old)/2;
        power_watts_old = power_watts; // prepare for next iteration
        float energy_joules = actual_period_sec*power_watts_avg;

        total_energy_joules += energy_joules;
    }

    if (total_energy_joules_p != nullptr)
    {
        // output this value back to the user
        *total_energy_joules_p = total_energy_joules;
    }

    return time_to_run;
}

void setup()
{
    // do whatever you need to here
    Serial.begin(115200);
}

void loop()
{
    // Energy, in Joules, or Watt*seconds. To convert to Watt*hours, simply divide by 3600 [sec/hr]
    float total_energy_joules;
    bool new_measurements_made = run_coulomb_counter(&total_energy_joules);

    // Let's do an event-based print where we print the latest total_energy_joules value at a rate
    // of 2 Hz, which is typical for digital displays showing information expected to be read by
    // us slow humans. Since the run_coulomb_counter() task is running at 100 Hz, that means we
    // need to print the latest value every 50 runs.
    if (new_measurements_made)
    {
        static uint16_t run_count = 0;
        run_count++;
        if (run_count % 50 == 0)
        {
            float total_energy_kwh = JOULES_TO_KWHRS(total_energy_joules);
            Serial.print("total energy received (J) = ");
            Serial.print(total_energy_joules);
            Serial.print("; (kWh) = ");
            Serial.println(total_energy_kwh);
        }
    }
}
```

## References:
1. My own answer about generic, timestamp-based cooperative multitasking: [Stack Overflow: How to do high-resolution, timestamp-based, non-blocking, single-threaded cooperative multi-tasking](https://stackoverflow.com/a/50032992/4561887)

## See also:
1. [my answer] [Numerical derivation and integration in code for physics, robotics, gaming, and controls](https://stackoverflow.com/a/72162992/4561887)

  [1]: https://en.wikipedia.org/wiki/Numerical_integration
  [2]: https://stackoverflow.com/questions/50028821/best-way-to-read-from-a-sensors-that-doesnt-have-interrupt-pin-and-require-some/50032992#50032992

body:
There are a number of good choices for a sampling device. Some like the INA2221 can do simultaneous I & V at a higher sample rate sampling and accumulate or average the results to produce a low rate data stream better suited to a processor with limited resources without sacrificing anything.

If the idea is to test the output of a solar panel the terminal voltage isn't entirely irrelevant. Panels aren't always maximally illuminated.

If this concept is tied to battery charging I think there's a dimension missing from the concept guiding the approach - the charge acceptance of a storage cell is not a constant. The implicit use for this is to monitor the battery state of charge in order to either disconnect the charger entirely or change to charge balancing and or float modes.

Simply relying on Amp-hours_out = constant * Amp-Hours_in would need to set the constant at the maximum value to avoid trying to drive current at a high rate into fully charged cells. That charger relies on a long low rate charge completion and balancing phase to avoid gradually walking the state of charge down to a fractional charge with maximum acceptance. The available hours of sunlight tend to limit the time available for charge balancing, and the battery's available capacity is set by the cell with the lowest state of charge, so the idea is to get as close to 100% as possible on the cell with the highest state of charge before the charge rate has to drop to avoid damaging cells.

The details are battery technology dependent, but if the idea is to know the state of charge of a battery, then a more complex formula for charge acceptance may produce a more satisfying result.


body:
Does the Bluetooth module HC-06 contains a built in antenna similar to HC-05 ?

and if so, then what is the benefit from using antenna?

title: antenna of the HC-06 bluetooth module

Answers: 0


body:
I am trying to make an **infinity gauntlet**. So it's obvious it should have a ***snap*** feature(which will switch of a light,motor or whatever). But I don't know how to go about sense this snap. I thought of two ideas: one detecting the snap sound but since I will be wearing a glove it can't be heard loudly, second is, trying to detect the pressure between thumb and middle finger and calculating velocity of middle finger during the snap. And I even found EMG sensor can be used but it's too costly so suggest me best way possible with proper explanation

P.S: This is my first ever Arduino project

title: Detecting a finger snap(basically trying to replicate infinity gauntlet)

Answers: 0


body:
I will like to understand how does Arduino measure a frequency. Also how does my voltmeter can measure a frequency as well. Since I am a beginner on using microcontroler I would read a frequency like this:

    void loop()
    {
        while(digitalRead(myPin)==HIGH)
        {
           // pin is high
        }
        // measure time using millis (this is the time the pin was high)

        while(digitalRead(myPin)==LOW)
        {
           // pin is low
        }
        // measure time using millis (this is the time the pin was low)

    }

**With this code it makes sense to me how to measure a frequency and a duty cycle. The problem with this code is that it will probably be very slow and I it will probably read frequencies up to 100Hz and less.**

So my questions are:

1. How can arduino read frequencies higher than 100Hz? How does it achieve that?

2. I Googled arduino's frequency and it shows to be 16MHz. That means arudino can read frequencies up to 16Mhz? Ethernet cables specifically CAT5 has a frequency of 100MHz. That means that it sends signals 100,000,000 in one second! How could Arduino send that many signals in one second if I where to buy a Ethernet shield such as [this one][1]?

  [1]: https://www.amazon.com/SunFounder-Ethernet-Shield-W5100-Arduino/dp/B00HG82V1A/ref=sr_1_1_sspa?crid=351KLIK08PC15&dchild=1&keywords=arduino ethernet shield&qid=1590619332&sprefix=arudino ethernet ,aps,216&sr=8-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyVlBHMDNORDE4UkRZJmVuY3J5cHRlZElkPUEwODUyNjg3UjlBRTBTWlY5OVRBJmVuY3J5cHRlZEFkSWQ9QTA1MjUzMTYzMklHSkZNTFdVQktHJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==

title: How can arduino read a frequency higher than 16Mhz?

Answers: 2

body:
> How can arduino read frequencies higher than 100Hz? How does it achieve that?

Interrupts (if you want to do it in software) or a magical piece of hardware called the Input Compare peripheral that is built into most MCUs.

> I Googled arduino's frequency and it shows to be 16MHz. That means arudino can read frequencies up to 16Mhz?

No, that is the speed the CPU operates at. The maximum frequency signal it can read is usually below that (for SPI it's half that, 8MHz, for example).

> Ethernet cables specifically CAT5 has a frequency of 100MHz. That means that it sends signals 100,000,000 in one second! How could Arduino send that many signals in one second if I where to buy a Ethernet shield such as this one?

It doesn't. The shield does. The Arduino just tells the shield what to do, and the chip on the shield does it.

body:
I would not use `millis()` to measure the period of a signal unless my
program had to deal with extremely low frequencies. And by extremely low
I mean below 1 mHz (one millihertz). For frequencies above
1 mHz, the pseudo-code you show would work just as well or better
using `micros()`.

As the frequency goes up, you will start to look at more fancy options
for measuring it. You could for example count the rising edges from an
interrupt and measure the duration of many (not just one) periods with
`micros()`. This should work up to a few hundred kHz. For faster
frequencies you can use a hardware timer configured as a counter, and
measure the time it takes to overflow. This should be good for
frequencies up to almost half the CPU frequency (8 MHz).

And for the Ethernet signals, see Majenko's answer.


body:
I'm trying to use Atom as an IDE for arduino and arduino-based boards.
I'm using arduino-cli for compilation and avrdude for upload, and now I'm trying to use linter-gcc for linting.

g++ is running and the linter seems to be working ok, but it's can't find built in libs.  I've added:

    "C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\*"

to my GCC include paths, I've also tried copying the lib sources to my working directory, but I'm still getting (e.g.):

    SPI.h: No such file or directory

Any ideas why gcc isn't seeing SPI.h?

title: Trying to show g++ (linter-gcc for Atom) where to find Arduino libs

Answers: 0


body:
I am having some issue writing to flash memory on Arduino Uno.

I burned the optiboot bootloader that ships with the IDE 1.8.3 to the chip, then uploaded the [test_dospm sketch](https://github.com/Optiboot/optiboot/blob/master/optiboot/examples/test_dospm) to write content to flash memory but appears to reset the device instead.

Any idea why this might be happening?

title: Writing to flash memory fails with Optiboot

Answers: 1

body:
The bootloader which ships with Arduino IDE is version 4 which was already in the Uno from factory. To use the do_spm function you need [Optiboot 8][1] <s>build with this support enabled. It is not enabled in the default builds, because it doesn't fit in the usual Optiboot size for Uno</s>.

The hex file of the bootloader is [here][2]. Simply replace the hex file in AVR boards package with this one.

  [1]: https://github.com/Optiboot/optiboot
  [2]: https://github.com/Optiboot/optiboot/blob/master/optiboot/bootloaders/optiboot/optiboot_atmega328.hex


body:
I am using an EA DOGM132-5 graphic display, they also have provided a library for Arduino, so everything is nice and easy. The library has a function for easily passing a string to the LCD.

    void dog_7565R::string(byte column, byte page, const byte *font_adress, const char *str)
    {
 unsigned int pos_array;           //Postion of character data in memory array
 byte x, y, column_cnt, width_max;        //temporary column and page adress, couloumn_cnt tand width_max are used to stay inside display area
 byte start_code, last_code, width, page_height, bytes_p_char; //font information, needed for calculation
 const char *string;

 start_code   = pgm_read_byte(&font_adress[2]);  //get first defined character
 last_code  = pgm_read_byte(&font_adress[3]);  //get last defined character
 width   = pgm_read_byte(&font_adress[4]);  //width in pixel of one char
 page_height  = pgm_read_byte(&font_adress[6]);  //page count per char
 bytes_p_char = pgm_read_byte(&font_adress[7]);  //bytes per char

    if(type != DOGM132 && page_height + page > 8) //stay inside display area
      page_height = 8 - page;
      else  if(type == DOGM132 && page_height + page > 4)
        page_height = 4 - page;

 //The string is displayed character after character. If the font has more then one page,
 //the top page is printed first, then the next page and so on
 for(y = 0; y < page_height; y++)
 {
  position(column, page+y); //set startpositon and page
  column_cnt = column; //store column for display last column check
  string = str;             //temporary pointer to the beginning of the string to print
  digitalWrite(p_a0, HIGH);
  digitalWrite(p_cs, LOW);
  while(*string != 0)
  {
   if((byte)*string < start_code || (byte)*string > last_code) //make sure data is valid
    string++;
   else
   {
    //calculate positon of ascii character in font array
    //bytes for header + (ascii - startcode) * bytes per char)
    pos_array = 8 + (unsigned int)(*string++ - start_code) * bytes_p_char;
    pos_array += y*width; //get the dot pattern for the part of the char to print

        if(type != DOGM132 && column_cnt + width > 128) //stay inside display area
     width_max = 128-column_cnt;
        else if(type == DOGM132 && column_cnt + width > 132)
           width_max = 132-column_cnt;
    else
     width_max = width;

    for(x=0; x < width_max; x++) //print the whole string
    {
     spi_out(pgm_read_byte(&font_adress[pos_array+x]));
     //spi_out(pgm_read_byte(&font_adress[pos_array+x])); //double width font (bold)
    }
   }
  }
  digitalWrite(p_cs, HIGH);
 }
    }
So I just use the function in the sketch with the variables I want and I can easily show a string, but I want to show a changing value for example a temperature reading Tc.

    int ThermistorPin = 0;
    int Vo;
    float R1 = 10000;
    float logR2, R2, T, Tc, Tf;
    float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

    Vo = analogRead(ThermistorPin);
    R2 = R1 * (1023.0 / (float)Vo - 1.0);
    logR2 = log(R2);
    T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
    Tc = T - 273.15;

But the string function doesn't support variables. Can someone help me to adjust the string function to take variables or perhaps suggest a better way altogether?

title: How to pass a changing value to a graphic display using Arduino?

Answers: 2

body:
You have to first convert the floating point value to a string, then pass the resulting string to the `dog_7565R::string()` function.

It looks like the standard `sprintf()` provided by Arduino does not support the `%f` format for floats, so you may have to find another way to convert it or write your own conversion function.

body:
You didn't mentioned how you convert the floating point value `Tc` to  a string before passing it to `dog_7565R::string`, but if you are using `sprintf()`, by default Arduino has the `sprintf()` support for floating point turn off, there is a way to turn it on if you are using Platform.io IDE, but it will not work for Arduino IDE.

One workaround is to use the `dtostrf()` function available in the avr-libc that is accessible in Arduino:

    dtostrf(floatvar, StringLengthIncDecimalPoint, numVarsAfterDecimal, charbuf);

The `dtostrf()` converts a float to a c string.

    float Tc = T - 273.15;
    char floatString[6];
    dtostrf(Tc, 4, 2, floatString);

This will turn a value like `32.15` into a string `"32.15"`.


body:
I am using [i2cdev library][1]

Code:(i did not know this code is correct or not)

    #include <Arduino.h>
    #include <MPU6050.h>
    #include <kalman.h>
    #include <stdint.h>

    #define ACCELLSB  2048
    #define GYROLSB   16.4

    #define CONSOLE
    #define CALIBRATE

    #ifdef  CALIBRATE
    int16_t Accel_X_offset;
    int16_t Accel_Y_offset;
    int16_t Accel_Z_offset;

    int16_t Gyro_X_offset;
    int16_t Gyro_Y_offset;
    int16_t Gyro_Z_offset;
    #endif

    MPU6050 mpu6050;

    Kalman  AngleX;
    Kalman  AngleY;

    void setup()
    {
       mpu6050.initialize();
       mpu6050.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);
       mpu6050.setFullScaleGyroRange(MPU6050_GYRO_FS_2000);

       #ifdef CALIBRATE
       mpu6050.CalibrateAccel();
       mpu6050.CalibrateGyro();

       Accel_X_offset = mpu6050.getXAccelOffset();
       Accel_Y_offset = mpu6050.getYAccelOffset();
       Accel_Z_offset = mpu6050.getZAccelOffset();

       Gyro_X_offset  = mpu6050.getXGyroOffset();
       Gyro_Y_offset  = mpu6050.getYGyroOffset();
       Gyro_Z_offset  = mpu6050.getZGyroOffset();
       #endif

       int16_t AccelX, AccelY, AccelZ;
       int16_t GyroX, GyroY, GyroZ;

       mpu6050.getMotion6(&AccelX,&AccelY,&AccelZ,&GyroX,&GyroY,&GyroZ);

       // I am going to use this values in kalman filter
       #ifdef CALIBRATE
       AccelX -= Accel_X_offset;
       AccelY -= Accel_Y_offset;
       AccelZ -= Accel_Z_offset;

       GyroX  -= Gyro_X_offset;
       GyroY  -= Gyro_Y_offset;
       GyroZ  -= Gyro_Z_offset;
       #endif
    }

    void loop()
    {

    }

What is the correct way to calibrate mpu6050(Correct me what i am wrong or this is correct)?

Thanks.

  [1]: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

title: How to calibrate Mpu6050 using library?

Answers: 1

body:
I personally suggest you `MPU6050_tockn` library.[https://github.com/tockn/MPU6050_tockn][1]

If you use `calcGyroOffsets()` in `setup()`, it will calculate calibration of the gyroscope, and the value of the gyroscope will calibrated.

    #include <MPU6050_tockn>
    #include <Wire.h>

    MPU6050 mpu6050(Wire);

    void setup(){
      Wire.begin();
      mpu6050.begin();
      mpu6050.calcGyroOffsets();
    }

If you use `calcGyroOffsets(true)` in `setup()`, you can see state of calculating calibration in serial monitor.

    #include <MPU6050_tockn>
    #include <Wire.h>

    MPU6050 mpu6050(Wire);

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

Serial monitor:

    Calculate gyro offsets
    DO NOT MOVE MPU6050.....
    Done!
    X : 1.45
    Y : 1.23
    Z : -1.32
    Program will start after 3 seconds

If you know offsets of gyroscope, you can set them by `setGyroOffsets()`, and you don't have to execute `calcGyroOffsets()`, so you can launch program quickly.

    #include <MPU6050_tockn>
    #include <Wire.h>

    MPU6050 mpu6050(Wire);

    void setup(){
      Serial.begin(9600);
      Wire.begin();
      mpu6050.begin();
      mpu6050.setGyroOffsets(1.45, 1.23, -1.32);
    }

But if want to do it with Kalman filter goto [https://github.com/jarzebski/Arduino-KalmanFilter/blob/master/KalmanFilter_MPU6050/KalmanFilter_MPU6050.ino][2] It will guide you.

  [1]: https://github.com/tockn/MPU6050_tockn
  [2]: https://github.com/jarzebski/Arduino-KalmanFilter/blob/master/KalmanFilter_MPU6050/KalmanFilter_MPU6050.ino


body:
I am trying to control the speed of motor through VFD using 4-20mA signal.

I generate the 4-20mA signal using Arduino.I use low pas filter to obtain the voltages from Arduino PWM pins as shown in the circuit.

Their is continuous deviation at the output.But the deviation is very small.

Example:
when Input is 1V(from 20% PWM in Arduino Code)--> Then output continuous to vary between 3mA to 4mA.

when Input is 5V(from 100% PWM in Arduino Code)--> Then output continuous to vary  between 19mA to 20mA

Can I implement this circuit practically with VFD?

Will this deviation create problem for VFD to control the speed?

Will this very fast continuous deviation is dangerous for

title: Vary the Speed of Motor

Answers: 1

body:
The sawtooth pattern you're showing looks like what I would expect from incomplete filtering of the PWM signal from the Arduino.

I don't know if the variation is going to affect your motor controller or not.

I suggest using a different low pass filter with a much lower pass frequency. That will slow down the response to changes in speed slightly, but produce smoother output. I'd suggest lowering the pass frequency of your filter by 10X or more.

(The good news is that you want to filter the hell out of your PWM signal. You want it to only pass like 10Hz or so. Using a very low cut-off frequency for your filter will get rid of that sawtooth. The result of that would be an output voltage that would be slower to respond, but that should be fine. If your motor takes 1/10th of a second to adjust speeds, is that a problem in your application?)


body:
I developed an android app to control a robot using nodemcu. I have added some buttons to on/off or blink some LEDs. It works fine but, if I on the one LED or drive the robot, the other LEDs goes off. What I want is the LEDs should be off only if I press the off button for that respective LED.

My code for nodemcu -

    #define RIGHT_MOTOR_1  15       // L298N in1 motors Right           GPIO15(D8)
    #define RIGHT_MOTOR_2  13       // L298N in2 motors Right           GPIO13(D7)
    #define LEFT_MOTOR_1   2        // L298N in3 motors Left            GPIO2(D4)
    #define LEFT_MOTOR_2   0        // L298N in4 motors Left            GPIO0(D3)

    #define FRONT_LED    16        //Front LED        GPIO14(D0)
    #define REAR_LED_1   5         //Rear LED        GPIO12(D1)
    #define REAR_LED_2   4         //Rear LED        GPIO12(D2)

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

    String command;

    const char* ssid = "NodeMCU";
    const char* password = "10101010";

    ESP8266WebServer server(80);

    void setup() {

      pinMode(RIGHT_MOTOR_1, OUTPUT);
      pinMode(RIGHT_MOTOR_2, OUTPUT);
      pinMode(LEFT_MOTOR_1, OUTPUT);
      pinMode(LEFT_MOTOR_2, OUTPUT);
      pinMode(FRONT_LED, OUTPUT);
      pinMode(REAR_LED_1, OUTPUT);
      pinMode(REAR_LED_2, OUTPUT);

      Serial.begin(74880);

      // Connecting WiFi
      WiFi.mode(WIFI_AP);
      WiFi.softAP(ssid, password);

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

      // Starting WEB-server
      server.on ( "/", HTTP_handleRoot );
      server.onNotFound ( HTTP_handleRoot );
      server.begin();
    }

    //LED Logic
    void frontLEDon(){
      digitalWrite(FRONT_LED, HIGH);
    }

    void frontLEDoff(){
      digitalWrite(FRONT_LED, LOW);
    }

    void frontLEDblink(){
        digitalWrite(FRONT_LED, HIGH);
        delay(500);
        digitalWrite(FRONT_LED, LOW);
        delay(500);
    }

    void rearLEDon(){
      digitalWrite(REAR_LED_1, HIGH);
      digitalWrite(REAR_LED_2, HIGH);
    }

    void rearLEDoff(){
      digitalWrite(REAR_LED_1, LOW);
      digitalWrite(REAR_LED_2, LOW);
    }

    void rearLEDblink(){
        digitalWrite(REAR_LED_1, HIGH);
        delay(50);
        digitalWrite(REAR_LED_1, LOW);
        delay(50);
        digitalWrite(REAR_LED_1, HIGH);
        delay(50);
        digitalWrite(REAR_LED_1, LOW);
        delay(50);
        digitalWrite(REAR_LED_2, HIGH);
        delay(50);
        digitalWrite(REAR_LED_2, LOW);
        delay(50);
        digitalWrite(REAR_LED_2, HIGH);
        delay(50);
        digitalWrite(REAR_LED_2, LOW);
        delay(50);
    }

    void forward(){
      digitalWrite(RIGHT_MOTOR_1, LOW);
      digitalWrite(RIGHT_MOTOR_2, HIGH);
      digitalWrite(LEFT_MOTOR_1, LOW);
      digitalWrite(LEFT_MOTOR_2, HIGH);
    }

    void backward(){
      digitalWrite(RIGHT_MOTOR_1, HIGH);
      digitalWrite(RIGHT_MOTOR_2, LOW);
      digitalWrite(LEFT_MOTOR_1, HIGH);
      digitalWrite(LEFT_MOTOR_2, LOW);
    }

    void right(){
      digitalWrite(RIGHT_MOTOR_1, HIGH);
      digitalWrite(RIGHT_MOTOR_2, LOW);
      digitalWrite(LEFT_MOTOR_1, LOW);
      digitalWrite(LEFT_MOTOR_2, HIGH);
    }

    void left(){
      digitalWrite(RIGHT_MOTOR_1, LOW);
      digitalWrite(RIGHT_MOTOR_2, HIGH);
      digitalWrite(LEFT_MOTOR_1, HIGH);
      digitalWrite(LEFT_MOTOR_2, LOW);
    }

    void robotStop(){
      digitalWrite(RIGHT_MOTOR_1, LOW);
      digitalWrite(RIGHT_MOTOR_2, LOW);
      digitalWrite(LEFT_MOTOR_1, LOW);
      digitalWrite(LEFT_MOTOR_2, LOW);
    }

    void loop(){
          server.handleClient();
          command = server.arg("State");

          if(command == "Forward"){
            forward();
            frontLEDon();
          }
          if(command == "Backward"){
            backward();
            rearLEDon();
          }
          if(command == "Left"){
            left();
          }
          if(command == "Right"){
            right();
          }
          if(command == "Stop"){
            robotStop();
          }
          if(command == "FrontLEDon"){
            frontLEDon();
          }
          if(command == "FrontLEDblink"){
            frontLEDblink();
          }
          if(command == "FrontLEDoff"){
            frontLEDoff();
          }
          if(command == "RearLEDon"){
            rearLEDon();
          }
          if(command == "RearLEDblink"){
            rearLEDblink();
          }
          if(command == "RearLEDoff"){
            rearLEDoff();
          }
    }

    void HTTP_handleRoot(void) {
      if( server.hasArg("State") ){
           Serial.println(server.arg("State"));
      }
      server.send ( 200, "text/html", "" );
      delay(1);
    }

title: LED goes off in nodemcu If I turn on other LED

Answers: 0


body:
i want to send data from my sensor to database phpmyadmin. but i only get zero values. please help me thank you.
```
void loop()
{
  pox.update();
  BPM = pox.getHeartRate();
  SpO2 = pox.getSpO2();
 // Sending_To_phpmyadmindatabase(BPM);

  if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
    Serial.print("BPM: ");
    Serial.println(BPM);
    Serial.print("SpO2: ");
    Serial.print(SpO2);
    Serial.println("%");
    Serial.println("*********************************");
    Serial.println();
    tsLastReport = millis();
    delay(0);
    }
    Sending_To_phpmyadmindatabase(BPM);
}

void Sending_To_phpmyadmindatabase(float BPM){
  if (client.connect(server_addr,80)) {
    Serial.println("connected");
    Serial.print("GET /pulse.php?BPM=12");
    client.print("GET /pulse.php?pox.getHeartRate="+String(BPM,1));
    Serial.println("pox.getHeartRate!");
    client.println("pulse=");
    client.println(BPM);
   // Serial.print("GET /vsmonitor/connect.php?SpO2=12");
   // client.print("GET /vsmonitor/connect.php?SpO2="+String(SpO2,1));
   // Serial.println("SpO2!");
    //client.println("o2_sat=");
    //client.println(SpO2);
    client.print(" ");
    client.println(" HTTP/1.1");
    client.println("Host: 192.168.15.4");
    client.println(server_addr);
    client.println("Connection: close");
    client.println();
  }
  else {
    Serial.println("--> connection failed\n");
  }
  Serial.println();
  delay(5000);
}
```

title: How can i send data to phpmyadmin database? using esp8266 nodemcu and max30100

Answers: 0


body:
i'm using arduino ide 1.8.12 opened preferences window and did enter

http://arduino.esp8266.com/stable/package_esp8266com_index.json, https://arduino.esp8266.com/stable/package_esp8266com_index.json

(all comma separated) into the Additional Board Manager URLs field. then i opened the boardmanager (Strg+Shift+I) and enter 'esp' in the search field. BUT I CAN'T FIND "esp8266 by ESP8266 Community". it's not listed. WHAT CAN I DO NOW ?

additive : is there a way to include a locally available json file in the arduino as a library?
the file
    package_esp8266com_index.json
is in the directory
    C: \ Users \ [user] \ AppData \ Local \ Arduino15

thanks in advance

title: cannot find esp8266 via boardmanager

Answers: 0


body:
I've built 2 motor drivers for a robotics project and need to set positions that I want the motors to move to, and read that using the arduino. The arduino then uses a rotary encoder to implement a closed loop PID controller and move the motor the set point. My code wasn't working so I started troubleshooting and found out that my setpoint was getting reset to 0 automatically!

The only thin that changes the setpoint was the serial read so I made a smaller sketch for troubleshooting which is this:

    volatile long setpoint;

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

    void loop() {
      if (Serial.available()){
        setpoint = Serial.parseInt();
        Serial.print("Set to: ");
        Serial.println(setpoint);
      }
    }

The result was quite odd, it sets the value correctly but resets back to 0 without me sending any new commands!

I tried updating the IDE to 1.8.12, tried old and new arduinos (with old and new bootloader) but all had the same result. Here is a demo video showing the weird reset to 0 problem:

https://streamable.com/kfgv61

I tried changing the buadrate higher or lower but that also didn't fix anything. Any ideas on what I'm doing wrong?

title: Issues with reading numbers from serial port

Answers: 1

body:
The problem here is that `Serial.parseInt()` stops when it sees the
newline, but _it does not consume that newline_, which is left in the
input buffer. Thus, at the next loop iteration, `Serial.available()`
returns true because of this newline and, unless you send another value
fast enough, `Serial.parseInt()` times out and returns zero.

The easy fix is to consume that newline yourself:

```c++
void loop() {
  if (Serial.available()){
    setpoint = Serial.parseInt();
    if (Serial.peek() == '\n') Serial.read();  // consume LF
    Serial.print("Set to: ");
    Serial.println(setpoint);
  }
}
```

I personally would not use `Serial.parseInt()` at all, and would [buffer
the data myself][read-serial] until I see the `'\n'`. This way there are
no surprises with timeouts being read as zero.

[read-serial]: https://majenko.co.uk/blog/reading-serial-arduino


body:
I am playing with this basic example:

[Arduino: Button][1]

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

There're a lot of existing questions about why to connect button to the ground. I get the idea more or less. Is done to avoid "noise" during reading the input value.

However, what I don't understand is why to use resistor instead of a wire? If I remove resistor and put the wire instead the example stops working. Could someone explain me this?

  [1]: https://www.arduino.cc/en/tutorial/button
  [2]: https://i.stack.imgur.com/ZMGFm.png

title: Button example: resistor vs wire

Answers: 0


body:
I have previously asked this question:

https://arduino.stackexchange.com/questions/75798/custom-build-of-arduino-on-a-pcb

And thanks to the answer by [Majenco][1] I have learned that my circuit works a lot better when adding a capacitor. For example I am using the [NRF24L01][2] and it is much more stable when using a capacitor. I am placing the capacitor for now next to the power supply like this:

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

Right now I am running this on a breadboard. The Atmega328 chip is very cheap compared to the arduino uno board; therefore, I will like to continue building my projects based on the a[tmega328P-PU chip][4].

Anyways before printing the PCB based on the Atmega328P-PU chip, where should I place the capacitors in order to reduce the most noise? **The capacitors are very cheap and making one good design will enable me for all my future designs to be based from this one.**

From researching on the internet I see a lot of different examples. Everyone uses different capacitance sizes. For example I have found this:

[![enter image description here][5]][5]
I got that from this link: https://www.autodesk.com/products/eagle/blog/what-are-decoupling-capacitors/

On other places they say to place the capacitance closest to the pins such as from [this video][6]. **If that is true should I just place one capacitor on pins 7 and 8. Lastly the other capacitor on pins 20 and 22?**

I do not mind soldering extra pins knowing my circuit will have the best performance.

  [1]: https://arduino.stackexchange.com/users/4143/majenko
  [2]: https://www.sparkfun.com/datasheets/RF/nRF2401rev1_1.pdf
  [3]: https://i.stack.imgur.com/hsKLr.png
  [4]: https://lcsc.com/product-detail/ATMEL-AVR_ATMEL_ATMEGA328P-PU_ATMEGA328P-PU_C33901.html
  [5]: https://i.stack.imgur.com/65yxO.png
  [6]: https://www.youtube.com/watch?v=KKjHZpNMeik&t=401s

title: Placing decoupling capacitors when building an Arduino PCB with Atmega328-PU

Answers: 1

body:
The Autodesk link explains it very well.

You should place small/fast decoupling capacitors (0.1uF) close to the power pins of your on-board ICs to deal with local spikes in power consumption of those devices.

Place a larger/slower decoupling capacitor (1uF or larger, depending on many factors such as distance of the power supply from the board and expected power consumption) somewhere on the board to deal with varying loads and ripples in your power supply.

This has been common practice at least since I’ve started with electronics about 40 years ago (and probably much longer).


body:
I am connecting this shift register to my ESP8266-01 for more GPIO options.

It appears there is a GPIO 16, but it's tied to a RESET pin.

I checked both datasheets, the [ESP8266 datasheet][1], and I also checked the [datasheet for the shift register][2] for more information on what kinds of pins can be hooked to each of the input pins.

I am also thinking whether it's viable to connect one of the other available pins of the ESP8266 and use it for this connection with the shift register (either RX or TX).

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

My understanding is that I need to connect three pins of the ESP8266 directly to the shift register for its latch, clock, and serial pin.

I am also wondering if I can connect the serial pin of the ESP8266 to the serial pin of the shift register?

  [1]: http://www.microchip.ua/wireless/esp01.pdf
  [2]: https://www.sparkfun.com/datasheets/IC/SN74HC595.pdf
  [3]: https://i.stack.imgur.com/nJs9W.png

title: How can I connect an ESP8266-01 to a shift register?

Answers: 1

body:
You have several options. Your drawing shows a 74HC595 which is a serial in parallel output. You need a minimum of two pins to operate it, one for clock and another for data. Adding a third for reset will make it much easier to use. You can use any GPIO pins you like but be cognisant of any other uses those pins may be performing in your system such as boot etc.

The part also has SPI, this will directly interface to the shift register. You can cascade them to as many deep as you want. The SPI operates concurrently input and output at the same time. You actually have to send something to get something, that is what cycles the clock. There technically is no limit to the number of devices but there are practical limitations. Since the data transfer is only one way on a pin you can easily buffer it. This generally is one of the fastest I/O you can get.

The second which only requires is I2C which is a synchronous buss that directly addresses the peripheral devices. Originally it had 7 address bits giving you 127 seperate devices you can access. Each device can have as many individual locations/registers as it needs but normally only one address. A lot of chips have this built in and have a preassigned address or address range. For example there are FRAM chips that are 32K x 8 bits at a single address.

There are a lot more options available but I mentioned these because modules that implement these functions are inexpensive and readily available. You can look up "SPI" and "I2" to get a lot more information. Good luck and enjoy your project.


body:
I am running my arduino project with the atmega328 chip like this:

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

I have purchased by mistake [this crystal][2]:

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

The reason why I purchased by mistake that crystal was because it has this description:

> 16MHz ±10ppm 22pF 60Ω SMD-3225 SMD Crystal Resonators RoHS

I thought that it contained the 22pF ceramic capacitors inside. But latter I learned that I still the 22pf ceramic capacitors. (Please correct me if I am wrong)

**Anyways how can I use that crystal?** I only know how to connect the 2 pin crystal. Since this crystal has 4 pins now I am confused.

To me it makes sense to connect it like this:

1. Connect pins 9 and 10 from atmega --TO--> pins 1 and 3 from the crystal.
2. Connect pins 2 and 4 from crystal --TO--> Ground
3. Connect the 22pf ceramic capacitors to pins 1 and 3 from crystal and ground like in the first diagram.

  [1]: https://i.stack.imgur.com/2UcoK.png
  [2]: https://lcsc.com/product-detail/SMD-Crystal-Resonators_XTY-7325-1600A2210-00_C389842.html
  [3]: https://i.stack.imgur.com/fcrxe.png

title: How do I use a SMD crystal with 4 pins?

Answers: 1

body:
this is a nice question. Once for a project I stumbled upon this problem too.

The way you described the connection should work perfectly fine.

> To me it makes sense to connect it like this:
Connect pins 9 and 10 from atmega --TO--> pins 1 and 3 from the crystal.
Connect pins 2 and 4 from crystal --TO--> Ground
Connect the 22pf ceramic capacitors to pins 1 and 3 from crystal and ground like in the first diagram.

Keep it going and greetings from Switzerland.


body:
I am working on an ARDUINO based wireless network. In this network, each node or device is having its own GPS module. Each GPS module has to get location data and have to send to a single base-station. Let say we have 10 nodes in our network. A specific time(let say 1 sec) is assigned to each node when it can receive location and send it to the base-station (everything to be done in that 1 sec allocated time). So, all nodes will be done sending the data to the station and now the 2nd cycle repeats and so on.

For experiment purpose, I have created two nodes and connected LEDs each one. I am getting time from GPS module using tinygps library. To verify the time synchronization, I have programmed MCU in such a way that it turns ON the LED for 50 ms after every 10 sec. Uploaded the same code on both devices.
If both devices are sync then LEDs will TURN ON and OFF at the same time. But that's is not the case. LEDs of both devices are turning ON and OFF with a huge difference of time (almost 4 to 5 sec). Which shows that GPS times are not synchronized.
Following is the code:

    #include <TinyGPS++.h>
    #include <SoftwareSerial.h>
    /*
       This sample code demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
       It requires the use of SoftwareSerial, and assumes that you have a
       4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
    */
    static const int RXPin = 4, TXPin = 3;
    static const uint32_t GPSBaud = 9600;

    // The TinyGPS++ object
    TinyGPSPlus gps;

    // The serial connection to the GPS device
    SoftwareSerial ss(RXPin, TXPin);

    const int LEDPIN = 13;
    void setup()
    {
      Serial.begin(9600);
      ss.begin(GPSBaud);

      Serial.println(F("FullExample.ino"));
      Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
      Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
      Serial.println(F("by Mikal Hart"));
      Serial.println();
      Serial.println(F("Sats HDOP  Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum"));
      Serial.println(F("           (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail"));
      Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));

      pinMode(LEDPIN,OUTPUT);
      digitalWrite(LEDPIN,LOW);
    }

    unsigned double interval = 50;
    bool pinState = LOW;
    unsigned double startmillis;
    void loop()
    {
      static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

      printDateTime(gps.date, gps.time);
      double sec = gps.time.second();

        while(1){

          if(millis()-startmillis >= interval){
                // 50 milli seconds passed
                digitalWrite(LEDPIN,LOW);
                Serial.println("50 millis passed.");
                smartDelay(1000);
              }
              else{
                 // Still in loop. Turn ON LED
                 digitalWrite(LEDPIN,HIGH);
              }

              }

      smartDelay(0);

      if (millis() > 5000 && gps.charsProcessed() < 10)
        Serial.println(F("No GPS data received: check wiring"));
    }

    // This custom version of delay() ensures that the gps object
    // is being "fed".
    static void smartDelay(unsigned long ms)
    {
      unsigned long start = millis();
      do
      {
        while (ss.available())
          gps.encode(ss.read());
      } while (millis() - start < ms);
    }

    static void printFloat(float val, bool valid, int len, int prec)
    {
      if (!valid)
      {
        while (len-- > 1)
          Serial.print('*');
        Serial.print(' ');
      }
      else
      {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i)
          Serial.print(' ');
      }
      smartDelay(0);
    }

    static void printInt(unsigned long val, bool valid, int len)
    {
      char sz[32] = "*****************";
      if (valid)
        sprintf(sz, "%ld", val);
      sz[len] = 0;
      for (int i=strlen(sz); i<len; ++i)
        sz[i] = ' ';
      if (len > 0)
        sz[len-1] = ' ';
      Serial.print(sz);
      smartDelay(0);
    }

    static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
    {
      if (!d.isValid())
      {
        Serial.print(F("********** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "d/d/d ", d.month(), d.day(), d.year());
        Serial.print(sz);
      }

      if (!t.isValid())
      {
        Serial.print(F("******** "));
      }
      else
      {
        char sz[32];
        sprintf(sz, "d:d:d ", t.hour(), t.minute(), t.second());
        Serial.print(sz);
      }

      printInt(d.age(), d.isValid(), 5);
      smartDelay(0);
    }

    static void printStr(const char *str, int len)
    {
      int slen = strlen(str);
      for (int i=0; i<len; ++i)
        Serial.print(i<slen ? str[i] : ' ');
      smartDelay(0);
    }

After a bit research, I found the following paper which is very helpful to solve my problem:

> [https://www.frontiersin.org/articles/10.3389/fbuil.2018.00082/full][1]

The problem is, they have not provided the code anywhere which I can use for my problem.
Please let me know what should I do to synchronize the GPS time for two devices and then, in the long run, for a network.

  [1]: https://www.frontiersin.org/articles/10.3389/fbuil.2018.00082/full

title: Time synchronization of GPS based Wireless Network

Answers: 0


body:
I am having an issue with the LCD1602A and Arduino Uno. I have followed a tutorial on youtube that has got the device working, however the LCD is only displaying white blocks in all 16 segments of the top row.

[![Failure Image][2]][2]

Pin Out

LCD

 - VSS -> GND on Breadboard
 - VDD ->  5V on Breadboard
 - V0  -> Connected to 5K potentiometer
 - RS  -> Pin 1 on Arduino Uno
 - RW  -> GND on Breadboard
 - E   -> Pin 2 on Arduino Uno
 - D0  -> Not Connected
 - D1  -> Not Connected
 - D2  -> Not Connected
 - D3  -> Not Connected
 - D4  -> Pin 7 on Arduino
 - D5  -> Pin 6 on Arduino
 - D6  -> Pin 5 on Arduino
 - D7  -> Pin 4 on Arduino
 - A   ->  5V on Breadboard
 - K   -> GND on Breadboard

Code

~~~c
#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
void setup() {
 lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display }
}
void loop() {
 lcd.print("Arduino"); // Prints "Arduino" on the LCD
 delay(3000); // 3 seconds delay
 lcd.setCursor(2,1); // Sets the location at which subsequent text written to the LCD will be displayed
 lcd.print("12345");
 delay(3000);
 lcd.clear(); // Clears the display
 lcd.blink(); //Displays the blinking LCD cursor
 delay(4000);
 lcd.setCursor(7,1);
 delay(3000);
 lcd.noBlink(); // Turns off the blinking LCD cursor
 lcd.cursor(); // Displays an underscore (line) at the position to which the next character will be written
 delay(4000);
 lcd.noCursor(); // Hides the LCD cursor
 lcd.clear(); // Clears the LCD screen
}
~~~

Now the program compiles and uploads OK the potentiometer dims the blocks perfectly fine.

However it is supposed to print Arduino and 12345 and I am unsure why.

What am I missing?

Thanks

  [2]: https://i.stack.imgur.com/Atv2y.png

title: LCD1602A displaying blocks

Answers: 0


body:
I'm EXTREMELY new to Arduino and fairly new to programming as a whole, but I thought it would be fun to try and write a program that draws arbitrary 1-bit bitmaps to an LED matrix using the Adafruit RGBMatrixPanel library. I'm trying to draw this image to the screen:

[![a 32x16 red-and-black image of text reading HEY! in a serif font][1]][1]

But it conks out after 16 pixels each row...

[![the same image, but with only the HE visible - the rest of the image is black][2]][2]

Below is my code in full. It seems like the bit mask only works for the first 16 columns, but I can't seem to figure out why it stops at that point. I'm using an Arduino Nano, if that helps.
```#include <RGBmatrixPanel.h>
#define CLK  8
#define OE   9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2

RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
unsigned long int pixelGrid[] = {
  0x00000000,
  0x31CEFDCE,
  0x78CCFCCC,
  0x78CC84CC,
  0x78CC04CC,
  0x78CC04CC,
  0x78CC24CC,
  0x78783CFC,
  0x783024FC,
  0x303004CC,
  0x303004CC,
  0x303004CC,
  0x003084CC,
  0x3030FCCC,
  0x3078FDCE,
  0x00000000
};
unsigned long int bitMask = 0x00000001;
void setup() {
  matrix.begin();
  uint8_t r=0, g=0, b=0;

  for(uint8_t y=0; y<16; y++) {
    unsigned long data = pixelGrid[y]; // select row of bits from image
      for (byte x = 0; x <32; x++) { //iterate through columns
        if (data & (bitMask << x)) {// works!
          r = 1; // set LED to ON
        }
        else {
          r = 0; // LED is OFF
        }
      matrix.drawPixel(x, y, matrix.Color333(r, g, b));
    }
  }
}

void loop() {
}
```
Here's the part of the code that's probably messing up, isolated:
```
for (byte x = 0; x <32; x++) {
        if (data & (1 << x)) {
          r = 1;
        }
        else {
          r = 0;
        }
```
Thanks for your help!

Edit: Changing the `data` variable from `int` to `long` to avoid it being truncated lead adds another column of pixels, but it kind of looks like they're all squished into column 16 for some reason:[![same image as image 2, except there is a vertical line running from (16, 1) to (16, 14)][3]][3]

Note: I tried drawing a rectangle from (0,0) to (31, 15) to make sure that all the LEDs worked, and I was able to do that.

Edit 2: Instead of the bitmask being `1`, I made it so that:
```
unsigned long int bitMask = 0x00000001;
// ...
 if (data & (bitMask << x)) { // works!
          r = 1; // set LED to ON
        }
        else {
          r = 0; // LED is OFF
        }
```
I'm guessing regular numbers default to 16-bit unsigned ints.
The issue is fixed, woo! I edited the big code block to match.
  [1]: https://i.stack.imgur.com/sf2Vy.png
  [2]: https://i.stack.imgur.com/wZ24i.png
  [3]: https://i.stack.imgur.com/Km4lw.png

title: Trying to draw a bitmap to an LED matrix only draws the left half

Answers: 1

body:
'pixelGrid[]' are longs but your temp inside the for() loop, 'data', is an int. Thus, it gets only half the data. Easy mistake to make (and they can be so hard to spot when you know perfectly well what you meant... :)

Update:

> By switching the int to long, I've successfully unlocked a seventeenth
> column! Unfortunately, it looks like all the pixels are bunched up in
> that seventeenth column.

Another error of the same kind (I missed it the first time around):
Change `(1 << x)` to `(1L << x)`. The original expression is calculated as int and the result is widened in the assignment to 'data' (and I think there was compiler bug int the code that did that, besides). The corrected expression is calculated as a long in the first place, which is what I think you intended.

Update 2:

From your question Edit 2:

> I'm guessing regular numbers default to 16-bit unsigned ints.

You are correct - ints of unspecified size default to 16-bits in the Arduino gcc compiler used by the Arduino IDE (and just about everywhere else in the Arduino domain that I know of). The language standard leaves the compiler writer free to choose the size of an int that best fits the target-machine's architecture. 16-bits is the most common, but by no means the only - size implemented in most compilers. For this reason, most compilers' pre-processors implement specific-sized data types, and application writers - you & I - are advised to use these wherever data-size matters. For the Arduino's gcc compiler, there are predefined types such as `int8_t` (signed 8-bit int), `uint32_t` (unsigned long int), etc.
`int` is an ok "I don't care, just as long as it works" option. When you do care - specify.

(If my answer helped you, please upvote it or select as best answer. The latter has the important function on this site of marking the question as "completed" so it doesn't keep re-appearing as an unanswered question.)


body:
I'm currently working with some WS2812B LEDs and tried out adding a capacitor to be safe from voltage spikes (was recommended by Adafruit). I noticed that a soon as I connect a capacitor between 5V and ground that the USB is disconnect from the PC (Windows Usb disconnect sound plays). I wondered why and tried another setup. This time just the capacitor between 5V and ground. Nothing else. According to my knownledge this isn't a short (capacitor is intact) and therefor this setup should be valid. Again the same thing happens: USB disconnects...

I really don't know why this happens but want to understand it. The capacitor I use is rated 16V 1000 mF (electrolytic in case this is relevant). The capacitor is also connected the right polarity. What forces the USB to disconnect (and let Windows play the USB disconnect sound). Am I may damaging the USB Port somehow and therefor a disconnect is forced as a security measurement?

Oh yeah... Using an Arduino Uno R3 made by Elegoo.

Hope you can help me out,
Tmirror

title: USB disconnects when using a capacitor

Answers: 1

body:
The USB specifications allow a maximum of 10uF total capacitance on the USB power lines. By putting 1000uF you have given it 100x more than is allowed.

This causes a massive inrush current and the USB host (your computer) sees it as a short circuit, so it shuts off the power in a panic to protect itself.

A capacitor does have a role to play in helping to remove power supply noise caused by power-hungry and noisy devices like WS2812B LEDs, but just slapping it across the power supply pins isn't going to really help.

Instead you should increase the impedance of the power supply to the noisy device(s) and use a capacitor to reduce the impedance again. This will help to preferentially draw current from the capacitor to supply the LEDs while smoothing out the draw from the main supply over time.

A simple circuit is to use a resistor with a capacitor:

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

<!-- End schematic -->

The values I show there for the resistor and capacitor are pretty random. The smaller the resistor the more demand will be put on the power supply. The bigger the resistor the more demand will be put on the capacitor. If the resistor is too big the capacitor won't be able to store enough power to run the LEDs, and too much voltage will be dropped across  it. If the capacitor is too small it won't be able to store enough power to run the LEDs. Tuning those values depends very much on the amount of noise there is and the current draw of the LEDs.

You must also make sure the resistor can handle the amount of power dissipated by the current flowing through it.


body:
I am trying to create a basic snake game using the arduino UNO along with the MAX72XX module, the LCD module and the analog joystick module. I have made my program using object orientated programming. I have no experience with C++ so I have done really well to get this far in my program (This is the only thing left to help me complete the game!). The only problem that is holding me back is that the snake head is always diagonal to the rest of the body. Here are a few examples of what I mean:

[![][1]][1]
[![][2]][2]

  [1]: https://i.stack.imgur.com/gta7H.jpg
  [2]: https://i.stack.imgur.com/xjRUt.jpg

Here is my code if the issue is in here (I have commented what part does what):

    #include "LedControl.h"
    #include <LiquidCrystal.h>
    LedControl lc=LedControl(12,10,11,1);
    LiquidCrystal lcd(8, 13, 3, 5, 6, 7);

    /*lcd->setCursor(0, 1);
      // print the number of seconds since reset:
      lcd->print(millis() / 1000);*/

    class Snake_body//class of each snake body part
    {
      //private:

      public:

        int following_direction;
        int x;
        int y;
        int previous_x;
        int previous_y;
        bool enabled;
        /*Snake_body()
        {
          this->enabled = false;
        }*/
        /*Snake_body(int x_value, int y_value)
        {
          this->enabled = false;
          this->following_direction = 1;
          this->x = x_value;
          this->y = y_value;
          this->previous_y = y_value;
          this->previous_x = x_value;
        }*/
        void configure(int x_value, int y_value)
        {
          //this->enabled = true;
          this->following_direction = 1;
          this->x = x_value;
          this->y = y_value;
          this->previous_y = y_value;
          this->previous_x = x_value;
        }

    };

    class Power_up
    {
      private:

      public:
        virtual void init()
        {
          this->x = 0;
          this->y = 0;
        }

        int x;
        int y;
    };

    Snake_body *snake[64];
    int snakes_length;

    //Snake_body *snake[0];
    Power_up *power_up;

    int score;

    void setup() {

      Serial.begin(9600);

      lcd.begin(16, 2);

      snakes_length = 1;

      for(int z = 1; z < 64; z++)
      {
        snake[z] = NULL;//makes all snake body parts except head NULL
      }

      snake[0] = new Snake_body();//define snake head
      snake[0]->configure(0,0);//set it up
      power_up = new Power_up();//power up to increase in body size
      //Snake_body snake[0] = new Snake_body();
      // put your setup code here, to run once:
      lc.shutdown(0,false);
      /* Set the brightness to a medium values */
      lc.setIntensity(0,8);
      /* and clear the display */
      lc.clearDisplay(0);
      lcd.setCursor(0, 0);
      score = 0;
      lcd.print("score: ");
      lcd.setCursor(6, 0);
      lcd.print(score);
      pinMode(2, INPUT);
      digitalWrite(2, HIGH);
      power_up->x = random(0, 8);
      power_up->y = random(0, 8);
    }

    int snake_direction;

    void loop()
    {
      int x_axis = analogRead(A0);
      int y_axis = analogRead(A1);
      int switcher = digitalRead(2);

       if(x_axis <= 400)//the following 4 directions are for moving the snake
       {
         snake[0]->following_direction = 0;
         //x += 1;
         Serial.println("left");
       }

       else if(x_axis >= 600)
       {
         snake[0]->following_direction = 1;
         //x -= 1;
         Serial.println("right");
       }

       else if(y_axis <= 400)
       {
         snake[0]->following_direction = 2;
         //y -= 1;
         Serial.println("up");
       }

       else if(y_axis >= 600)
       {
         snake[0]->following_direction = 3;
         //y += 1;
         Serial.println("down");
       }

      if(snake[0]->following_direction == 0 && snake[0]->x < 7)//updates the snakes position
      {
        snake[0]->previous_x = snake[0]->x;
        snake[0]->x += 1;
      }

      else if(snake[0]->following_direction == 1 && snake[0]->x > 0)//updates the snakes position
      {
        snake[0]->previous_x = snake[0]->x;
        snake[0]->x -= 1;
      }

      else if(snake[0]->following_direction == 2 && snake[0]->y > 0)//updates the snakes position
      {
        snake[0]->previous_y = snake[0]->y;
        snake[0]->y -= 1;
      }

      else if(snake[0]->following_direction == 3 && snake[0]->y < 7)//updates the snakes position
      {
        snake[0]->previous_y = snake[0]->y;
        snake[0]->y += 1;
      }

      Serial.println("\n");//USED THESE PRINT STATEMENTS TO PRINT VALUES

      Serial.print("previous x: ");
      Serial.print(snake[0]->previous_x);
      Serial.println("");
      Serial.print("previous y: ");
      Serial.print(snake[0]->previous_y);
      Serial.println("");
      Serial.print("direction: ");
      Serial.print(snake[0]->following_direction);
      Serial.println("\n");

      if(snake[0]->x == power_up->x && snake[0]->y == power_up->y)//if the head collides with the power up
      {
        score += 1;
        lcd.setCursor(6,0);
        lcd.print(score);

        power_up->x = random(0, 8);
        power_up->y = random(0, 8);

        for(int j = 0; j < 64; j++)
        {
          if(snake[j] == NULL)//searches for empty snake body
          {

             snake[j] = new Snake_body();//creates new snake body part
             snake[j]->configure(snake[j-1]->previous_x, snake[j-1]->previous_y);//sets up the snake body part

             snake[j]->following_direction = NULL;
             snakes_length += 1;
             break;
          }
        }
      }

      for(int i = 1; i < 64; i++)
      {
        if(snake[i] != NULL)//updates the other body parts appart from the snake head (it was updated before this)
        {
          snake[i]->previous_x = snake[i]->x;
          snake[i]->previous_y = snake[i]->y;
          snake[i]->x = snake[i-1]->previous_x;
          snake[i]->y = snake[i-1]->previous_y;
        }
      }

      lc.setLed(0,power_up->x,power_up->y,true);
      for(int w = 0; w < 64; w++)//drawing body parts onto the screen
      {

        if(snake[w] != NULL)
        {
          lc.setLed(0,snake[w]->x,snake[w]->y,true);
        }
      }

      delay(100);

      lc.clearDisplay(0);
    }

title: Snake head in snake game always diagonal to rest of body

Answers: 0


body:
I am trying to generate LED blink after 4 second using Interrupt  but Interrupt is not triggering not even once .
Request: if you have arduino uno r3 please check at your end and let me know result.
I have read Timer counter section multiple times and applied everything i can for example :-

 - Enabled Global Interrupt
 - Select CTC Mode
 - Enable Interrupt for OCIE0A
 - Prescaling to clk/1024
 - Initializing OCR0A
 - When OCR0A equal TCNT0 ,interrupt will generate

```
int var;
void setup() {
  // put your setup code here, to run once:
    SREG = SREG | (1<<7);          // Gloval interrupt enable
    TCCR0A = TCCR0A | (1<<WGM01); // Clear counter on compare match mode
 OCR0A = 255; // when TCNT equal OCR0 interrupt will generate
 TIMSK0 = TIMSK0 | (1<<OCIE0A); //  Output Compare Match A Interrupt Enable
 TCCR0B = TCCR0B | (1<<CS01) | (1<<CS02);  // Prescaling by 1024
 DDRB = DDRB | (1<<5);
 Serial.begin(9600);      // Testing
 Serial.println("Start");   // Testing
}

void loop() {
  // put your main code here, to run repeatedly:

}

ISR(TIMER0_COMPA_vect){
 var++;
 Serial.print(var); // Testing
 volatile long unsigned i;
 if(var == 246){
  PORTB = PORTB | (1<<5);
  for(i=0; i<30000; i++);
  PORTB = PORTB & ~(1<<5);
  for(i=0; i<30000; i++);
  var=0;
 }
}
```

 - clock is 16 00 00 00 Hz
 - Prescaling by 1024 = 15625
 - 1 Tick = 1/15625 = 0.00 00 64 sec
 - OCR0 is initialized by 255
 - TCNT0 Ticks to 255
 - Total time taken to generate one interrupt = 255 * 0.00 00 64 =
   0.01632 sec that means after every  0.01632 sec Interrupt supposed to generate
 - How many interrupt is required to generate LED after 4 sec =>
   4/0.01632 = 246

Update working code
```
int var;
void setup() {
  // put your setup code here, to run once:
  SREG = SREG | (1<<7);          // Gloval interrupt enable
  TCCR0A =(1<<WGM01); // Clear counter on compare match mode
  OCR0A = 255; // when TCNT equal OCR0 interrupt will generate
  TIMSK0 = (1<<OCIE0A); //  Output Compare Match A Interrupt Enable
  TCCR0B = (1<<CS00) | (1<<CS02);  // Prescaling by 1024

  DDRB = DDRB | (1<<5);

    Serial.begin(9600);      // Initialize the USART
    Serial.println("Start");   // Write the welcome message

}

void loop() {
  // put your main code here, to run repeatedly:

}

ISR(TIMER0_COMPA_vect){
  var++;
 // Serial.print(var);
  volatile long unsigned i;
  if(var == 246){
        PORTB = PORTB | (1<<5);
        for(i=0; i<300000; i++);
        PORTB = PORTB & ~(1<<5);
        var=0;
  }
}
```

title: Arduino Uno CTC mode interrupt is not tiggering

Answers: 1

body:
There are a few issues with your code:

First, you should completely overwrite the timer control registers
rather than changing single bits. For example, when you write

```c++
TCCR0A = TCCR0A | (1<<WGM01); // Clear counter on compare match mode
```

You end up with a timer mode that results from the combination of the
bits that were already set there and the ones you are setting. Judging
from the comment, you assume that this will be CTC mode, but this is not
granted, because the Arduino initialization routine has already set some
bits in this register. Since you are taking the timer for your own
usage, just overwrite all the control registers:

```c++
TCCR0A = (1<<WGM01); // Clear counter on compare match mode
```

and same for `TCCR0B` and `TIMSK0`.

The second problem is that you misread the “Clock Select Bit
Description” table from the datasheet. Your timer is being clocked from
an external clock source on T0 pin. Presumably you have nothing
connected there, so the timer does not increment. You probably meant

```c++
TCCR0B = (1<<CS00) | (1<<CS02);  // Prescaling by 1024
```

A smaller issue is your delay loop. The program would be easier to
understand if you instead use a proper delay function. The Arduino
`delay()` will not work, as you have reconfigured Timer 0, but you can
use `_delay_ms()` from the avr-libc if you `#include <util/delay.h>`.


body:
Instead of using the regular Arduino board I have purchased the [atmega328p-pu][1] along with this components:

1. 22pf ceramic capacitor
2. 10K resistor
3. 16mhz crystal
4. 47uF capacitor
5. 3.3 Volts Power supply

The diagram looks like this:

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

Because the atmega328p chip that I purchased already comes loaded with arduino bootloader I can program this chip right away! [This video][3] explains in more detail how to upload the code to the chip. It is very simple.

**The reason why I run my atmega328p chip with a 3.3V power supply is because of these reasons:**

1. I have multiple sensors like the NRF24L01 that cannot take 5 volts.
2. I run this project of a 3.3 battery as well in order to save power.
3. I do not want to use voltage regulators as they are inefficient and they will waste my battery.
4. Everything works great.

Even though everything works great if I am running atmega328P at 16mhz @ 3.3V I am not following the specifications. **In order to do things correct I will like to run my code at 8mhz so that I am in within the specs**

Question
-------

What is the correct way of running this project at 8mhz? If I change the 16mhz crystal for a 8mhz it runs at 8mhz but everything is half the speed. I have to divide all time related functions by 2. Moreover, I cannot upload new code if it has a 8mhz crystal. In order to upload new code I have to place the 16mhz crystal upload the code and then change the crystal again.

Can I still use my 16mhz crystal and run at 8mhz so that I do not have to keep replacing the crystal? I want my `millis` function and other time dependent functions to have the correct time. I do not want to have to divide everything by 2.

Do I have to burn a different bootloader for this to work? Where can I find a tutorial that can explain me all this?

**There are tutorials on how to use the internal 8mhz crystal from the atmega328 chip but still want to use an external crystal as it is much more accurate**

Edit
----

I just found  [this link][4] that explains how to do it. Edgar Bonet answer seems a lot simpler so I will stick to that.

  [1]: https://www.amazon.com/SparkFun-ATmega328-with-Arduino-Bootloader/dp/B004G51AMW/ref=sr_1_2_sspa?dchild=1&keywords=atmega328p-pu&qid=1590774888&sr=8-2-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExTEowVjk2TFdUQkM4JmVuY3J5cHRlZElkPUEwMDIyNDgzMlFVVzJNNzBVTjlMTyZlbmNyeXB0ZWRBZElkPUEwMDQxOTAzMTdFT0lNWkpRVlYxRyZ3aWRnZXROYW1lPXNwX2F0ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU=
  [2]: https://i.stack.imgur.com/uXj0N.png
  [3]: https://youtu.be/Sww1mek5rHU
  [4]: https://tttapa.github.io/Pages/Arduino/Bootloaders/ATmega328P-custom-frequency.html

title: How to run atmega328p at 8, 4 and 1 mhz?

Answers: 1

body:
If you run your MCU at 8 MHz, everything will run at this frequency: not
only the CPU core but also the timers, including Timer 0 which is used
for `millis()`, `delay()`, etc. So you will have to use a modified
version of the Arduino timing functions in order to cope with this clock
frequency.

Fortunately, such version already exists. Actually, it is even supported
by the standard Arduino core, since it supports the 3.3 V version
of the Arduino Pro Mini, which uses an ATmega328P clocked at 8 MHz.

I thus suggest you install an 8 MHz crystal, burn in the bootloader
for the 3.3 V Pro Mini, and tell your IDE that you are using that
board. In the Tools menu:

 * set board to "Arduino Pro or Pro Mini"
 * set processor to ""ATmega328P (3.3V, 8 MHz)"


body:
I want to know the purpose of using the EEPROM because I can't get it,
I mean I know that it can store values for a long time, but I just can't get the goal here

    #include<EEPROM.h>
    void setup()
    {
      Serial.begin(9600);
      EEPROM.write(0,4);
      int s=EEPROM.read(0);
      int f=10;
      Serial.print(s);
      Serial.print(" ");
      Serial.print(10);
    }

    void loop()  {}

For example, I'm using EEPROM to see the difference if I print a value inside variable `s` to the serial moniter using EEPROM and a normal value inside the variable `f`.
But I couldn't find the difference between both because when unplugging the power and turn it on again, both of them are printed.
Hope you got the idea and I hope to see some feedback.
Thank you..

**the LED program**

then I made this program that will compare the EEPROM value to num.4 and compares the F variable to num.4
known that both F and the EEPROM values are 4.
and then I changed both of the values to 3.
shouldn't the GREEN LED of the EEPROM still on because it has already stored num.4??

    #include<EEPROM.h>
    void setup()
    {
      pinMode(12,OUTPUT);
      pinMode(11,OUTPUT);
    }

    void loop()
    {

      EEPROM.write(0,4);                 //GREEN LED
      int f=4;                           //RED LED

      if(EEPROM.read(0)==4) digitalWrite(12,HIGH);
      if(f==4) digitalWrite(11,HIGH);
    }

title: the use of the Arduino's EEPROM

Answers: 2

body:
In short:
Once you shutdown an Arduino, every variables on it, which have been calculated by the sketch, are lost. That is because they are stored in RAM, which is not able to store things without power. That is not the problem of EEPROM: values stored there will be available on reboot, and won't need to be calculated again.

This can prove useful is your device is allowing a user to store *presets*: so a configuration of the program. If this configuration, which can be for instance variables affecting the program behavior, is stored in RAM, it will be lost on next reboot. On the other hand, a value stored in EEPROM during the first execution (entered by user for instance) will still be available on next reboot, if you took the time to write it (on the first run) and to read it (on the second run). Just like *saving* and then *recalling* a preset.

Beware that EEPROM does not like to be written too many times and wear out, so you should keep that to a minimum (values that really need to be restored on reboot, and cannot be calculated at this time).

body:
"It can store values for a long time" - that's not exactly what an eeprom does, the major property is that the information in the eeprom **persists during power cycles and chip resets**. In contrast, a RAM looses all information when you unpower the chip.

To get a feeling for eeproms, I suggest you follow the below routine:

**1.** Upload this sketch:

    #include "EEPROM.h"

    void setup() {
      EEPROM.write(0,4);
    }

    void loop(){}

**2.** Once this sketch has been executed, upload and run the below sketch (you could even unplug the arduino before this step):

    #include "EEPROM.h"

    void setup() {
      pinMode(12,OUTPUT);
      if(EEPROM.read(0)==4) digitalWrite(12,HIGH);
      EEPROM.write(0,3);
    }

    void loop(){}

**3.** Now, the green led will light up.

**4.** Reset the atmega and now the green led will remain off.

By just using a variable `int f` which is in RAM, you can not "transfer" a value between those sketches/runtimes.


body:
i'm using this serial topology to connect my Act ATmega328p (Arduino) slaves together to a master ESP32.

They are in total 10 ATmega328p slaves and one master:

[![serial topology][1]][1]

With this type of wiring i'm sure that only one slave per time will talk back to master (when requested), now here comes the problem, basically i need dynamic addressing of slaves: they can be many (up to 30) and i need to access in order the slave devices.

In order to solve the "dynamic addressing" problem i'm thinking about that:

The first slaves will be plugged in and will send to the master his default address (i.e.: 0xFF)
The master will check if the address is used and then reply back to the device with the first available address (i.e.: 0x01)
The slave will get back the response from the master and set an internal variable with the new address (maybe it's a good idea to store the variable in a EEPROM like M24C02: enter link description here)
Starting from the next cpu cycle, the master will ask sequentially to all enumerated slaves to (for example) do an analog read using this workflow:

The master will send a message to the serial bus with address 0x01 asking to do an analog read
The respective slave will handle the request, read the analog input and then reply back to the master
I think that this can work, but i've not found any kind of this implementation...maybe i'm totally out of mind?

**New idea and concept**

Guys, what do you think about sequentially power up the circuits and using the same mechanism to assign dynamically the address?

This assumption will avoid me to save the assigned id to the eeprom and some other id software function defined functionalities like address reset, etc...

It can be a good (and dynamic) method to solve the problem, about that, how I can implement this sequential power up?

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

title: Arduino UARTS Auto addressing slaves

Answers: 1

body:
> The first slaves will be plugged in and will send to the master his
> default address

If this happens while the master is talking to one of the other slaves,
you risk a collision.

I suggest a very small variation on your scheme. Each slave has a
default address (0xff). When you turn it on, it doesn't say anything.
The slaves only talk when they are addressed.

Every now and then, the master sends a “ping” message to 0xff. The newly
installed slave responds, then the master gives it a real address, and
goes back to its business of collecting sensor data. If no response is
received for the ping within some specified timeout, the master assumes
there is no unconfigured slave.

Since no slave ever sends unsolicited messages, this should avoid any
kind of collision. You just have to make sure that new slaves are added
at a slow rate: after connecting a slave, you wait for slightly more
than the ping period before connecting another one.


body:
I'm trying to use the RN 42 and Arduino Uno to control a bluetooth mouse. I configured the RN 42 with the commands S~,6 and SH,0220 and R,1 to put the device in HID mouse mode. Is there anything I missed? Below is the sketch I am using to send mouse reports to the bluetooth. The sketch compiles fine, but moving the joystick does not move the cursor. I included a line of code at the end to print on the serial port whatever data is being sent through software serial to the bluetooth. However when I view the serial monitor, I get back a lot of reversed question marks. Anyone know why this is? Thanks in advance.
```#include <SoftwareSerial.h>

const int bluetoothTx = 4;    // TX pin of RN-42, Arduino D2 (configure as RX pin of Ard)
const int bluetoothRx = 3;    // RX pin of RN-42, Arduino D3 (configure as TX pin)
const int button = 5;
const int xAxis = A0;         // joystick X axis
const int yAxis = A1;         // joystick Y axis
int range = 12;               // output range of X or Y movement
int responseDelay = 5;        // response delay of the mouse, in ms
int threshold = range / 4;    // resting threshold
int center = range / 2;       // resting position value

SoftwareSerial BT(bluetoothTx, bluetoothRx); // args SoftwareSerial(RXpin, TXpin)

void mouseCommand(byte buttons, byte x, byte y) {
  BT.write((byte)0xFD);
  BT.write((byte)0x05);
  BT.write((byte)0x02);
  BT.write((byte)buttons);
  BT.write((byte)x);
  BT.write((byte)y);
  BT.write((byte)0x00);
}

int readAxis(int thisAxis) {
  // read the analog input:
  int reading = analogRead(thisAxis);

  // map the reading from the analog input range to the output range:
  reading = map(reading, 0, 1023, 0, 12);

  /* threshold prevents the mouse from reading small unintentional movements.
  If the output reading is outside from the rest position threshold, use it: */
  int distance = reading - center;

  if (abs(distance) < threshold) {
    distance = 0;
  }

  // return the scaled distance for this axis:
  return distance;
}

void setup() {
  pinMode(button, INPUT);
  pinMode(bluetoothTx, INPUT); // bluetoothTX is equivalent to arduino RX pin
  pinMode(bluetoothRx, OUTPUT);
  Serial.begin(115200);  // Begin the serial monitor at 115200bps
  BT.begin(115200);  // RN-42 defaults to 115200bps
}

void loop() {
  // read and scale the two axes:
  int xReading = readAxis(xAxis);
  int yReading = readAxis(yAxis);
  int buttonState = digitalRead(button);

  // move the mouse:
  mouseCommand(buttonState, xReading, yReading);
  delay(responseDelay);

  if(BT.available())  // If there's data being sent to the bluetooth module
  {
    // Send any characters the bluetooth receives to the serial monitor
    Serial.print((char)BT.read());
  }
}

title: Debugging RN 42 HID Mouse

Answers: 1

body: The problem with getting no response from the mouse was that the bluetooth did not auto reconnect to the computer after powering down. I solved this by sending the command SM,6 for auto reconnect and then R,1 to reboot.


body:
I'am using a Wemos D1 mini V3.0.0 (esp 8266 core).

I tried to save a structure in EEPROM memory but all data are lost when i reboot the board.

I am using these basics functions :
```
int cle_verif = 519; //verification key

struct sauvegarde_data {
  int cle; //verification key
  int mode_ecl; //var
  int r; //var
  int v; //var
  int b; //var
};
sauvegarde_data customVar;

void sauvegardeEEPROM() {
  EEPROM.put(0, customVar);
  EEPROM.commit();
}

void chargeEEPROM() {
  // Lit la mémoire EEPROM
  EEPROM.get(0, customVar);
  Serial.println("");
  Serial.println("cle : "+String(customVar.cle));
  Serial.println("mode eclairage : "+String(customVar.mode_ecl));
  Serial.println("r : "+String(customVar.r));
  Serial.println("v : "+String(customVar.v));
  Serial.println("b : "+String(customVar.b));
  if(customVar.cle != cle_verif){ // check if the key is correct
    initialiserEEPROM();
  }
}

void initialiserEEPROM(){
  // Valeurs par défaut
  customVar.cle=cle_verif;
  customVar.mode_ecl=0;
  customVar.r=15;
  customVar.v=15;
  customVar.b=15;
  sauvegardeEEPROM();
}
```
and then, i ran the following code to initialize the EEPROM memory with default values :
```
EEPROM.begin(128);
initialiserEEPROM(); // initialisation
customVar.b=2; // change cached var value
chargeEEPROM(); // read EEPROM memory
```
the output is customVar.b=15 which is correct and it means it has been saved in EEPROM.

Any idea ?

Have a great day.

PS: i use four libraries which are FastLed, EEPROM, ESP8266WiFi, ESP8266WebServer.
My goal is to save the LEDs color for a more pertinent reboot.

title: EEPROM not consistent over reboot

Answers: 1

body:
It turns out i'm just really stupid. I spent something like 7 hours to make things work but i just selected the wrong card during the whole time.

Sorry for bothering you guys :-/


body:
I am facing a strange issue. I am trying to blink an external LED using **Wemos D1 mini V2 board**. But it is not working. My sketch is as below.

    int LED = D3;
    void setup()
    {
      pinMode(LED, OUTPUT);
    }
    void loop() {
      digitalWrite(LED, LOW);   // LED off
      delay(1000);              // Wait 1 second
      digitalWrite(LED, HIGH);  // LED on
      delay(1000);              // Wait 1 second
    }

The same problem happens on D0, D3, and D4 pins. I am getting 0 volts constantly on pin D0 and 3.3v constantly on pins D3 and D4.

However, The same sketch works for the D7 pin.

Does anyone know how to fix this?

title: Blink doesn't work on pin D3,D4 and D0 but works on D7

Answers: 0


body:
At the moment I try to make a library which uses `attachInterrupt(?,?,RISING)` to read a sensor. The article of Nick Gammon on [Calling an ISR from a class][1] helped me a lot, but his "Glue routines" get pretty ugly with more than 30 potential Interrupt Pins on the ESP32, which all need their own `static void`. Has anyone got a more elegant idea how to do this "Gluing"?

  [1]: https://gammon.com.au/forum/?id=12983

title: Use ISRs inside a library more elegantly

Answers: 1

body:
As a matter of efficiency, I would favor chrisl’s advise to use the
platform's low-level interrupts if at all possible. This, however, comes
at the cost of portability: you would need an implementation specialized
for each platform you want to support. If you don't want to or cannot
maintain all this platform-specific code, `attachInterrupt()` may be a
reasonable option.

Then, you will absolutely need all those glue routines: since the
interrupt system calls your handlers with no parameters, you will not be
able to share handlers between interrupts, and you end up with as many
handlers as interrupts you are going to use.

There is, however, an elegant way of creating all these specialized
functions without writing them explicitly: you can ask the compiler to
write them for you on the basis of a _template_ you provide.

Below is a version of Nick Gammon's example code modified to use a
_template class_. Note that you do not necessarily need a class to use
templates: you could use _template functions_ as interrupt handlers if
that is appropriate for your use case.

```c++
template <uint8_t pin>
class myClass
{
    static volatile bool switchChanged;

public:
    static void begin()
    {
        pinMode(pin, INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(pin),
                        switchPressed, FALLING);
    }

    static void switchPressed()
    {
        switchChanged = true;
    }
};

template <uint8_t pin>
volatile bool myClass<pin>::switchChanged;

myClass<2> foo;
myClass<3> bar;

void setup()
{
    foo.begin();
    bar.begin();
}

void loop(){}
```

Note also that `myClass<2>` and `myClass<3>` are two different classes:
you actually have a different class for each pin. This means that
`foo::switchChanged` and `bar::switchChanged` are two different class
members even though both are `static`. Since you should (in principle)
have at most one instance of each pin-specific class, you can make
everything within the class `static`.

The main caveat of this method is that the pin numbers have now to be
compile-time constants. The great advantage is that you will have a
class created for each interrupt that is actually _used_: no need for an
array of 32 instances on an ESP32 if only a handful of interrupt pins
are going to be actually used.