message:
Homodyne detection for arduino

In your code https://gist.github.com/edgar-bonet/0b03735d70366bc05fc6 for homodyne detection, is there a way to make the frequency detected a range of frequencies? For example detecting between 3kHz and 4kHz?
Thanks in advance!

body:
It may be possible to modify that program in order to get such a large
frequency range:

 * change the local oscillator frequency to 3.5 kHz
 * drastically shorten the filter's time constant in order to get a
   wider passband

However, the homodyne detection scheme is best suited for building very
narrow band filters. In your case, the upper limit you want is quite
close to the Nyquist frequency (4,808 Hz), so I suggest you use a
high-pass, rather than a band-pass filter. The simplest high-pass you
can get is a numerical derivative:

y[n] = x[n] − x[n−1]

The gain of this filter is 2×sin(π×f/fsamp), so you get the
−3 dB cutoff at fsamp/4 ≈ 2,404 Hz. If you need
something better, you may want to try a higher order filter. But then
you get deep into the territory of digital filter design, which can be
tricky, especially if you have no experience with the z-transform or you
want to implement the filter in fixed point.

**Edit**: If you really want a bandpass, the simplest I can think of is
this two-pole filter:

y[n] = 0.360 x[n] − 0.885 y[n−1] − 0.552 y[n−2]

It will give you a maximum gain of roughly 1 at about
3.43 kHz, and −3 dB cutoffs at 3 and 4 kHz. A
straightforward floating point implementation would be:

```c++
float filter(float x)
{
    static float y1, y2;
    float y = 0.360 * x - 0.885 * y1 - 0.552 * y2;
    y2 = y1;
    y1 = y;
    return y;
}
```

You should convert this to fixed point if you want to use it, otherwise
I doubt your Arduino will have the processing power to run every sample
through it. Below is a plot of this filter's gain, compared with the
simple derivative, which I divided by 2 in order to normalize its
gain:

[![gain vs frequency][1]][1]

Note that the gain gets flat as you approach the Nyquist frequency, and
stays relatively high (above −5.4 dB).

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


sender: user

message:
Is volatile qualifier needed if shared variable cannot be changed externally during complete function call?

Consider the following example:

    int i { 0 };

    void incInt() {
        ++i;
    }

    int readInt() {
        return i;
    }

    setup() {
        Serial.begin(9600);
        attachInterrupt(digitalPinToInterrupt(D1), incInt, CHANGE);
    }

    loop() {
        noInterrupts();
        int currI = readInt();
        interrupts();

        Serial.println(currI);
    }

By wrapping the call to `readInt()` with `noInterrupts()` and `interrupts()` it is ensured that `i` cannot be changed externally during the execution of `readInt()`. `i` also cannot be changed externally during the execution of `incInt()`, as long as it is only called as ISR (interrupt service routine). Do I still need to declare `i` as `volatile`?

Does the situation change if `i` is accessed directly in the main loop:

    loop() {
        noInterrupts();
        int currI = i;
        interrupts();

        Serial.println(currI);
    }

In other words: What is the context in which the compiler expects a variable to not be changed externally if it is not declared `volatile`?

sender: assistant

body:
Declaring a variable as `volatile` tells the compiler, that it always has to read the real variable and that it cannot use a cached value. Also the compiler cannot optimize this variable, since it is unknown, when the variable will change. For this it is irrelevant, how you actually read the variable in the main sketch, it only matters, that it get's read. Also this has nothing directly to do with doing the read atomically (with `noInterrupts()`) (though you only garantee correct values, when doing it)

So yes, you need to declare it volatile, or the compiler might think, that the value doesn't change and optimize it out in some way.

> What is the context in which the compiler expects a variable to not be changed externally if it is not declared volatile?

Externally here means outside of the main routine. This covers variables, that get changed in ISRs and also registers, that are changed by hardware (so the register definition in the used core are also `volatile`). The compiler cannot know, when these changes happen, because they are triggered by the hardware, not by the code. It will try to optimize your sketch (which is a rather complex procedure), and might see, that your variable is never changing in the code (the ISR does not get called from the main sketch, thus the compiler does not see it getting called) and will try to optimize it. To ensure, that your sketch works properly, it is your task to tell the compiler, that this variable can change at any time (so that it does not think the other way). You are doing this by declaring it as `volatile`


body:
Let's forget about atomicity for a moment, which is a separate issue, and
assume `i` is an atomic type (maybe `byte` or something equivalent).
Consider the following code:

```c++
void loop()
{
    Serial.println(i);
}
```

Not so long ago I would have expected this to work just fine on Arduino,
as there aren't many ways to compile this function… on its own! However,
since version 1.6.10, [the IDE enables link-time optimization][release].
This means that the compiler (or rather, the optimizer working within
the linker), can see the whole program and notice that `setup()` and
`loop()` are called from only one function which belongs to the Arduino
core:

```c++
int main()  // slightly simplified
{
    init();      // Arduino core initialization
    setup();     // User's initialization
    for (;;)
        loop();  // User's loop
}
```

This makes them perfect candidates for [inlining][]:

```c++
int main()
{
    init();      // will likely be inlined too

    // Inlined setup():
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(D1), incInt, CHANGE);

    for (;;) {
        // Inlined loop():
        Serial.println(i);
    }
}
```

Now it should become clearer that repeatedly reading `i` from memory
looks like a waste of time, which can be optimized-out. The `for` loop then
becomes:

```c++
register uint8_t cached_i = i;  // save `i' in an internal CPU register
for (;;) {
    // Inlined loop():
    Serial.println(cached_i);
}
```

And now the program only prints zeros. That's why you need `volatile` to
prevent that optimization.

[release]: https://blog.arduino.cc/2016/07/27/download-the-new-arduino-ide-1-6-10/
[inlining]: https://en.wikipedia.org/wiki/Inline_expansion


message:
Arduino Uno board not recognized in IDE. Board is not in device manager!

My arduino uno is not recognized by the Arduino IDE. I'm using 1.8.0, The IDE is not showing the COM. The tool section is showing only COM 1, i.e. the hardware.

I opened Device manager, there is no board for UNO.

Help me please.

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

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

  [1]: https://i.stack.imgur.com/i8hOc.png
  [2]: https://i.stack.imgur.com/XRzPJ.png

Arduino Nano works fine.

I have CH340 driver already installed. My computer do not make any "hardware connected sound". I have 3 arduino IDE versions - 1.8.0, 1.8.9, 1.8.10!.

body:
I had a similar problem with my Arduino. My solution is to unplug it, replug it and do what you need to do before the computer can auto-configure it.
I hope it helps! :)
BTW make sure you are choosing the right board.


body: According to https://www.arduino.cc/en/Guide/ArduinoUno, you may need to install a separate driver for the Arduino Uno because it does not have a true USB port. The details are in the link.


message:
Battery solution Nano 33 iOT

Since the Nano 33 boards are quite new right now, I haven't found any details on how to hook one up with batteries.

I'm pretty daft when it comes to electronics (I'm a software man), and I read that the new Nano 33 requires 3.2V, which is a bit of a departure from the 5V the old models supported.

From what I can tell, I might be able to use a single LiFePO4 cell. Am I correct in this assumption? And if so, are there any pitfalls in going this route?

EDIT: I might have misunderstood the difference between operating voltage and input voltage. Does this mean that I can plug any AA battery pack in as a power source?

body:
You can either use the 3.3V pin to supply power to the board, or use the Vin pin.

By using the VIN pin to power goes through a (step down) voltage regulator, that provides a nice stable 3.3V to the board. The regulator in the Nano 33 IoT is the `MPM3610`, which requires an input voltage of at least 4 - 4.5 Volt. Which is more that a LiPo or LiFePo single cell can supply. You could use a multi-cell battery pack. Or a USB power bank. So this solutions is not really ideal.

The other option was to connect the battery directly to the 3.3V pin. The voltage of a LiFePo however changes as it is being discharged. The voltage is around 3.65V when full, and 2.5-2.75V when "empty". The 3.2V rating is called the nominal voltage (kind of an average voltage).
So it's a bit too high when full, and too low when empty. The voltage also isn't regulated, so it can fluctuate a bit, based on the amount of current that's being used.

The maximum voltage for the SAMD21 on this Nano is 3.63V. Maximum voltage for the gyro (LSM6DS3) is 3.6V. The absolute maximum voltage for the radio (NINA-W10) is 3.6V.

So a full LiFePo is slightly too high for the Nano. Though I think you should be fine. But don't try this with a regular LiPo of Lion battery (4.2V when full).


message:
Flash size in boards.txt ATmega 328p 32u4

The ATmega328p and ATmega32u4 microcontroller have 32Kb of flash memory (as datasheet). Bootloader for each microcontroleer has different size (about 512 byte for 328p and 4kb for 32u4).

Why in boards.txt the "upload.maximum_size" parameters is 32256 for 328p and 28672 for 32u4?

I we have to consider bootloader size, the "upload.maximum_size" parameter for 328p must be about 31.5k and not 32k. And, if we do not have to consider bootloader size, as the default boards.txt configuration (above) for 328p, the "upload.maximum_size" parameter for 32u4 must be 32k not 28k. Correct?

Thank you

body:
`1KB` is 1024 bytes, not 1000 bytes.

Therefore 32kb = 32768 bytes.

`32768-512=32256`, which is exactly the value used for upload.maximum_size for the 328p.

4kb=4096 bytes. `32768-4096=28672` which is the value for the 32u4.


message:
Why Wire.write twice?

I'm checking an example for the MPU6050 and got to this part

    Wire.beginTransmission(0x68);           //begin, Send the slave adress (in this case 68)
    Wire.write(0x1B);                       //We want to write to the GYRO_CONFIG register (1B hex)
    Wire.write(0x10);                       //Set the register bits as 00010000 (1000dps full scale)
    Wire.endTransmission(true);             //End the transmission with the gyro

    Serial.begin(9600);                     //Remember to set this same baud rate to the serial monitor
    time = millis();                        //Start counting time in milliseconds

    /*Here we calculate the gyro data error before we start the loop
     * I make the mean of 200 values, that should be enough*/
    if(gyro_error==0)
    {
      for(int i=0; i<200; i++)
      {
        Wire.beginTransmission(0x68);            //begin, Send the slave adress (in this case 68)
        Wire.write(0x43);                        //First adress of the Gyro data
        Wire.endTransmission(false);
        Wire.requestFrom(0x68,4,true);           //We ask for just 4 registers

Why is there two consecutive wire.write() in the begining and only one later? Is it different somehow?

body:
The truth is, the Arduino Wire library sends the data only if `endTransmission` is called. Until then it collects the data in TX buffer. The version of the `write` function used in your snippet adds a byte to the TX buffer.

With I2C usually the first byte written is the address of the register to write. Then the data follow. In case of the first part in your snippet the data are only one byte long.

In the second part, first the register address is sent with `write` and then the data from this register and 3 following registers are requested.


message:
'TCCR1B' was not declared in this scope

I'm trying to use a MS5540C (digital pressure sensor)
and the sample code has this line:

     TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

I'm a bit of a noob to the IoT but its not beyond me to check the SPI.h and see that there is indeed no declaration.

I'm using an **Arduino UNO WiFi Rev 2**.
(Seems like its pins are quit different from an UNO)
I have noted in the comments that Im using pins 32,33,34 instead of 11,12,13

I'm not 100% sure what to ask … other than
Is there a replacement call/function/method that should replace that line? ..or am I missing something else totally. As it stands now...when the program runs its results are inconsistent. I'm just commenting out the faulty line to get it to compile.

**Complete sketch**
source: [Future Electronics][1]

    /*
      MS5540C Miniature Barometer Module
      This program will read your MS5440C or compatible pressure sensor every 5 seconds and show you the calibration words, the calibration factors,
      the raw values and the compensated values of temperature and pressure.
      Once you read out the calibration factors you can define them in the header of any sketch you write for the sensor.

      Uno Pins:
      MS5540 sensor attached to pins 10 - 13:
      MOSI: pin 11
      MISO: pin 12
      SCK: pin 13
      MCLK: pin 9 (or use external clock generator on 32kHz)
      CS is not in use, but might be pin 10

      ==[ addendum start]=============================
      Uno WiFi Rev2 Pins:
      MOSI: pin 32
      MISO: pin 33
      SCK: pin 34
      MCLK: pin 9 (or use external clock generator on 32kHz)
      ==[ addendum end ]=============================

      created 29 February 2012
      by MiGeRA
    */

    /*
      Calibration of my sensor example ...

      Calibration word 1 = 46958
      Calibration word 2 = 65369
      Calibration word 3 = 39392
      Calibration word 4 = 45914
      c1 = 23479
      c2 = 2074
      c3 = 717
      c4 = 615
      c5 = 1021
      c6 = 25
    */

    #include <SPI.h>

    const int clock = 9;

    void setup() {
      Serial.begin(9600);
      SPI.begin(); //see SPI library details on arduino.cc for details
      SPI.setBitOrder(MSBFIRST);
      SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz

      pinMode(clock, OUTPUT);
      delay(100);
    }

    void loop()
    {
      Serial.println("=====================================================================");
      TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

      analogWrite (clock, 128) ;
      resetsensor(); //resets the sensor - caution: afterwards mode = SPI_MODE0!

      //Calibration word 1
      unsigned int result1 = 0;
      unsigned int inbyte1 = 0;
      SPI.transfer(0x1D); //send first byte of command to get calibration word 1
      SPI.transfer(0x50); //send second byte of command to get calibration word 1
      SPI.setDataMode(SPI_MODE1); //change mode in order to listen
      result1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
      result1 = result1 << 8; //shift returned byte
      inbyte1 = SPI.transfer(0x00); //send dummy byte to read second byte of word
      result1 = result1 | inbyte1; //combine first and second byte of word
      Serial.print("Calibration word 1 = ");
      Serial.print(result1, HEX);
      Serial.print(" ");
      Serial.println(result1);

      resetsensor(); //resets the sensor

      //Calibration word 2; see comments on calibration word 1
      unsigned int result2 = 0;
      byte inbyte2 = 0;
      SPI.transfer(0x1D);
      SPI.transfer(0x60);
      SPI.setDataMode(SPI_MODE1);
      result2 = SPI.transfer(0x00);
      result2 = result2 << 8;
      inbyte2 = SPI.transfer(0x00);
      result2 = result2 | inbyte2;
      Serial.print("Calibration word 2 = ");
      Serial.print(result2, HEX);
      Serial.print(" ");
      Serial.println(result2);

      resetsensor(); //resets the sensor

      //Calibration word 3; see comments on calibration word 1
      unsigned int result3 = 0;
      byte inbyte3 = 0;
      SPI.transfer(0x1D);
      SPI.transfer(0x90);
      SPI.setDataMode(SPI_MODE1);
      result3 = SPI.transfer(0x00);
      result3 = result3 << 8;
      inbyte3 = SPI.transfer(0x00);
      result3 = result3 | inbyte3;
      Serial.print("Calibration word 3 = ");
      Serial.print(result3, HEX);
      Serial.print(" ");
      Serial.println(result3);

      resetsensor(); //resets the sensor

      //Calibration word 4; see comments on calibration word 1
      unsigned int result4 = 0;
      byte inbyte4 = 0;
      SPI.transfer(0x1D);
      SPI.transfer(0xA0);
      SPI.setDataMode(SPI_MODE1);
      result4 = SPI.transfer(0x00);
      result4 = result4 << 8;
      inbyte4 = SPI.transfer(0x00);
      result4 = result4 | inbyte4;
      Serial.print("Calibration word 4 = ");
      Serial.print(result4, HEX);
      Serial.print(" ");
      Serial.println(result4);

      //now we do some bitshifting to extract the calibration factors
      //out of the calibration words;
      long c1 = (result1 >> 1) & 0x7FFF;
      long c2 = ((result3 & 0x003F) << 6) | (result4 & 0x003F);
      long c3 = (result4 >> 6) & 0x03FF;
      long c4 = (result3 >> 6) & 0x03FF;
      long c5 = ((result1 & 0x0001) << 10) | ((result2 >> 6) & 0x03FF);
      long c6 = result2 & 0x003F;

      Serial.print("c1 = ");
      Serial.println(c1);
      Serial.print("c2 = ");
      Serial.println(c2);
      Serial.print("c3 = ");
      Serial.println(c3);
      Serial.print("c4 = ");
      Serial.println(c4);
      Serial.print("c5 = ");
      Serial.println(c5);
      Serial.print("c6 = ");
      Serial.println(c6);

      resetsensor(); //resets the sensor

      //Pressure:
      unsigned int presMSB = 0; //first byte of value
      unsigned int presLSB = 0; //last byte of value
      unsigned int D1 = 0;
      SPI.transfer(0x0F); //send first byte of command to get pressure value
      SPI.transfer(0x40); //send second byte of command to get pressure value
      delay(35); //wait for conversion end
      SPI.setDataMode(SPI_MODE1); //change mode in order to listen
      presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
      presMSB = presMSB << 8; //shift first byte
      presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
      D1 = presMSB | presLSB; //combine first and second byte of value
      Serial.print("D1 - Pressure raw = ");
      Serial.println(D1);

      resetsensor(); //resets the sensor

      //Temperature:
      unsigned int tempMSB = 0; //first byte of value
      unsigned int tempLSB = 0; //last byte of value
      unsigned int D2 = 0;
      SPI.transfer(0x0F); //send first byte of command to get temperature value
      SPI.transfer(0x20); //send second byte of command to get temperature value
      delay(35); //wait for conversion end
      SPI.setDataMode(SPI_MODE1); //change mode in order to listen
      tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
      tempMSB = tempMSB << 8; //shift first byte
      tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
      D2 = tempMSB | tempLSB; //combine first and second byte of value
      Serial.print("D2 - Temperature raw = ");
      Serial.println(D2); //voila!

      //calculation of the real values by means of the calibration factors and the maths
      //in the datasheet. const MUST be long
      const long UT1 = (c5 << 3) + 20224;
      const long dT = D2 - UT1;
      const long TEMP = 200 + ((dT * (c6 + 50)) >> 10);
      const long OFF  = (c2 * 4) + (((c4 - 512) * dT) >> 12);
      const long SENS = c1 + ((c3 * dT) >> 10) + 24576;
      const long X = (SENS * (D1 - 7168) >> 14) - OFF;
      long PCOMP = ((X * 10) >> 5) + 2500;
      float TEMPREAL = TEMP / 10;
      float PCOMPHG = PCOMP * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

      /*
        Serial.print("UT1 = ");
        Serial.println(UT1);
        Serial.print("dT = ");
        Serial.println(dT);
        Serial.print("TEMP = ");
        Serial.println(TEMP);
        Serial.print("OFFP = ");
        Serial.println(OFF);
        Serial.print("SENS = ");
        Serial.println(SENS);
        Serial.print("X = ");
        Serial.println(X);
      */

      Serial.print("Real Temperature in C = ");
      Serial.println(TEMPREAL);

      Serial.print("Compensated pressure in mbar = ");
      Serial.println(PCOMP);
      Serial.print("Compensated pressure in mmHg = ");
      Serial.println(PCOMPHG);

      //2-nd order compensation only for T < 20°C or T > 45°C

      long T2 = 0;
      float P2 = 0;

      if (TEMP < 200)
      {
        T2 = (11 * (c6 + 24) * (200 - TEMP) * (200 - TEMP) ) >> 20;
        P2 = (3 * T2 * (PCOMP - 3500) ) >> 14;
      }
      else if (TEMP > 450)
      {
        T2 = (3 * (c6 + 24) * (450 - TEMP) * (450 - TEMP) ) >> 20;
        P2 = (T2 * (PCOMP - 10000) ) >> 13;
      }

      if ((TEMP < 200) || (TEMP > 450))
      {
        const float TEMP2 = TEMP - T2;
        const float PCOMP2 = PCOMP - P2;

        float TEMPREAL2 = TEMP2 / 10;
        float PCOMPHG2 = PCOMP2 * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

        Serial.print("2-nd Real Temperature in C = ");
        Serial.println(TEMPREAL2);

        Serial.print("2-nd Compensated pressure in mbar = ");
        Serial.println(PCOMP2);
        Serial.print("2-nd Compensated pressure in mmHg = ");
        Serial.println(PCOMPHG2);
      }

      delay(5000);
    }

    void resetsensor() //this function keeps the sketch a little shorter
    {
      SPI.setDataMode(SPI_MODE0);
      SPI.transfer(0x15);
      SPI.transfer(0x55);
      SPI.transfer(0x40);
    }

  [1]: https://cdn.shopify.com/s/files/1/0672/9409/files/water_depth_sensor_MS5540C_Arduino_tutorial.pdf?698

body:
While writing this answer, I found out about the register emulation of the Arduino Uno Wifi. The Uno Wifi is a different chip, than the Uno, thus you have different registers. But the Uno Wifi was thought as a drop in replacement, so register emulation maps the old register names to the new registers, so that you can basically simply reuse the old code for the Uno. In my Arduino IDE (v1.8.9) I had a buildin Uno Wifi board, which seems to have the register emulation enabled without configuration option (I could compile your sketch even for the Uno Wifi). Through the board manager I installed the "Arduino megaAVR Boards" core, that contains the Arduino Uno Wifi rev2. If you choose this board in the board selection, you get the option to select the register emulation. For old code you need the emulation for ATmega328. With that, your old code should compile.

This makes the rest of my answer unnecessary, but since I already spend some time writing it,  I will leave it in the answer for information and for the case, that you don't want to use the register emulation.

---

You get the error, because the sketch, that you copied is made for the Arduino Uno, not the Arduino Uno Wifi. While the first uses an ATmega328P chip, the last is build with an ATmega4809 (you can find this information [here at the Arduino.cc store][1]). These are different chips, thus you cannot simply reuse code that is made for the Uno on the Uno Wifi.

`TCCR1B` is the control register B of Timer 1. This name is specific to the ATmega328P chip. The ATmega4809 has even more timers than the 328P, but they seem to get configured via different registers. Refer to the datasheets on the [product site of the ATmega4809][2]. The timer hardware and it's registers are described in the more general [megaAVR 0 series family datasheet][3]. At the first glance it seems, that not only the register description is different from the 328P, but also the positions of the different configurations. This means, that every code, that uses direct register manipulations for the timer, must be rewritten for the 4809.

Fortunately, I see only 1 line here, that does this: The line, that generated the compiler error. (The SPI library very likely already has fitting definitions inside for the 4809). You have the line

    TCCR1B = (TCCR1B & 0xF8) | 1;

That clears the 3 least significant bits (leaving the rest as it was) and setting the least significant bit to 1. According to chapter 16.11.2 of the 328P's datasheet (description of the TCCR1B register), these 3 bits are the clock selection. A bit code of `001` (only least significant bit set) means timer on, but with no prescaling.

To be honest, I'm not sure, if this line really does something, since directly after that, `analogWrite()` is called and I thought this function would overwrite the timer settings. But other posts (like [this one][4]) suggest, that it at least does not overwrite the clock selection.

I don't know, which timer get's used for outputting PWM to that pin, but for now, I will assume the first timer of type B. If you look into the families datasheet (as linked above) the clock source of the second timer (TCB) is configured with the register `TCB0.CTRLA` (see chapter 20.5.1). Bits 1 and 2 are configuring the prescaler (binary `00` for no prescaler), bit 0 enables the timer. So you can again write binary `001` to this register, leaving the rest untouched. So I suggest, you use this line instead of the old one

    TCB0.CTRLA = (TCB0.CTRLA & 0xF8) | 1;

This should do the same with the second timer, that was done in the original sketch. If the first timer is used for this, you would have to change `TCB0` to `TCA0.SINGLE` (I really don't know, why this SINGLE is needed) and change `0xF8` to `0xF0`, since TCA has 3 bits for selecting the clock source.

  [1]: https://store.arduino.cc/arduino-uno-wifi-rev2
  [2]: https://www.microchip.com/wwwproducts/en/ATMEGA4809
  [3]: http://ww1.microchip.com/downloads/en/DeviceDoc/megaAVR-0-series-Family-Data-Sheet-40002015C.pdf
  [4]: https://arduino.stackexchange.com/questions/25609/set-pwm-frequency-to-25-khz


message:
SoftwareSerial receives beginning of data mangled

I'm using SoftwareSerial to communicate with a Sigfox module. Documentation for the [`read`][1] function assigns its value to a `char`. However using it I get mangled characters and also have read in other question that I should assign it to `int` as it can return `-1` for no data and `[0;255]` for received character.

This is my basic troubleshooting example:
```
#include <SoftwareSerial.h>
SoftwareSerial Sigfox(11,10);

void setup() {
  Serial.begin(9600); // HW serial
  Sigfox.begin(9600); // SW serial --> sigfox
}

void loop() {
  if(Sigfox.available()) {
    int c = Sigfox.read();
    Serial.write(c);
  }
  if(Serial.available()) Sigfox.write(Serial.read());
}
```
When `c` is char, I get `-5` instead of `OK`. Also other output is mangled. When `c` is int, it receives the data OK.

My question is - why they use `char` in the example in documentation? Why is `char` signed in Arduino?

I want to read the entire line of text from serial port and store it into array. How to define that array? I have found an example on web that uses `char buffer[32]`, but then again I get mangled data when I assign to it. If I use array of `byte`/`int`/`unsigned char`, I can't print it as `Serial.write(SF_buffer);` won't compile because of `no matching function for call to 'write(unsigned char [32])'`.

So what variable types should I use to receive and store the text from SoftwareSerial correctly?

Here is my function for reading the whole line:
```arduino
unsigned char SF_buffer [32]; // max length of line to read from serial
bool SigfoxReadine() { // return true when whole line was received and is in buffer
  static int SF_cnt=0;
  while (Sigfox.available()) {
    int c = Sigfox.read();
    SF_buffer[SF_cnt++] = c;
    if ((c == '\n') || (SF_cnt == sizeof(SF_buffer)-1)) {
       SF_buffer[SF_cnt] = '\0';
       SF_cnt = 0;
       return(true);
    }
  }
  return(false);
}
```

**UPDATE:**

Trying `readBytesUntil` - the same result, but I have found that issue is only when I send data to module using `println` as in this example:

```
#include <SoftwareSerial.h>
SoftwareSerial Sigfox(11,10);

void setup() {
  Serial.begin(9600); // HW serial
  Sigfox.begin(9600); // SW serial --> sigfox
  Sigfox.println("AT$I=11");
}

void loop() {
  if(Serial.available()) Sigfox.write(Serial.read());
  SF_read();
}

void SF_read() {
  if (Sigfox.available()) {
    char buff[32];
    int l = Sigfox.readBytesUntil('\n', buff, sizeof(buff));
    if (l > 0 && buff[l - 1] == '\r') {
      l--; // to remove \r if it is there
    }
    buff[l] = 0; // terminate the string
    Serial.println(buff);
  }
}
```
The response to first command (in setup) is mangled. The response to the same AT command manually written into serial monitor (and sent to module via Sigfox.write in loop) is OK.

> ӂ*⸮FBB1E27EE7
>
> 3430E2FBB1E27EE7

Also maybe I'm little lost in when to use print and when write... Example says to use `write()` to send back the char that was `read()`. Juraj's response uses `println()` to print the null-terminated buffer. What is the difference when I write/println this buffer?

  [1]: https://www.arduino.cc/en/Reference/SoftwareSerialRead

body:
I like the readBytes or readBytesUntil function. It doesn't end on a small gap between received bytes and fills the buffer. This functions are blocking with timeout, but if read some other device the input is usually fast and terminated reliably.

example for readBytesUntil:

    if (Serial.available()) {
      char buff[32];
      int l = Serial.readBytesUntil('\n', buff, sizeof(buff));
      if (l > 0 && buff[l - 1] == '\r') {
        l--; // to remove \r if it is there
      }
      buff[l] = 0; // terminate the string
      Serial.println(buff);
    }


body:
Last test showed it mangles data only when using `println()` and doesn't depend on the `char` type. Then I remembered something about CRLF in the Sigfox datasheet:
> Is recommended to use full duplex UART. In case of using half duplex, AT
commands has to be ended only with one of ‘\r’ or ‘\n’ not both. Because if you send
“AT\r\n” the Sigfox devkit starts sending “OK” instantly after it receive ‘\r’, but
microcontroller is still sending byte ‘\n’.

SoftwareSerial is in fact [half-duplex only][1] (although I didn't find it in the reference documentation) and `println()` sends both '\r' and '\n', so while sending the later, Sigfox module is already trying to send back the answer, which gets mangled by SoftwareSerial.

Feel free to add your answer to explain why `char` is signed in Arduino and when to use `print()` and when `write()` with serial port.

  [1]: https://electronics.stackexchange.com/questions/23265/arduino-software-serial-full-duplex


message:
SIM800L GSM module is not working

I'm testing SIM800L GSM module with Arduino UNO and module is blinking 3 times every 15 seconds or sometime every 45 seconds. Why this is happening?
In serial monitor it shows `Message Sent Successfully!` but I'm not getting any message.I tried with multiple numbers. Still not getting any message.

I have tested several codes which shows outputs of AT commands. Nothing was working. Power supply is 5V 5A.

    /*
     *   Author@ExploreEmbedded
     *   Example to Send messages Interactively using GSM Sim800L
     *
     *   LIBRARY CREDITS:
     *   Thanks to Cristian Steib(steibkhriz@gmail.com) for the library.
     *
     *
     *
     *      PINOUT:
     *        _____________________________
     *       |  ARDUINO UNO >>>   Sim800L  |
     *        -----------------------------
     *            GND      >>>   GND
     *        RX  10       >>>   TX
     *        TX  11       >>>   RX
     *       RESET 2       >>>   RST
     *
     *
    */

    #include <Sim800L.h>
    #include <SoftwareSerial.h> //is necesary for the library!!
    Sim800L Sim800L;  //to declare the library
    char text[161]=""; //buffer to store message
    char number[11]=""; //phone number to send message
    int cnt;
    bool error; //to catch the response of sendSms

    void setup(){
        Sim800L.begin(); // initializate the library.
        Serial.begin(9600);
    }

    void loop(){

          //Read the Number
          Serial.print("\nEnter 10 digit Phone Number:");
          while(Serial.available()<=0);
          cnt = Serial.readBytesUntil('\n',number, 11);
          number[cnt] = '\0';
          Serial.println(number);

          //clear the serial input buffer so that no typed characters are pending

          delay(1000); //delay required before clearing the input buffer
          while(Serial.available()>0) //clear buffer
          {
            Serial.read();
          }

          //Read the Message to be sent
          Serial.print("Enter Message:");
          while(Serial.available()<=0);
          cnt = Serial.readBytesUntil('\n',text, 160);
          text[cnt] = '\0';
          Serial.println(text);
          delay(1000);

          while(Serial.available()>0) //clear buffer
          {
            Serial.read();
          }

          //Send the message and display the status
          error = Sim800L.sendSms(number,text);
          if(error)
          Serial.println("Error Sending Message");
          Serial.println("Message Sent Successfully!");

    }

body: I found what's happening. Module was shutdown due to over voltage.


message:
Relay board not working with nodemcu

![enter image description here](https://i.stack.imgur.com/ObKcZ.jpg)

This is the relay board

I am using nodemcu to make a home automation project which is controlled by google assistant. This is the code i am using is this one

    #include <ESP8266WiFi.h>
    #include "Adafruit_MQTT.h"
    #include "Adafruit_MQTT_Client.h"

    #define Relay1            D0
    #define Relay2            D1
    #define Relay3            D2
    #define Relay4            D3

    #define WLAN_SSID       "Subhodip"             // Your SSID
    #define WLAN_PASS       "09003244135"        // Your password

    /************************* Adafruit.io Setup *********************************/

    #define AIO_SERVER      "io.adafruit.com"
    #define AIO_SERVERPORT  1883                   // use 8883 for SSL
    #define AIO_USERNAME    "SubhodipRoy"            // Replace it with your username
    #define AIO_KEY         "50a98bb44f6b48b69e645badadf8fb577894"   // Replace with your Project Auth Key

    /************ Global State (you don't need to change this!) ******************/

    // Create an ESP8266 WiFiClient class to connect to the MQTT server.
    WiFiClient client;
    // or... use WiFiFlientSecure for SSL
    //WiFiClientSecure client;

    // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
    Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

    /****************************** Feeds ***************************************/

    // Setup a feed called 'onoff' for subscribing to changes.
    Adafruit_MQTT_Subscribe Light1 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME"/feeds/Relay1"); // FeedName
    Adafruit_MQTT_Subscribe Light2 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay2");
    Adafruit_MQTT_Subscribe Light3 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay3");
    Adafruit_MQTT_Subscribe Light4 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay4");

    void MQTT_connect();

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

      pinMode(Relay1, OUTPUT);
      pinMode(Relay2, OUTPUT);
      pinMode(Relay3, OUTPUT);
      pinMode(Relay4, OUTPUT);

      // Connect to WiFi access point.
      Serial.println(); Serial.println();
      Serial.print("Connecting to ");
      Serial.println(WLAN_SSID);

      WiFi.begin(WLAN_SSID, WLAN_PASS);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println();

      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

      // Setup MQTT subscription for onoff feed.
      mqtt.subscribe(&Light1);
      mqtt.subscribe(&Light3);
      mqtt.subscribe(&Light2);
      mqtt.subscribe(&Light4);
    }

    void loop() {

      MQTT_connect();

      Adafruit_MQTT_Subscribe *subscription;
      while ((subscription = mqtt.readSubscription(20000))) {
        if (subscription == &Light1) {
          Serial.print(F("Got: "));
          Serial.println((char *)Light1.lastread);
          int Light1_State = atoi((char *)Light1.lastread);
          digitalWrite(Relay1, Light1_State);

        }
        if (subscription == &Light2) {
          Serial.print(F("Got: "));
          Serial.println((char *)Light2.lastread);
          int Light2_State = atoi((char *)Light2.lastread);
          digitalWrite(Relay2, Light2_State);
        }
        if (subscription == &Light3) {
          Serial.print(F("Got: "));
          Serial.println((char *)Light3.lastread);
          int Light3_State = atoi((char *)Light3.lastread);
          digitalWrite(Relay3, Light3_State);
        }
        if (subscription == &Light4) {
          Serial.print(F("Got: "));
          Serial.println((char *)Light4.lastread);
          int Light4_State = atoi((char *)Light4.lastread);
          digitalWrite(Relay4, Light4_State);

        }
      }

    }

    void MQTT_connect() {
      int8_t ret;

      // Stop if already connected.
      if (mqtt.connected()) {
        return;
      }

      Serial.print("Connecting to MQTT... ");

      uint8_t retries = 3;

      while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
        Serial.println(mqtt.connectErrorString(ret));
        Serial.println("Retrying MQTT connection in 5 seconds...");
        mqtt.disconnect();
        delay(5000);  // wait 5 seconds
        retries--;
        if (retries == 0) {
          // basically die and wait for WDT to reset me
          while (1);
        }
      }
      Serial.println("MQTT Connected!");

    }

Connecting the pins as stated below

VIN-->VCC
D0--> IN1
D1--> IN2
D2-->IN3
D3-->IN4
Gnd-->Gnd

But only IN2,IN3 and IN4 led of relay board are only glowing the IN1 is not glowing and the relays are not switching on/off...

Anyone please help....

Please give any solution... Why the relays are not switch-on?

Please reply as soon as possible... I am very disturbed... Even cant sleep at night....

body:
From the description and comments it looks like the problem is HW related. I recommend you to do a relay module test (wthout NodeMCU):

 1. Try to switch the relays on/off  just by connecting the power source you are using for powering the NodeMCU. Connect VCC–5V, GND–GND and one of the IN channels directly to 5V pin. If the relay switches on, try another channel. If not, try to connect IN to GND instead of 5V (inverted logic).
 2. If 1. did not worked, check the yellow jumper on the right side of the relay board. The jumper must be attached (in case you don't want to use another independent power source just for relays).
 3. If 2. did not worked, check if the relay board is not intended for use with 12 V DC power source (check the relay marking).

At this point you should know if all channels of the relay module are working and also the switching logic (inverted/noninverted). The next step should be connecting the relay module to the NodeMCU and run a "blink" example for all channels. If all is working well, we will be sure the problem is NOT HW related...


message:
I don't know how to do the code for an rtc controlling a relay

I'm doing a project for my brother witch is an automatic watering thing,
it's all working fine but I just don't know how to repeat the code to make the relay say come on for 5min at 0900 than 5min at 1200 and also 5min at 1700.
how do I do this, I'm not very good at this so I need clear instructions or someone to write it.
pls help.
thank you, James.

here is the code I need to be repeated to meet what I need done, basically I just need the relay to trigger every 4h for 5min. its on an rtc on an Arduino UNO.

    #include <DS3231.h>

    int Relay = 4;

    DS3231  rtc(SDA, SCL);
    Time t;

    const int OnHour = 19; //SET TIME TO ON RELAY (24 HOUR FORMAT)
    const int OnMin = 55;
    const int OffHour = 19; //SET TIME TO OFF RELAY
    const int OffMin = 56;

    void setup() {
      Serial.begin(115200);
      rtc.begin();
      pinMode(Relay, OUTPUT);
      digitalWrite(Relay, LOW);
    }

    void loop() {
      t = rtc.getTime();
      Serial.print(t.hour);
      Serial.print(" hour(s), ");
      Serial.print(t.min);
      Serial.print(" minute(s)");
      Serial.println(" ");
      delay (1000);

      if(t.hour == OnHour && t.min == OnMin){
        digitalWrite(Relay,HIGH);
        Serial.println("LIGHT ON");
        }

        else if(t.hour == OffHour && t.min == OffMin){
          digitalWrite(Relay,LOW);
          Serial.println("LIGHT OFF");
        }
    }

body:
You will most likely find nobody here, who will write the code for you, since this is not a free code writing service. But I will suggest a good way.

> I just need the relay to trigger every 4h for 5min

The phrase "every x hours" screams for using the modulo operator `%`. Modulo gives you the rest value of an integer division. See these values:

    0 % 4 = 0
    1 % 4 = 1
    2 % 4 = 2
    3 % 4 = 3
    4 % 4 = 0
    5 % 4 = 1
    ...
    7 % 4 = 3
    8 % 4 = 0

You see, the modulo 4 operation gives you zero every 4 hours starting with midnight. So make an if statement based on that

    if(hour % 4 == 0 && min == 0)

to switch on and

    if(hour % 4 == 0 && min == 5)

to switch off. Just change your code in this way and you are done.


message:
ESP32 playing wav sounds distorted or too fast (but not all wav's)

I am building a sound project on an ESP 32 via I2S  using an example from:
[https://github.com/nhatuan84/esp32-i2s-sdcard-wav-player][1]

It works fine with the example wav file t.wav posted in the repository.

But when I try to use a custom wav which I exported from audacity it sounds distorted  and/or too slow/fast (it sounds fine when I play it within audacity).

This is an example that is totaly distorted when playing from the esp with I2S:
[badly sounding wav][2]
While it sounds fine when playing from audacity.

I tried different settings in audacity exporting 16 bit, 32 bit. 44100 Hz, 11025.

Any hints or tips what I could try or am doing wrong?

Thx!

Jeroen

  [1]: https://github.com/nhatuan84/esp32-i2s-sdcard-wav-player
  [2]: http://vandevorst.com/temp/starting.wav

body:
I know this is an old question, but I ran into the same issue and spent days trying to figure it out, so I hope this answer can save another poor soul from that:

The Problem
------

For reference, I have an ESP32 (HUZZAH32 from Adafruit) hooked up to a breakout board that uses a PCM5102a chip as an external DAC. I would set the sample rate to 44.1khz but it seemed my song, which I confirmed had accurate data, would play at double speed. Lowering the sample rate to 22.05khz made it play at the correct speed, but quality seemed reduced.

The Root Cause
------
The issue was that my .channel_format value was set to I2S_CHANNEL_FMT_RIGHT_LEFT, however *my data was mixed to mono in Audacity.* This problem may exhibit itself differently depending on how you push bytes via I2S, but for me, this meant double speed. This is because the protocol was reading every 2 samples (which should be separate) as the left/right channels. Effectively, this meant that it was skipping every other sample, which doubled the playback speed.

Code Snippets
------
My i2s_config_t code:

    #define DMA_BUFFER_COUNT 8
    #define DMA_BUFFER_LENGTH 1024

    i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_TX,
        .sample_rate = 44100,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // this was causing double speed due to being I2S_CHANNEL_FMT_RIGHT_LEFT
        .communication_format = (i2s_comm_format_t) (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
        .tx_desc_auto_clear = true,
        .dma_buf_count = DMA_BUFFER_COUNT,
        .dma_buf_len = DMA_BUFFER_LENGTH,
        .use_apll = false,
        .intr_alloc_flags = 0
    };

My code for sending bytes to the external DAC (which is its own task):

(rx_buffer and readPointer here are part of a ring buffer that I streamed in over wifi on a separate task, please only use as reference and substitute for your own sound data)

    int FRAMES_TO_SEND = 1024;
    int32_t frames[FRAMES_TO_SEND];

    for (int i = 0; i < FRAMES_TO_SEND; i++) {
        // copy into i2s buffer
        int32_t sample = (int32_t)rx_buffer[readPointer];

        // write bytes to the i2s peripheral
        esp_err_t err = i2s_write(i2s_num, (char *) &sample,
            sizeof(int32_t), &bytesWritten, 100);

        if(err != ESP_OK) {
            printf("ESP32 i2s Errorcode %i", err);
        }

        readPointer++;
        if (readPointer == TOTAL_BUFFER_SIZE) {
            readPointer = 0;
        }
    }

Hopefully this helps out some of you, or at least get you on track to the solution. Unfortunately, the I2S protocol on the ESP32 is not very well documented so there's a lot of trial and error to be had. Keep at it!


message:
MKR GSM 1400 Works only when connected to computer

My MKR GSM 1400 works fine when connected to a computer (powered USB) and after opening a serial connection to it.  It does not when I plug it into a power supply. My power supply is a 5V 3A with a USB adapter.

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

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

body: If your sketch on an Arduino with native USB doesn't run if not connected to USB, always first check if you didn't forget to disable a dependence on `Serial`.  A common error is a `while (!Serial) {}` endless loop in setup().


message:
ESP32 access point code not compiling

I'm trying to use the ESP32 board to control an LED, buzzer, and motor (ABA) through an access point.

I got some code from this page:
https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/
Which is amazing! I changed some names here and there and evrything okay (to control ONLY 2 things).

Now that I wanted to add the 3rd device, the code is not compiling.

I get this error:

    exit status 1

    too few arguments to function 'String SendHTML(uint8_t, uint8_t, uint8_t)'

With the line in bold marked.

**server.send(200, "text/html", SendHTML(ABA1status,false));**

    #include <ETH.h>
    #include <WiFi.h>
    #include <WiFiAP.h>
    #include <WiFiClient.h>
    #include <WiFiGeneric.h>
    #include <WiFiMulti.h>
    #include <WiFiScan.h>
    #include <WiFiServer.h>
    #include <WiFiSTA.h>
    #include <WiFiType.h>
    #include <WiFiUdp.h>

    #include <HTTP_Method.h>
    #include <WebServer.h>

    /* Put your SSID & Password */
    const char* ssid = "ESP32DeltaSolutions";  // Enter SSID here
    const char* password = "deltasolutions123";  //Enter Password here

    /* Put IP Address details */
    IPAddress local_ip(192,168,1,2);
    IPAddress gateway(192,168,1,1);
    IPAddress subnet(255,255,255,0);

    WebServer server(80);

    uint8_t LED1pin = 25;
    bool LED1status = LOW;

    uint8_t BUZZ1pin = 32;
    bool BUZZ1status = LOW;

    uint8_t ABA1pin = 35;
    bool ABA1status = LOW;

    void setup() {
      Serial.begin(115200);
      pinMode(LED1pin, OUTPUT);
      pinMode(BUZZ1pin, OUTPUT);
      pinMode(ABA1pin, OUTPUT);

      WiFi.softAP(ssid, password);
      WiFi.softAPConfig(local_ip, gateway, subnet);
      delay(100);

      server.on("/", handle_OnConnect);
      server.on("/led1on", handle_led1on);
      server.on("/led1off", handle_led1off);
      server.on("/buzz1on", handle_buzz1on);
      server.on("/buzz1off", handle_buzz1off);
      server.on("/aba1on", handle_aba1on);
      server.on("/aba1off", handle_aba1off);
      server.onNotFound(handle_NotFound);

      server.begin();
      Serial.println("HTTP server started");
    }
    void loop() {
      server.handleClient();
      if(LED1status)
      {digitalWrite(LED1pin, HIGH);}
      else
      {digitalWrite(LED1pin, LOW);}

      if(BUZZ1status)
      {digitalWrite(BUZZ1pin, HIGH);}
      else
      {digitalWrite(BUZZ1pin, LOW);}

      if(ABA1status)
      {digitalWrite(ABA1pin, HIGH);}
      else
      {digitalWrite(ABA1pin, LOW);}

    }

    void handle_OnConnect() {
      LED1status = LOW;
      BUZZ1status = LOW;
      ABA1status = LOW;
      Serial.println("GPIO4 Status: OFF | GPIO5 Status: OFF");
      server.send(200, "text/html", SendHTML(LED1status,BUZZ1status,ABA1status));
    }

    void handle_led1on() {
      LED1status = HIGH;
      Serial.println("GPIO4 Status: ON");
      server.send(200, "text/html", SendHTML(true,LED1status));
    }

    void handle_led1off() {
      LED1status = LOW;
      Serial.println("GPIO4 Status: OFF");
      server.send(200, "text/html", SendHTML(false,LED1status));
    }

    void handle_buzz1on() {
      BUZZ1status = HIGH;
      Serial.println("GPIO5 Status: ON");
      server.send(200, "text/html", SendHTML(BUZZ1status,true));
    }

    void handle_buzz1off() {
      BUZZ1status = LOW;
      Serial.println("GPIO5 Status: OFF");
      server.send(200, "text/html", SendHTML(BUZZ1status,false));
    }

    void handle_aba1on() {
      ABA1status = HIGH;
      Serial.println("GPI35 Status: ON");
      server.send(200, "text/html", SendHTML(ABA1status,true));
    }

    void handle_aba1off() {
      BUZZ1status = LOW;
      Serial.println("GPI35 Status: OFF");
      **server.send(200, "text/html", SendHTML(ABA1status,false));**
    }

    void handle_NotFound(){
      server.send(404, "text/plain", "Not found");
    }

    String SendHTML(uint8_t LED1status,uint8_t BUZZ1status,uint8_t ABA1status){
      String ptr = "<!DOCTYPE html> \n";
      ptr +="<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
      ptr +="<title>LED Control</title>\n";
      ptr +="\n";
      ptr +="\n";
      ptr +="\n";
      ptr +="
ESP32 Web Server
\n";
      ptr +="
Using Access Point(AP) Mode
\n";
      ptr +="
Delta solutions
\n";

       if(led1stat)
      {ptr +="
LED1 Status: ON
OFF\n";}
      else
      {ptr +="
LED1 Status: OFF
ON\n";}

      if(buzz1stat)
      {ptr +="
BUZZ1 Status: ON
OFF\n";}
      else
      {ptr +="
BUZZ1 Status: OFF
ON\n";}

      if(aba1stat)
      {ptr +="
ABA1 Status: ON
OFF\n";}
      else
      {ptr +="
ABA1 Status: OFF
ON\n";}

      ptr +="\n";
      ptr +="\n";
      return ptr;

Any suggestions?

Thanks!

body:
The syntax of six `SendHTML` you use with `true` and `false` is actually wrong.

By defining a function like this `String SendHTML(uint8_t LED1status,uint8_t BUZZ1status,uint8_t ABA1status)`, you mean that first, second and third input to this function are Status of LED1, Status of BUZZ1 and Status of ABA1.

So try replacing all six `SendHTML` with `true` and `false` functions to this `SendHTML(LED1status,BUZZ1status,ABA1status)`


message:
Time information from GPS receiver: how to tell whether it is fresh or stale?

I see that TinyGPS++ library extracts time information from `GxRMC` and `GxGGA` NMEA sentences streamed by GPS receiver. However, in my experiments I observed that both of my GPS receivers generate `GxRMC` sentences with time data in them at least once a second even when they have no access to satellites.

I presume that the time data comes from the internal clock of the receiver (and is maintained between warm startups). This is perfectly OK. However, I would like to know what measures are required by NMEA specification to ensure the reliability of this time data.

Am I correct in assuming that the device itself is supposed to understand that after certain period of time its internal clock will diverge? And that after that period the device will by itself stop pumping out these `GxRMC` sentences, until it gets a chance to see a satellite and re-sync its internal clock? Or should I expect to see the next field in `GxRMC` sentence to change from `A` to `V`?

If not, then what is the proper way to ensure that I receive "satellite time" (or close to that) or nothing at all?

body:
Most of the GPS modules keep on sending the data in the NMEA format whether they have a GPS fix or not, however, you can parse the GPS data to find whether the data is the latest data received from the GPS or not. If you look at the definition of the NMEA data [here](http://aprs.gids.nl/nmea/), there are a few variables in the data that you can use to find whether the data is the latest data from the GPS or not.

You can use the "Fix Quality" in GPGGA as well as "Validity/Receiver warning" in GPRMC for your module. The tinyGPS indeed has both of these variables being parsed.

In the tinyGPS library, if **_gps_data_good** is true then the data coming from the GPS module is the latest data it received from the GPS satellites. The program uses either the fix or validity to determine this (Refer to the library [here](https://github.com/mikalhart/TinyGPS/blob/master/TinyGPS.cpp#L233) and [here](https://github.com/mikalhart/TinyGPS/blob/master/TinyGPS.cpp#L264)).

You should just keep checking this variable to find whether the current data is the latest from the GPS or is it being calculated internally.


message:
Noisy analogRead

I'm trying to read voltage using Arduino, here's the code:

    float r1 = 99700;
    float r2 = 10004;
    float adc, voltage;
    unsigned long analog;
    void setup() {
      Serial.begin(9600);
      analogReference(EXTERNAL);
      pinMode(A0, INPUT);
    }

    void loop() {
      for (int i = 0; i < 64; ++i) {
        analog += analogRead(A0);
        delay(1);
      }
      analog = analog / 64;
      adc = (analog * 2.441) / 1024;
      voltage = adc / (r2 / (r1 + r2));
      Serial.print(analog);
      Serial.print(", ");
      Serial.print(adc);
      Serial.print(", ");
      Serial.print(voltage);
      Serial.println(" ");
    }

Had a VERY noisy reading and what I did was adding an external voltage reference (TL431) and also connected a 9V switching adapter to Arduino UNO. But I still had some noise in analog readings so as you can see in the code I'm taking 64 sample and averaging them.

After doing all those noise reduced a lot but not completely:

[![console][1]][1]

What else should one do to get an steady reading?

<sub>*By taking 1024 sample noise will be removed but then I'm sacrificing performance...*</sub>

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

body:
I solved the problem by adding 3 capacitors:

1. 220uF on the Arduino power supply.

2. 100uF on TL431 output.

3. 1uF on A0 input.

I also increased the sampling rate to 128 times (and removed the delay).

Here's the result, as accurate as my multimeter:

[![concole][1]][1]

[![result][2]][2]

There's still 2mV difference in higher voltages which is because of my 2.5V reference voltage and Arduino ADC 10bit resolution (2.5 / 1024 = 0.002).

  [1]: https://i.stack.imgur.com/yy4p4.png
  [2]: https://i.stack.imgur.com/lSvgw.jpg


message:
Running loop for a specific time period

I currently have a loop that runs without a time condition:

    unsigned long previousMillis = 0;        // will store last time LED was updated

    int WET=4;//wet line
    int DRY=5;//dry line
    int Inhale=1000;//msec
    int Exhale=1000;//msec
    //int Noflow=3000;//msec

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

    void loop() {
      //inhale
      digitalWrite(WET,LOW);
      digitalWrite(DRY,HIGH);
      delay (Inhale);
      //exhale
      digitalWrite(WET,HIGH);
      digitalWrite(DRY,LOW);
      delay (Exhale);
      //No flow
      //digitalWrite(WET,HIGH);
      //digitalWrite(DRY,HIGH);
      //delay (Noflow);
    }

Then i have tried to code a "timer" for each cycle,but i got error:"
exit status 1
Error compiling for board Arduino/Genuino Uno."

Code with timer:

    unsigned long previousMillis = 0;        // will store last time LED was updated

    int WET = 4; //wet line
    int DRY = 5; //dry line
    //int Inhale=1000;//msec
    //int Exhale=1000;//msec
    //int Noflow=1000;//msec
    int BPM = 60;
    int IE = (((60 * 1000) / BPM) / 2);

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

    void loop() {
      for (int i = 0; i = 20;)
        int BPM = BPM + 10;
    #include <elapsedMillis.h>

      elapsedMillis timeElapsed;
      unsigned int interval = 60000; //one minute in ms

      while (timeElapsed < interval) {

        //inhale
        digitalWrite(WET, LOW);
        digitalWrite(DRY, HIGH);
        delay (IE);
        //exhale
        digitalWrite(WET, HIGH);
        digitalWrite(DRY, LOW);
        delay (IE);
        //No flow
        //digitalWrite(WET,HIGH);
        //digitalWrite(DRY,HIGH);
        //delay (2000);
      }
    }

Target ouput: to run every cycle of the loop for 1 min.

Any one familiar with this error?
Many thanks for your help

body:
Your code has a number of problems:

Don't put `#include` statements for header files in the middle of your code. They belong at the top, before any other code. (What is the header file `elapsedMillis.h`?)

Another thing: Your for loop is a mess. It should read something like: `for (int i = 0; i < 20; i++)` (That would cause the for loop to run 20 times, with the value of i ranging from 0 to 19.) However, what do you want to happen in your for loop? Without braces after that code, the ONLY line that will execute 20 times is the `int BPM = BPM + 10;` line (which doesn't make any sense.)

You really shouldn't use time-based while loops inside your main loop function. That defeats the purpose of using timers instead of delay statements. And you should get rid of your calls to `delay()` and use `millis()` to manage all your timing. Do a search on "Arduino blink no delay" and study the examples for information on how to restructure your code.


body:
1. Your for loop won't run as initially i is equal to 0 and you are comparing it with 20 also you didn't have any 3rd variable refreshing condition in your for loop.
2. You are declaring BPM new every time your loop run which is wrong
3. Also you are including header file in between your program run which will mess up your code and it is totally wrong practice.


message:
How to make a custom character on a TFT LCD display? (128x128)

I'm currently using the ucglib library. I'm new to arduino and I'm wanting to simply display a lcd smiley I made with the byte generator. I still have some of the original 'font hello world' stuff down the bottom but I'm curious how to make my character work.

I want to make different smileys in different colours but I'm unsure how to go about this as every guide is on a 16x2 lcd and not a tft one. I have an arduino nano that is just hooked up to that lcd display. I'm going to make pressing buttons change the smiley after I've figured out how to actually put a smiley into it. Hope someone can help.

     * LED =   3.3V
     * SCK =   13
     * SDA =   11
     * A0 =    8
     * RESET = 9
     * CS =    10
     * GND =   GND
     * VCC =   5V

        #include "Ucglib.h"  // Include Ucglib library to drive the display

    // Create display and define the pins:
    Ucglib_ST7735_18x128x160_HWSPI ucg(8, 10, 9);

    int smiley = byte customChar[] = {
      B00000,
      B01010,
      B01010,
      B00000,
      B10001,
      B10001,
      B11111,
      B00000
    };

    void setup(void)  // Start of setup
    {

      //ucg.begin(UCG_FONT_MODE_TRANSPARENT);  // It doesn't overwrite background, so it's a mess for text that changes
      ucg.begin(UCG_FONT_MODE_SOLID);  // It writes a background for the text. This is the recommended option

      ucg.clearScreen();  // Clear the screen

      ucg.setRotate180();  // Put 90, 180 or 270, or comment to leave default

      ucg.setColor(0, 255, 255, 255);  // Set color (0,R,G,B)
      ucg.setColor(1, 0, 0, 0);  // Set color of text background (1,R,G,B)
      ucg.setPrintPos(0,24);  // Set position (x,y)
      ucg.print("Welcome");  // Print text or value

      // Draw smiley:
      ucg.setColor(0, 255, 255);  // Set color (0,R,G,B)
      ucg.drawFrame(0, 58, 60, 30);  // Start from top-left pixel (x,y,wigth,height)

    void loop(void)  // Start of loop
    {

      Variable1++;  // Increase variable by 1
      if(Variable1 > 150)  // If Variable1 is greater than 150
      {
        Variable1 = 0;  // Set Variable1 to 0
      }

      // Convert Variable1 into a string, so we can change the text alignment to the right:
      // It can be also used to add or remove decimal numbers.
      char string[10];  // Create a character array of 10 characters
      // Convert float to a string:
      dtostrf(Variable1, 3, 0, string);  // (<variable>,<amount of digits we are going to use>,<amount of decimal digits>,<string name>)

      // We are going to print on the display everything that is dynamic on the loop, to refresh continuously:

      // Write to the display the Variable1 with left text alignment:
      ucg.setFont(ucg_font_inb16_mr);  // Set font
      ucg.setColor(0, 255, 255, 0);  // Set color (0,R,G,B)
      ucg.setColor(1, 0, 0, 0);  // Set color of text background (1,R,G,B)
      ucg.setPrintPos(9,81);  // Set position (x,y)
      ucg.print(Variable1);  // Print text or value

      // There is a problem when we go, for example, from 100 to 99 because it doesn't automatically write a background on
      // the last digit we are not longer refreshing. We need to check how many digits are and fill the space remaining.
      if(Variable1 < 10)  // If Variable1 is less than 10...
      {
        // Fill the other digit with background color:
        ucg.print(" ");
      }
      if(Variable1 < 100)  // If Variable1 is less than 100...
      {
        // Fill the other digit with background color:
        ucg.print(" ");
      }

      // Write to the display the string with right text alignment:
      ucg.setFont(ucg_font_inb16_mr);  // Set font
      ucg.setColor(0, 0, 255, 0);  // Set color (0,R,G,B)
      ucg.setColor(1, 0, 0, 0);  // Set color of text background (1,R,G,B)
      ucg.setPrintPos(76,81);  // Set position (x,y)
      ucg.print(string);  // Print text or value

    }  // End of loop

body:
Simple: you don't.

You only need to create a "custom character" on character-only displays (where you are actively programming a new character into the display's internal character set).

With a graphical display there is no "character" - only graphics.  The graphics library has fonts, which it then uses to convert text into graphics.

To display something that isn't in your currently selected font, just draw it. That could be from a bitmap graphic (there will be examples in your chosen graphics library) or using primitives, like circles and lines.


message:
Menus not changing when button is pressed TFT 128 x 128

I've just followed a tutorial so that when a button is pressed it goes through a menu. Click once, next slide. Only issue is it isn't appearing on my screen at all. It has uploaded but I'm a total novice when it comes to breadboards etc. Here is my code:

        #include "Ucglib.h" // library for this display
    #include <TFT.h> // Hardware-specific library
    #include <SPI.h>

    #define CS   10
    #define DC   8
    #define RESET  9

    #define up 5
    #define down 6

    TFT TFTscreen = TFT(CS, DC, RESET);
    const int menuSize = 4;
    String menuItems(menuSize);

    bool upLastState = HIGH;
    bool downLastState = HIGH;

    int currentMenu = 0;
    String temp;
    char currentPrintOut(10);

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

      pinMode(up, INPUT_PULLUP);
      pinMode(down, INPUT_PULLUP);

      menuItems[0] = ":)";
      menuItems[1] = ":(";
      menuItems[2] = "X(";
      menuItems[3] = ":S";
      menuItems[4] = ":T";

      //initialize the library
      TFTscreen.begin();

      MenuChanged();
    }

    void loop() {
      if (digitalRead(up) != upLastState) {
        upLastState = !upLastState;
      }

      if (!upLastState) {
        if (currentMenu > 0) {
          currentMenu--;
        } else {
          currentMenu = menuSize - 1;
        }
        MenuChanged();
      } else {
      }

     if (digitalRead(down) !=downLastState) {
      downLastState = !downLastState;

      if (!downLastState) {
        if (currentMenu < menuSize - 1) {
          currentMenu++;
        } else {
          currentMenu = 0;
        }
        //Serial.printIn(menuItems[currentMenu]);
        MenuChanged();
      } else {
        //Release
      }
     }

       delay(50);
     }

     void MenuChanged() {
      Serial.println(menuItems[currentMenu]);

    // clear the screen with a black background
      TFTscreen.background(0,0,0);
      TFTscreen.setTextSize(9);
      TFTscreen.stroke(255,255,255);

      temp = String(menuItems[currentMenu]);
      temp.toCharArray(currentPrintOut, 10);

      TFTscreen.text(currentPrintOut, 40, 32);
    }

Edited back to original as per request

body:
You can make things much simpler:

    int count = 0;
    int button = 5;
    int buttonStatus;
    unsigned long timer = 0;

    void setup() {
      Serial.begin(9600);
      pinMode(button, INPUT_PULLUP);
    }

    void loop() {
      buttonStatus = digitalRead(button); // read the button status
      if (buttonStatus == LOW) {
        if (millis() - timer > 200) { //de-bouncing the button
          count++; // increase +1 each time button is pressed
          // clear screen function should be here
          timer = millis();
        }
      }
      if (count > 3){ // if count is bigger than 3 start over.
        count = 0;
        // clear screen function should be here
      }
      switch (count){
        case 1: // if count == 1
        // show charecter :)
        break; // break out of this case!
        case 2:
        // show charecter :(
        break;
        case 3:
        // show charecter :D
        break;
        default: // if none of above cases is valid
        count = 0;
        // clear screen function should be here
      }
      Serial.println(count);
      delay(100);
    }

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

<!-- End schematic -->

So each time button is pressed `count` value will increase by 1. you can also add another button to decrease this value...

You might also notice when pushing the button it'll count more than once, you'll also need to De-Bounce the button. [tutorial][1].

**Edit:** added de-bounce function.

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


message:
counting revolution of incremental encoder

I'm doing a project which requires me to use an faulhaber encoder,and the one i have is a 2channel 16lines per revolution.
I haven't worked with encoders before and based on what i found the lines per revolution mean how many pulses i get for each revolution and so in my code i used an interrupt and counted the times my channel A changed till it got to 32 counting once for every high to low and once for every low to high for my 16 pulses which then by my belief means that I've had one revolution but when i test the code after around like 1/6 of a spin my counter reaches 32 and I'd appreciate if someone can tell me where I'm going wrong with this .

This is the datasheet of the encoder I'm using [IE2_16][1] .

**here is the code :**

    volatile long int ticks = 0 ;
    unsigned long int rev = 0 ;
    const int channelA = 2 ;
    void setup(){
       Serial.begin(9600);
       pinMode(6,OUTPUT);
       pinMode(7,OUTPUT);
       pinMode(8,OUTPUT);
       pinMode(channelA,INPUT);
       attachInterrupt(digitalPinToInterrupt(channelA), numCunts,  CHANGE);
       digitalWrite(7,LOW);
       digitalWrite(8,HIGH);
       analogWrite(6,15);
    }
    void loop(){
           Serial.println(rev);

        if(ticks>=32){
           ticks = 0;
           rev++;

          }
    }

    void numCunts(){
      ticks+=1 ;
      }

  [1]: https://www.faulhaber.com/fileadmin/Import/Media/EN_IE2-16_DFF.pdf

body:
No, there are several problems with your decoding. First, you are detecting every change. You want to detect only rising or falling edge changes.

Second, the changes are likely noisy, so you need to write your decoder to "debounce" the readings. With a 2-channel encoder like you're using, the usual way to do that is to only respond to rising edge changes on channel A after you've seen a rising edge change on channel B, and visa-versa.

See this link for a description of how they work: http://www.creative-robotics.com/quadrature-intro

I tried my hand at writing my own decoder, but it's harder than you might think to get it right. I'd suggest using somebody else's rotary encoder library.

And a quick google search revealed this library on github: https://github.com/PaulStoffregen/Encoder

(I don't know if it's any good or not. It's the first hit I found.)


message:
Where do class files go in Sloeber Eclipse project?

I'm attempting to create a new Arduino project using Sloeber (Eclipse). Assume it's a newly-created project whose main entry file is ".\ArduinoMainClass.ino"

Now... assume I want to create a half dozen new classes:

* ExecutionState-- a C++ class that's intended to be functionally equivalent to a Java Interface. If you're wondering, I'm attempting to implement the 'State' pattern.

* GoodState, BadState, UglyState, WeirdState-- C++ classes that all extend ExecutionState. If they were Java, they'd technically be implementing an interface... but since this is C++ and I'm still taking baby steps, for now ExecutionState is just a class with one method that does nothing, and all of THESE classes override it to do the actual work.

* StateContainer-- a C++ class whose only purpose in life is to hold single instances of GoodState, BadState, UglyState, and WeirdState. If this were Java, they'd be Singletons... GoodState (and the others) would have something like:
~~~
    private static ExecutionState instance = new GoodState();
    // ...
    public static ExecutionState getInstance() { return instance; }
~~~

... but it's obviously not Java,  and I'm nowhere close to knowing enough about C++ to properly implement static singletons yet, so for now, I'm just going to create an instance of StateContainer to create and hold those single instances.

So... I now have Sloeber/Eclipse loaded, and I've created my project. If this were Java, I'd create a subdirectory like .\src\java\com\packagename\executionstate and stick the .cpp and .hpp files for ExecutionState, GoodState, BadState, UglyState, WeirdState, and StateContainer in it, and add "include com.packagename.executionstate.*" to it.

* I know C++ namespaces have no direct connection to directory names
* I've gotten the impression that "Arduino"-ish C++ auto-generates the #include files for things it regards as libraries. I have a hunch that I probably want to put all of the classes I mentioned above in a directory somewhere and present them to the IDE as an Arduino "library" so they'll all get implicitly included in one go within the .ino file.
* I'm completely confused about what I need to #include in the classes I mentioned above so they can mutually find each other... and whether those #includes rightfully belong in the .hpp or .cpp files.

So... getting back to the big picture. If my project is in c:\users\moi\Documents\Slober-workspace\FirstSloeberArduinoApp...

1. Where do the .cpp and .hpp files for ExecutionState, GoodState, BadState, UglyState, WeirdState, and StateContainer go? (Assume I'd be inclined to put them all in a directory named "executionstates" somewhere in the project's directory hierarchy, but I'm not sure where that exact directory should go).

2. What #includes do I need to put in ExecutionState, Good/Bad/Ugly/WeirdState, and StateContainer... and do they go in the .hpp file, or the .cpp file for their respective class?

3. What do I have to do so the .ino file can find StateContainer?

In case you're totally confused at this point, my actual .ino file will look something like this:

    void setup() {
        // executionStates is a global variable declared higher up
        executionStates = new StateContainer();
        executionState = executionStates.getGoodState();
        // StateContainer's constructor itself creates instances of the various subclasses of ExecutionState,
       // and passes references to itself to their constructors so they can
       // get the references to the others states as they need to return them.
    }

    void loop() {
        executionState = executionState->doSomething();
        /* executionState holds a pointer to an instance of an ExecutionState subclass.
           Each time doSomething() executes, it returns a pointer to its new state
         */
    }

... and in reality, there will be dozens of subclasses of ExecutionState, each representing a unique execution state.

body:
With Sloeber Eclipse plugin the ino files go to root of the project and the cpp, c and h files can be in root or in subfolders. example:

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

Folders created by Sloeber: `core` subfolder is a virtual folder with links to Arduino core files and variant files of the selected board. `libraries` folder is a virtual folder with links to libraries selected for the project. `Release` folder contains the generated make file, the .o files and the resulting elf, hex, bin files. (And sloeber.ino.cpp is a file generated by Sloeber)

Project folders: `data` folder in example picture is a convention for a folder with esp8266 SPIFFS files. `utility` is a subfolder with additional source files of the project.

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


body:
I put my class files, [class].cpp and [class].h, in the same folder as my project.ino file, at least during development. Then, if they're sufficiently general, I'll move them to [workspace]/libraries/[class]/ for future use.

But even if they're only for this project (so they might as well stay in the project's source code folder), it's good organization to keep them in their own files, since by nature, classes only expose their interfaces, not their "guts".


message:
SIM800L is not registering on network

I'm testing SIM800L module by registering to network manually and I'm getting an `error` message.
Here are the commands I tried.

    AT+CSQ

    +CSQ: 31,0

    OK

    AT+CBAND?

    +CBAND: EGSM_MODE,ALL_BAND

    OK

    AT+COPS=?

    +COPS: (1,"Bharat Karnataka","CellOne","40471"),(2,"Airtel","AIRTEL","40445"),(3,"Hutch-Kamataka","HUTCH","40486"),,(0-4),(0-2)

    OK

    AT+COPS=1,1,"40471"

    ERROR

`AT+COPS=1,1,"40471"`  is this command right? My
SIM card is CellOne and it's 4G.

Power supply -7.4 li-ion 1100mAh battery with an adjustable 5V-5A buck converter(3.8v is supplied to SIM800L)

body:
For the `AT+COPS` command you are setting manual with long alphanumeric network name but then using the numeric network name. Try `AT+COPS=1,2,"40471"`

[REF](https://m2msupport.net/m2msupport/atcops-plmn-selection/)

```
//Manually select T-mobile as carrier using short format alphanumeric network name
AT+COPS=1,0,"TMO"

//Manually select T-mobile as carrier using long format alphanumeric network name
AT+COPS=1,1,"T-Mobile USA"

//Manually select T-mobile as carrier using numeric network name
AT+COPS=1,2,"310260"
```

---

`AT+CSQ` checks the signal strength, you can check the reply range with a question mark,

```
AT+CSQ=?

+CSQ: (0-31,99),(0-7,99)

OK
```

The first number, 31, shows you have a good signal strength locally.

---

`AT+CBAND?` shows the mobile operating band set

---

`AT+COPS=?` will search for networks, your response indicates you found a few.


message:
Problems integrating Reed Switch and Solenoid Lock in Arduino Code

I am trying to integrate solenoid lock, reed switch in my Arduino Code. The flow that I am trying to achieve is - first, the solenoid lock is set to LOW and then the program checks if reed switch is High or Low. Only if its High I want to proceed further. However, even when the reed switch is HIGH the program is not executing further. Here is my code below:

        #include<HX711_ADC.h>
        #include<math.h>

        //pins for lock
        int solenoidPin = 7;

        //pins for reed switch
        int reedSwitch = 2;
        bool reedSwitchStatus;

        //pin for led
        int led_pin= 9;

        void setup()
        {
          Serial.begin(38400);
          pinMode(solenoidPin, OUTPUT);
          pinMode(reedSwitch, INPUT);

          doorUnlock();
        }

        void loop()
          {}

        void doorUnlock()
        {
          digitalWrite(solenoidPin, LOW);
          delay(5000);
          checkReedSwitchStatus();
        }

        void checkReedSwitchStatus()
        {
          reedSwitchStatus = digitalRead(reedSwitch);

          if(reedSwitchStatus == 1)
          {
            Serial.println("Beginning Transaction");
            beginTransaction();
            }
          if (reedSwitchStatus == 0)
            {
              Serial.println("Ending trasaction");
              endTransaction();
              }
          }
          void beginTransaction()
          {
          digitalWrite(led_pin, HIGH);
          delay(500);
          digitalWrite(led_pin, LOW);
          delay(500);
          }

My issue is the beginTransaction function is never executed. Serial monitor continuously prints 'Beginning Transaction'. Attached the screenshot of the serial monitor. Please suggest me what is the error in my code. Thanks in advance!
[![enter image description here][1]][1]

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

body:
The problem is, that you don't initiate the LED's pin to an output. On reset the pin is configured as input. Doing a `digitalWrite(led_pin, HIGH)` in this state just enables the internal pullup resistor. If you measure the voltage without the LED connected, it will be 5V, but since the pin only provides a very small amount of current through the pullup resistor, the LED cannot light up when connected.

You need to configure the LED's pin as an output through

    pinMode(led_pin, OUTPUT);

in your `setup()` function.

So actually the `beginTransaction()` function was correctly executed. You just couldn't see it.


message:
Connecting Peltier module to Arduino Nano

I am a beginner to Arduino programming and started working on my first Arduino project recently to power a Peltier cooling pad. Below is the code I used and in the circuit,
I connected the positive (red wire) end of the Peltier to D12 of Nano Arduino board and the negative end( black wire) to the negative end of the 6V battery. Then I powered the Arduino board by connecting Vin(Arduino) and battery(+) using a jumper wire. The GND pin of the Arduino was connected to the battery(-) using a jumper wire.

The Peltier is not working and it would be a great help if someone can help me to understand what I did wrong.

```c++
int p=12;

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

void loop() {
   digitalWrite(p,HIGH);
   delay(2000);
}
```

body:
I prepared a little circuit that should help you safely connect the Peltier module to Arduino. It uses a single n-channel MOSFET and 1K resistor.

I couldn't find any Peltier in Tinkercad so instead I used a simple light bulb. (In previous version of this answer I used a DC motor, but it was not a good replacement for Peltier module)

When Arduino Pin12 is HIGH light is bright (high current flows through it just like it should through the Peltier) when Pin12 is LOW light bulb goes dark (no current is flowing)

[![circuit][1]][1]

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


message:
Is std::array (from the C++ STL) safe to use on arduino? Does it use dynamic memory allocation?

I'd like to use std::array on a project that will need to be very stable, and have all memory pre-allocated to avoid heap fragmentation.

I am reading in characters from the serial port, following a known protocol. Each received byte will be written to a char array of ample size to hold the longest possible string I will receive. I will then perform some minor on the fly operations, (i.e. skipping certain characters, replacing one with another, etc.) and write those out another serial port.

This device needs to function indefinitely. I will not be calling malloc or new anywhere in my code. All of my control objects are singletons, (audible gasp from the high-level crowd!) created during setup, and never being destroyed.

Is the STL array template safe to use in this context?

After reading [this post][1], and [this post][2], the only potential issues I can see are exception handling. As far as I'm concerned, an exception is as fatal as an access violation. I would not expect to ever attempt recovery from an exception, so I don't care that Arduinos don't support them.

But what will happen if the program tries to throw one? Will the arduino compiler even allow the use std::array if it supports exceptions? Is there an Arduino-friendly array template that uses fixed size arrays and supports iterators?

Thanks!

  [1]: https://embeddedartistry.com/blog/2017/6/28/an-introduction-to-stdarray
  [2]: https://www.modernescpp.com/index.php/std-array-dynamic-memory-no-thanks

body:
`std::array` does not use dynamic memory allocations to store its elements. If you use static or stack-allocated `std::array`s, you don't have to worry about memory fragmentation (contrary to `std::vector` or `String`, for example).
Of course, if you allocate arrays on the stack, you can have a stack overflow if you call too many functions, either by design, or because of a bug.

That brings us to the problem of exceptions. If you look in the standard, you'll see that most of the member functions of `std::array` are marked `noexcept`, with the notable exception of the element accessors. Obviously, the `at()` accessor can throw, but you'd expect that `operator[]` doesn't.
In practice, `operator[]` is marked `noexcept` in the version of the STL (GCC9) that I have on my computer, so if you check it in the STL implementation you're using, you can be pretty confident that it won't throw. Just keep in mind that this is not mandated by the standard.

**/usr/include/c++/9/array**

```
      // Element access.
      _GLIBCXX17_CONSTEXPR reference
      operator[](size_type __n) noexcept
      { return _AT_Type::_S_ref(_M_elems, __n); }

      constexpr const_reference
      operator[](size_type __n) const noexcept
      { return _AT_Type::_S_ref(_M_elems, __n); }
```

The debug version is also marked `noexcept`, but it can throw/abort if the index is out of bounds:

**/usr/include/c++/9/debug/array**
```
      // Element access.
      _GLIBCXX17_CONSTEXPR reference
      operator[](size_type __n) noexcept
      {
 __glibcxx_check_subscript(__n);
 return _AT_Type::_S_ref(_M_elems, __n);
      }

      constexpr const_reference
      operator[](size_type __n) const noexcept
      {
 return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
  : (_GLIBCXX_THROW_OR_ABORT(_Array_check_subscript<_Nm>(__n)),
     _AT_Type::_S_ref(_M_elems, 0));
      }
```

The STL implementations for Arduino I found online don't seem to have the `<array>` header.

Luckily, you can easily create your own array container, for example:

```cpp
template <class T, size_t N>
struct Array {
    // Storage
    T data[N];

    static size_t length() { return N; }
    using type = T;

    // Item access
    T &operator[](size_t index) { return data[index]; }
    const T &operator[](size_t index) const { return data[index]; }

    // Iterators
    T *begin() { return &data[0]; }
    const T *begin() const { return &data[0]; }
    T *end() { return &data[N]; }
    const T *end() const { return &data[N]; }

    // Comparisons
    bool operator==(const Array<T, N> &rhs) const {
        if (this == &rhs)
            return true;
        for (size_t i = 0; i < N; i++)
            if ((*this)[i] != rhs[i])
                return false;
        return true;
    }
    bool operator!=(const Array<T, N> &rhs) const {
        return !(*this == rhs);
    }
};

void setup() {
  Serial.begin(115200);
  while (!Serial);

  // Create an array
  Array<int, 5> myArray = {1, 2, 3, 4, 5};
  // On older compilers, use double braces:
  //    Array<int, 5> myArray = {{1, 2, 3, 4, 5}};

  // Iterate over the array
  for (int element : myArray)
    Serial.println(element);

  // Access elements of the array
  myArray[2] = 30;
  Serial.println(myArray[2]);
}

void loop() {}
```


message:
ADS1115, ACS712 and ESP8266

I have an ACS712 (5v sensor), an ADS1115 (5 or 3.3v) and an ESP8266 board (3.3v).

I know I can't directly use the ACS with the ESP without a voltage divider on the analog pin. So I figured I could run the ADS and the ACS off 5 volts as the ADS communicates over I2C. Does this cause any issues with the SDA/SCL lines on the ESP?

What is the correct way in going about this?

body:
The SDA line of of ADS1115 will use 3.3 V if you power it with 3.3 V, but then the maximum analog input voltage would be 3.6 V (VDD + 0.3 V).

The ACS712 has the middle value at 2,5 V so to read it you need the 5 V range and must power the ADS1115 from 5 V. Then the SDA line of esp8266 will be connected to 5 V logic level, but the esp8266 pins can handle 5 V TTL communication currents.

The SCL line is driven from master (esp8266) at 3.3 V and the ADS1115 is good with it.


message:
UART communication - Serial is always empty

I have a payment terminal which uses UART (or simply speaking `Rx`, `Tx`, `Gnd` pins) and I have an `Android` tablet app which is connected to the terminal using `USB` to `DB9` adapter based on `PL2303` chip. The Android app works well and it uses https://github.com/felHR85/UsbSerial to support serial communication. The protocol is very simple, basically Android sends strings like "*REQINFO,4*", "*L2,xxx,xxx,*\*" etc. and recieves back a string statuses.

I'm trying to replace Android app with `Arduino UNO`, for which I naively assumed would be enough just to connect `Tx`,`Rx` of the terminal with `Rx`,`Tx` pins of the Arduino and also to connect `Gnd` pins. But I can't get it working. The only thing I noticed is when I connect Arduino `Rx` to terminal `Tx`, the terminal's screens briefly shows "Connecting..." but that's probably because it detects some incoming voltage. When it comes to reading `Serial` (or also I tried `SoftwareSerial`) nothing is ever returned.

```
String data = "";

void setup() {
  Serial.begin(9600);
  while (!Serial);
  delay(1000);
  Serial.println("REQINFO,4");
  delay(1000);
}

void loop() {
  if (Serial.available())  {
    char c = Serial.read(); // also I tried readString() and readStringUntil()
    if (c == '\n' || c == '\r') {
      Serial.println(data); // jsut to see it in the montor
    } else {
      data += c;
    }
  }
}
```

So do I miss anyting in order to have a proper communication? Thanks.

body:
Check (e.g. with a multimeter) the DB9 voltages! Mostly RS-232 is used on those kind of connectors with voltages +-12Volts (there are other variants as well, up to 15V), but your Arduino's UART uses TTL levels (0V as logic low or 5V as high on a 5V Arduino). You'll need to convert these, possibly with a chip like MAX232 or similar.

Also, for reverse engineering this I recommend using an Arduino with multiple serial ports (e.g. Mega), or at least multiple software serials (with proper level shifting of course). You connect your Android tablet to your reader through your Arduino, and when you receive a byte from one device, send it to the other one, and also send it to your PC along with the information about direction. This way you can understand all the used commands if you sniff long enough. You could also use an SD card on SPI if you need your sniffer system to be mobile (walking in a warehouse scanning items).

If you have access to a logic analyzer, it can also be used as a sniffer. This has an additional advantage, you can change BAUD rates later if your guess was wrong.

(started as a comment but ran out of characters, so I thought I'll explain it a bit more)

https://www.db9-pinout.com/db9-pinout/db9-pinout.gif[![pinout][1]][1]

If it's a standard cable for RS-232, this diagram shows which pin is which. DCE-DCE and DCE-DTE cables were different back then (one connects a PC to a modem, the other 2 PCs), so you should check both voltages from 5 (GND) to either 2 or 3. An empty line has logic high, which is 5V in case it uses TTL, and -5 or lower (like -12 or -15) for RS-232.

Test different BAUD rates as well!

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


body:
There is already an answer and comment about possible hardware / flow control issues, so this answer is only dealing with your Arduino sketch. Iv’e added a couple of print statements and the `FreeMemory` library to test your sketch.

    #include <MemoryFree.h>
    String data = "";

    void setup() {
      Serial.begin(9600);
      while (!Serial);
      delay(1000);
      Serial.println("REQINFO,4");
      delay(1000);
    }

    void loop() {
      if (Serial.available())  {
        char c = Serial.read(); // also I tried readString() and readStringUntil()
        if (c == '\n' || c == '\r') {
          Serial.println(data); // jsut to see it in the montor
          Serial.print("freeMemory()=");
          Serial.println(freeMemory());
        } else {
          data += c;
        }
      }
    }

When I repeatedly enter the following text in the serial monitor "1234567890", here is the results of the print statements:

    REQINFO,4
    1234567890
    freeMemory()=1770
    1234567890
    freeMemory()=1770
    12345678901234567890
    freeMemory()=1760
    12345678901234567890
    freeMemory()=1760
    123456789012345678901234567890
    freeMemory()=1750
    123456789012345678901234567890
    freeMemory()=1750
    1234567890123456789012345678901234567890
    freeMemory()=1740
    1234567890123456789012345678901234567890
    freeMemory()=1740
    12345678901234567890123456789012345678901234567890

Every time you receive new data, it is appended to the `data` string, causing the string to grow and available memory to disappear. Using the `String` object should be avoided.

Here is a simple sketch that uses a `char` array as a buffer for the incoming data:

    // Set the buffer size to accomodate the largest
    // "chunk" of data you will be receiving.
    const byte bufferSize = 64;
    char inputBuffer[bufferSize + 1];

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

    void loop(){
      if(Serial.available() > 0){
        Serial.readBytesUntil('\n', inputBuffer, bufferSize);
        Serial.print("inputBuffer=");
        Serial.println(inputBuffer);
        memset(inputBuffer, 0, sizeof(inputBuffer));
      }
    }


message:
Can I connect esp32 to a phone USB charger?

I have a USB charger. Is it ok to connect it as a power supply for esp32?

Edit: i have a dev board esp32

![enter image description here](https://i.stack.imgur.com/6LM8z.jpg)

body:
In principle yes (see also comment in update).

The voltage is ok (5V), typically USB, and it doesn't differ from the output of a computer USB port.

The output current is max 2000 mA, so check if your project (ESP + related hardware powered by this USB), is not exceeding 2000 mA. The ESP needs much less than 2000 mA, so if you didn't have a lot of external components or motors than you will be safe.

**Update**

Important omment from Sim Sson: The bare esp32 is not 5V-tolerant, so using a usb-charger is only ok for esp modules that have a voltage regulator onboard.


message:
LCD screen won't stop printing the same characters twice

I'm hoping that someone might be able to help me figure out how to prevent my LCD from giving me double digits (i.e. 55, 66, 77 - instead of 5,6,7);

I have 2 functions that are printing, so I'm expecting the issue to be related to this.

Here's the code:

    #include <Wire.h>

    #include <Adafruit_LiquidCrystal.h>
    #include <Keypad.h>

    unsigned int deBounce = 100;
    int curs = 0;

    Adafruit_LiquidCrystal lcd(8, 9, 3, 10, 11, 12, 13);

    const byte numRows = 4; //number of rows on the keypad
    const byte numCols = 4; //number of columns on the keypad

    char keymap[numRows][numCols] =
    {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'.', '0', '#', 'D'}
    };

    char keymap2[numRows][numCols] =
    {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'.', '0', '#', 'D'}
    };

    //Code that shows the the keypad connections to the arduino terminals
    byte rowPins[numRows] = {25, 27, 29, 31};
    byte colPins[numCols] = {17, 19, 21, 23};

    //initializes an instance of the Keypad class
    Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
    Keypad myKeypad2 = Keypad(makeKeymap(keymap2), rowPins, colPins, numRows, numCols);

    char enteredDigits[10]  = " ";//null terminated character array to hold entry
    char enteredDigits2[10]  = " ";//null terminated character array to hold entry
    boolean entryComplete = false;
    boolean entryComplete2 = false;
    boolean first = 0;

    float result; // Create an integer for the result of 'A' and 'B' (in this case, it will be the 'Inductance' x 'Capacitance')
    float power = .5; // Used in the equation
    float r1; // Result 1
    float r2; // Result 2
    float r3; // Result 3
    float r4; // Result 4
    float fc; // Result 5
    float power2 = 6; // Used in the last part of the equation
    float result2 = 10; // Also used in the last part of the equation
    #define TWO_PI 6.283185307179586476925286766559 // two Pi (:
    float num1;
    float num2;

    void setup()
    {
      myKeypad.setDebounceTime(deBounce);
      myKeypad2.setDebounceTime(deBounce);

      lcd.begin(16, 2);
    }

    void loop()
    {
      getNumber();
      if (entryComplete)
      {
        entryComplete = false;
        lcd.setCursor(0, 1);
        num1 = atof(enteredDigits);
        first = 1;
      }

      if (first == 1) {
        getNumber2();
        if (entryComplete2)
        {
          entryComplete2 = false;
          lcd.setCursor(0, 1);
          num2 = atof(enteredDigits2);
          values();
          first = 0;
        }
      }
    }

    void getNumber()
    {
      static byte index = 0;
      char key = myKeypad.getKey();
      if (key != NO_KEY)
      {
        switch (key)
        {
          case '0': case '1': case '2': case '3': case '4':
          case '5': case '6': case '7': case '8': case '9': case'.':
            lcd.print(key);//print entry on top row
            enteredDigits[index] = key;//build character string
            index++;
            enteredDigits[index] = '\0'; //null terminate
            break;

          case '#':
            lcd.setCursor(8, 0);
            lcd.print(F("= Ind."));
            delay(1000);
            entryComplete = true;
            index = 0;//reset for next entry
            break;

          case 'D'://clear entry and display
            memset(enteredDigits, '\0', 10); //clear buffer
            lcd.clear();
            index = 0;
            entryComplete = false;
            break;
        }
      }
    }

    void getNumber2()
    {
      static byte index2 = 0;
      char key2 = myKeypad2.getKey();
      if (key2 != NO_KEY)
      {
        switch (key2)
        {
          case '0': case '1': case '2': case '3': case '4':
          case '5': case '6': case '7': case '8': case '9': case'.':
            lcd.print(key2);//print entry on top row
            enteredDigits2[index2] = key2;//build character string
            index2++;
            enteredDigits2[index2] = '\0'; //null terminate
            break;

          case '#':
            lcd.setCursor(8, 1);
            lcd.print(F("= Cap."));
            delay(1000);
            entryComplete2 = true;
            index2 = 0;//reset for next entry

            break;

          case 'D'://clear entry and display
            memset(enteredDigits2, '\0', 10); //clear buffer
            lcd.clear();
            index2 = 0;
            entryComplete2 = false;
            break;
        }
      }
    }

    void values() {

      result = num1 * num2; // If a 'comma' key is pressed (in this case, the # key on a 4x4 keypad)

      lcd.clear(); // Clear the writing from the LCD
      lcd.setCursor(0, 0); // Set the cursor position to the first block on the first line
      lcd.print(F("Ind. =")); // Display 'Ind. =' onto the LCD Screen
      lcd.setCursor(7, 0); // Set the cursor position to display after the previous text
      lcd.print(num1, 4); // Display the number value given to num1
      lcd.setCursor(0, 1); // Set the cursor for the first block on the second line
      lcd.print(F("Cap. ="));// Display 'Cap. =' onto the LCD Screen
      lcd.setCursor(7, 1); // Set the cursor position to display after the previoust text
      lcd.print(num2, 2); // Display the number value given to num2
      delay(2500);

      r1 = pow(result, power);
      r2 = r1 * TWO_PI;
      r3 = 1 / r2;
      r4 = pow(result2, power2);
      fc = r3 * r4;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("Res. Peak =")); // Display the answer onto the LCD Screen
      lcd.setCursor(0, 1);
      lcd.print(fc);
      lcd.setCursor(9, 1);
      lcd.print(F("(Hz)"));
    }

body:
You need to break your code into parts and debug it part by part. Start by printing a single character to the LCD once, and setting a bool so you don't do it repeatedly. If that works, the LCD is not your problem.

As DataFiddler suggested, bounce problems with your switch seem like a likely culprit. Add serial print statements to your button handling code and see if it's being triggered more than once. If so, research debouncing code.


body:
I had to remove this line from the getNumber2 function!

lcd.print(key2);

works now (: