message:
Elements excluded from buffer array output after given structure (ESP8266 WifiSniffer) (snifferPacket)

I am currently trying to determine how the [ESP8266 WifiSniffer program by Kalanda][1] works.

Here is the source code:

    #include <Arduino.h>

    extern "C" {
      #include <user_interface.h>
    }

    #define DATA_LENGTH           112

    #define TYPE_MANAGEMENT       0x00
    #define TYPE_CONTROL          0x01
    #define TYPE_DATA             0x02
    #define SUBTYPE_PROBE_REQUEST 0x04

    struct RxControl {
    //THESE HAVE AN EFFECT
    // signed rssi:8; // signal intensity of packet
    // unsigned rate:4;
    // unsigned is_group:1;
    // unsigned:1;
    // unsigned legacy_length:12; // if not 11n packet, shows length of packet. NOT THIS
    // unsigned MCS:7; // if is 11n packet, shows the modulation and code used (range from 0 to 76)
    // unsigned Smoothing:1;
    // unsigned Not_Sounding:1;
    // unsigned:1;
    // unsigned Aggregation:1;
    // unsigned STBC:2;
    // unsigned rxend_state:8;
    // unsigned ampdu_cnt:8;
    // unsigned channel:4; //which channel this packet in.

    //THESE HAVE NO EFFECT
    // unsigned sig_mode:2; // 0:is 11n packet; 1:is not 11n packet;
    // unsigned damatch0:1;
    // unsigned damatch1:1;
    // unsigned bssidmatch0:1;
    // unsigned bssidmatch1:1;
    // unsigned CWB:1; // if is 11n packet, shows if is HT40 packet or not
    // unsigned HT_length:16;// if is 11n packet, shows length of packet. NOT THIS
     //unsigned FEC_CODING:1; // if is 11n packet, shows if is LDPC packet or not.
     //unsigned SGI:1;
     //unsigned:12; //HAS NO EFFECT
    };

    struct SnifferPacket{
        struct RxControl rx_ctrl; //RxControl is just a name, can be named anything (as long as you change other things)
        uint8_t data[DATA_LENGTH]; //DOES NOT HAVE EFFECT
    //    uint16_t cnt; //THIS HAS NO EFFECT
    //    uint16_t len; //THIS HAS NO EFFECT
    };

    // Declare each custom function (excluding built-in, such as setup and loop) before it will be called.
    // https://docs.platformio.org/en/latest/faq.html#convert-arduino-file-to-c-manually
    //static void showMetadata(SnifferPacket *snifferPacket);
    //static void sniffer_callback(uint8_t *buffer, uint16_t length);
    static void printDataSpan(uint16_t start, uint16_t size, uint8_t* data);
    static void getMAC(char *addr, uint8_t* data, uint16_t offset);
    void channelHop();

    /**
     * Callback for promiscuous mode
     */
    static void sniffer_callback(uint8_t *buffer, uint16_t length) {

      struct SnifferPacket *snifferPacket;
      snifferPacket = (struct SnifferPacket*) buffer;

      Serial.print("buffer size: ");
      Serial.print(sizeof(buffer));

      Serial.print(" length size: ");
      Serial.print(sizeof(length));

      Serial.print(" snifferPacket size: ");
      Serial.print(sizeof(snifferPacket));

      Serial.print(" START OF BUFFER OG: ");
      for (int i = 0; i < 20; i++){
        Serial.print((unsigned int) buffer[i], BIN);
        Serial.print(" ");
      }
      Serial.print(" END OF BUFFER OG ");

      showMetadata(snifferPacket);
    }

    static void showMetadata(SnifferPacket *snifferPacket) {

      unsigned int frameControl = ((unsigned int)snifferPacket->data[1] << 8) + snifferPacket->data[0];

      uint8_t version        = (frameControl & 0b0000000000000011) >> 0;
      uint8_t frameType      = (frameControl & 0b0000000000001100) >> 2;
      uint8_t frameSubType   = (frameControl & 0b0000000011110000) >> 4;
      uint8_t toDS           = (frameControl & 0b0000000100000000) >> 8;
      uint8_t fromDS         = (frameControl & 0b0000001000000000) >> 9;
      uint8_t moreFragments  = (frameControl & 0b0000010000000000) >> 10;
      uint8_t retry          = (frameControl & 0b0000100000000000) >> 11;
      uint8_t powerMgmt      = (frameControl & 0b0001000000000000) >> 12;
      uint8_t moreData       = (frameControl & 0b0010000000000000) >> 13;
      uint8_t protectedFrame = (frameControl & 0b0100000000000000) >> 14;
      uint8_t htcOrder       = (frameControl & 0b1000000000000000) >> 15;

      Serial.print(" START OF BUFFER: ");
      for (int i = 0; i < 20; i++){
        Serial.print((unsigned int)snifferPacket->data[i], BIN);
        Serial.print(" ");
      }
      Serial.print(" END OF BUFFER ");

      Serial.print(" DATASPAN START: ");
      printDataSpan;
      Serial.print(" DATASPAN END ");

      Serial.print(" frameControl: ");
      Serial.print(frameControl);

      Serial.print(" version: ");
      Serial.print(version);

      Serial.print(" Type: ");
      Serial.print(frameType);

      Serial.print(" frameSubType: ");
      Serial.print(frameSubType);

      Serial.print(" toDS: ");
      Serial.print(toDS);

      Serial.print(" fromDS: ");
      Serial.print(fromDS);

      Serial.print(" moreFragments: ");
      Serial.print(moreFragments);

      Serial.print(" retry: ");
      Serial.print(retry);

      Serial.print(" powerMgmt: ");
      Serial.print(powerMgmt);

      Serial.print(" moreData: ");
      Serial.print(moreData);

      Serial.print(" protectedFrame: ");
      Serial.print(protectedFrame);

      Serial.print(" htcOrder: ");
      Serial.print(htcOrder);

      Serial.print(" Ch: ");
      Serial.print(wifi_get_channel());

    //  Serial.print(" rssi: ");
    //  Serial.print(snifferPacket->rx_ctrl.rssi, BIN);

    //  Serial.print(" RSSI: ");
    //  Serial.print(snifferPacket->rx_ctrl.rssi, DEC);

      //Only look for probe request packets
    //  if (frameType != TYPE_MANAGEMENT ||
    //      frameSubType != SUBTYPE_PROBE_REQUEST)
    //        //Serial.println();
    //        return;

    //  Serial.print(" RSSI: ");
    //  Serial.print(snifferPacket->rx_ctrl.rssi, DEC);

      Serial.print(" Ch: ");
      Serial.print(wifi_get_channel());

      char addr[] = "00:00:00:00:00:00";
      getMAC(addr, snifferPacket->data, 10);
      Serial.print(" Peer MAC: ");
      Serial.print(addr);

    //  uint8_t SSID_length = snifferPacket->data[25];
    //  Serial.print(" SSID: ");printDataSpan
    //  printDataSpan(26, SSID_length, snifferPacket->data);

      Serial.println();
    }

    static void printDataSpan(uint16_t start, uint16_t size, uint8_t* data) {
      for(uint16_t x = start; x < DATA_LENGTH && x < start+size; x++) {
        Serial.print(data[x]);
        //Serial.write(data[x]);
      }
    }

    static void getMAC(char *addr, uint8_t* data, uint16_t offset) {
      sprintf(addr, "x:x:x:x:x:x", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5]);
    }

    #define CHANNEL_HOP_INTERVAL_MS   100
    static os_timer_t channelHop_timer;

    /**
     * Callback for channel hoping
     */
    void channelHop()
    {
      // hoping channels 1-13
      uint8 new_channel = wifi_get_channel() + 1;
      if (new_channel > 13) {
        new_channel = 1;
      }
      wifi_set_channel(new_channel);
    }

    #define DISABLE 0
    #define ENABLE  1

    void setup() {
      // set the WiFi chip to "promiscuous" mode aka monitor mode
      Serial.begin(115200);
      //delay(10);
      wifi_set_opmode(STATION_MODE);
      wifi_set_channel(1);
      wifi_promiscuous_enable(DISABLE);
      //delay(10);
      wifi_set_promiscuous_rx_cb(sniffer_callback);
      //delay(10);
      wifi_promiscuous_enable(ENABLE);

      // setup the channel hoping callback timer
      //os_timer_disarm(&channelHop_timer);
      //os_timer_setfn(&channelHop_timer, (os_timer_func_t *) channelHop, NULL);
      //os_timer_arm(&channelHop_timer, CHANNEL_HOP_INTERVAL_MS, 1);
    }

    void loop() {
      //delay(10);
    }

I have noticed the `Serial.print` output directly from the `buffer` differs to the `Serial.print` output for the variable `snifferPacket` which is given attributes of the struct `RxControl`.

When the code is configured as normal, the raw buffer output (BUFFER OG) has 12 additional elements compared to the snifferPacket (BUFFER) output.
Here is an example:

    buffer size: 4 length size: 2 snifferPacket size: 4 START OF BUFFER OG: 10100010 10000 11100110 1010000 0 0 0 0 0 0 1 0 10000000 0 0 0 11111111 11111111 11111111 11111111  END OF BUFFER OG  START OF BUFFER: 10000000 0 0 0 11111111 11111111 11111111 11111111 11111111 11111111 11011000 111 10110110 11010 10100010 1000001 11011000 111 10110110 11010  END OF BUFFER  DATASPAN START:  DATASPAN END  frameControl: 128 version: 0 Type: 0 frameSubType: 8 toDS: 0 fromDS: 0 moreFragments: 0 retry: 0 powerMgmt: 0 moreData: 0 protectedFrame: 0 htcOrder: 0 Ch: 1 Ch: 1 Peer MAC: d8:07:b6:1a:a2:41

Comparing just the two buffer outputs:

     - BUFFER OG: 10100010 10000 11100110 1010000 0 0 0 0 0 0 1 0 10000000 0
       0 0 11111111 11111111 11111111 11111111
     - BUFFER: 10000000 0 0 0 11111111 11111111 11111111 11111111...

I've been able to identify parts of the first 12 elements:

    1.  10100010 -> RCPI (RSSI) in two's complement format
    2.  10000    -> Unknown
    3.  11100110 -> Unknown
    4.  1010000  -> Unknown
    5.  0        -> Unknown, but constant
    6.  0        -> Unknown, but constant
    7.  0        -> Unknown, but constant
    8.  0        -> Unknown, but constant
    9.  0        -> Unknown, but constant
    10. 0        -> Unknown, but constant
    11. 1        -> Wi-Fi channel (in this example it's channel 1)
    12. 0        -> Unknown, but constant

These 12 elements come before the 802.11 packet (starting with the frame header which begins at 10000000)

Through trial and error, I've been able to the identify parts of the code that effect the snifferPacket output. These are:
 1. 14 attributes in the `RxControl` struct, titled as `THESE HAVE AN EFFECT`.

       a. Commenting between 1-8 of any attributes: The last 4 elements appear in the `snifferPacket` output (`0 0 1 0`)

       b. Commenting between 9-13 of any attributes: The last 8 elements appear in the `snifferPacket` output (`0 0 0 0 0 0 1 0`)

       c. Commenting all 14 attributes: The last 11 elements appear in the snifferPacket output (`10000 11100110 1010000 0 0 0 0 0 0 1 0`)

 2. `struct RxControl rx_ctrl;`, under `struct SnifferPacket`

    a. Commenting out: All 12 elements appear in the snifferPacket output (`10100010 10000 11100110 1010000 0 0 0 0 0 0 1 0`)

So it's clear that there is an association between defining attributes and their exclusion from the snifferPacket output.

Note that leading 0s are part of an element are ignored are part of the output. For example:

     - 0100 = 100
     - 0000 = 0
     - 1000 = 1000

 So my questions are:

 1. What do each of the 12 elements represent?
 2. Why is there a difference in the output between the output of the raw `buffer` and `snifferPacket`?
 3. Why do only certain attributes effect the output of `snifferPacket`?
 4. Why does commenting a greater number of attributes result in a greater number of elements reappearing, no matter which attributes are commented?

Thanks in advance.

  [1]: https://github.com/kalanda/esp8266-sniffer

body:
> What do each of the 12 elements represent?

Things in the header. That is off-topic for here.

> Why is there a difference in the output between the output of the raw buffer and snifferPacket?

snifferPacket is overlaid over the incoming buffer. That includes the "data" buffer which you are printing. The data buffer is only a portion of the snifferPacket.

> Why do only certain attributes effect the output of snifferPacket?

They are bit fields, and they are packed into bytes or words. The number and size of bit fields affects the number of bytes needed to contain them, and thus where in the structure the `data` array comes.

> Why does commenting a greater number of attributes result in a greater number of elements reappearing, no matter which attributes are commented?

See above. Also, the attributes must be there. Removing them will mean that other attributes don't point to the right bits in memory.

You should learn how C bit fields work. You can read more at the C++ reference [here](https://en.cppreference.com/w/cpp/language/bit_field).


sender: user

message:
how to use Nano instead of Uno3 to operate DC motors

OK I have the Logitech G29 Wheel and Pedal setup that I use for my Racing Sim. On YouTube there is a gentleman (amstudio) who has used motors on the Gas and Brake pedals to give some realism to the Sim. To achieve this he used a Uno 3 and a motor shield. The motors used are those that you'd find in the XBox/PS4 controllers. It's my understanding that the Uno 3, Nano and Micro are the same in its basic form, meaning that the sketch he uses can be used on all 3. If this is true then I want to use the smallest footprint to achieve the Rumble effect.

**Question** is how do I wire up the Nano to do this and with the motors as small as they are is it really necessary to have a motor shield or H bridges?

I have taken a picture of his Uno setup.  My aim here is to make it the smallest as it can be and still do the function of this mod' as this will be its only function. Any ideas on how best to go about this, The XBox Controller is rated at 5v @ 450mA. have included a picture showing his setup.thanks in advance![![enter image description here][1]][1]

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

sender: assistant

body:
> It's my understanding that the Uno 3, Nano and Micro are the same in its basic form

Not exactly. The Uno and Nano use the same chip (the Atmega328p) and have the same pins broken out. The Arduino Pro Mini also uses that chip, but I think the pinout is a bit different. But mostly a code can be reused between these boards. The Arduino Micro uses an ATmega32U4, which is a different chip. Depending on the actual code, you might not be able to just reuse the code. Then you might have to change to code to use the Micros hardware.

> with the motors as small as they are is it really necessary to have a motor shield or H bridges?

I would say yes. A digital output pin of an Arduino can only supply 20mA of current over longer time (absolute maximum 40mA). Even very small motors can easily exceed that. As long as you don't know the exact needed current in worst case (like stalling the motor), you should assume, that it is more than 20mA. Also a running motor generates a lot of electrical noise and the coils can induce backcurrents, that might destroy the output hardware of the Arduino pin (for that you need a flyback diode). And lastly, if you want to change the direction of the motor, you absolutely need an H-bridge. Otherwise it is only on or off.

> Question is how do I wire up the Nano to do this

With H-bridges you normally need 3 pins to control the motor:

- The enable pin (often marked as EN) enables or disables the motor (run or stop). You normally use `analogWrite(en_pin, speed)` to control the speed of the motor. It will send a PWM signal with the given duty cycle to the enable pin.
- And you have 2 input pins (often marked as IN). They give you control over the direction.
    - `IN1` to HIGH and `IN2` to LOW will give you the first direction. Reversing to `IN1` LOW and `IN2` HIGH will give you the other direction. This will cause the H-bridge to lead the current through the motor in different directions.
    - Setting them to the same value will cause the motor to break (because that will short circuit the motors coil).

So you would wire 3 output pins of the Arduino to the mentioned pins on the H-bridge. It is up to you, what you want to use here. You can use a shield (which is normally the size of the Uno), you can use other ready to use motor driver boards (there are many) or you could build your own driver with a H-bridge chip and flyback diode.


message:
SPI read while writing?

I'm working on a driver for an SPI device that returns some data (device status) while the command byte is still being written.  Is there a way to read this status data using standard Arduino APIs or do I need to bit-bang to access it?

Here's what the SPI signals look like:

[![SPI timing diagram][1]][1]

The 6 bits in red are the ones I'm interested in reading.

---

For context, the device in question is a Microchip [MCP3561 ADC](https://ww1.microchip.com/downloads/en/DeviceDoc/MCP3561-2-4-Two-Four-Eight-Channel-153.6-ksps-Low-Noise-24-Bit-Delta-Sigma-ADCs-DS20006181B.pdf) (MCP3X6X series).  [It has a bug](https://ww1.microchip.com/downloads/en/DeviceDoc/MCP3X5X-Family-Data-Sheet-Errata-DS80000845B.pdf) (erratum 2) where the new-data-ready flag (`/DR_STATUS`) is not always set correctly.  Part of the work-around involves reading the status bits mentioned above.

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

body:
[The `SPI.transfer()` method][spi] is designed to send a byte through
the SPI port and, _at the same time_ receive an incoming byte.

Usage pattern:

```c++
uint8_t byte_to_send = ...;
uint8_t received_byte = SPI.transfer(byte_to_send);
```

[spi]: https://www.arduino.cc/en/Reference/SPITransfer


message:
Issue using Arduino Mega Timer2 with PinChange Interrupt

I was working on a program to measure the pulse width , for that I thought of using Timer 2 in Arduino mega along with pin change interrupt,

The program I have written is as follows

```
volatile float ovfCount = 0;

typedef struct{
  float curr_ovfCount,prev_ovfCount;
  uint8_t curr_tcnt2, prev_tcnt2;
  uint16_t width;
  bool stateHigh = true;
}Pulse;

Pulse ch1, ch2, ch3, ch4, ch5, ch6;

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

  /*
   * Pin Change Interupt for
   * measuring the pulse width
   * from the receiver
   *
   */

  DDRK = 0; // A8:A15 -> direction as Input
  PORTK = B00111111; // A8:A15 -> pullupResistor

  PCICR = B00000100; // activating 2 nd PCINT
  PCIFR = 0; // resetting the flags
  PCMSK2 = B00111111; // activating from A8:21 :: 6

  /*
   * 8 bit timer setup for counting
   * timer 2 is used
   */
   TCCR2B=0x00;
   TCCR2A = 0x00; // wave generation is normal:: all zeros
   TCNT2 = 0x00;
   TIFR2 = 0x00; // resetting all flags
   TIMSK2 = 0x01; //timer overflow enable
   TCCR2B = 0x01; // no prescaling

}

ISR(TIMER2_OVF_vect){
  ovfCount++;
}

ISR(PCINT2_vect){
  float ovf_count = ovfCount;
  uint8_t tcnt2 = TCNT2;

  if( (PINK & 1 << PINK0) & ch1.stateHigh ){
    //Low-High
    ch1.prev_ovfCount = ovf_count;
    ch1.prev_tcnt2 = tcnt2;
    ch1.stateHigh = false;
  } else if( ! ((PINK & 1 << PINK0) & ch1.stateHigh)){
//    High-Low
    ch1.curr_ovfCount = ovf_count;
    ch1.curr_tcnt2 = tcnt2;
    ch1.width = (256.0*(ch1.curr_ovfCount - ch1.prev_ovfCount) + (ch1.curr_tcnt2 - ch1.prev_tcnt2) ) * 1000 / 16e6;
    ch1.stateHigh = true;
  }

}

void loop() {
  Serial.println(ch1.width);
  pinMode(13, OUTPUT);
  digitalWrite(13,!digitalRead(13));
  delay(1000);

}

```

and the output I am getting is ,

```
16:22:05.667 -> 0
16:22:05.847 -> 927
16:22:06.826 -> 927
16:22:07.820 -> 1001
16:22:08.847 -> 1001
16:22:09.837 -> 1001
16:22:10.843 -> 1001
16:22:11.835 -> 1002
16:22:12.863 -> 1002
16:22:13.871 -> 1002
16:22:14.854 -> 1002
16:22:15.873 -> 1003
16:22:16.875 -> 1003
16:22:17.887 -> 1003
16:22:18.860 -> 1003
16:22:19.875 -> 1003
16:22:20.867 -> 1003
16:22:21.907 -> 1003
16:22:22.895 -> 1003
16:22:23.922 -> 1008
16:22:24.921 -> 1008
16:22:25.938 -> 1008
16:22:26.922 -> 1008
16:22:27.939 -> 1008
16:22:28.961 -> 1008
16:22:29.946 -> 1008
16:22:30.971 -> 1008
16:22:31.993 -> 1008
16:22:32.974 -> 1008
16:22:34.011 -> 1008
16:22:35.016 -> 1008
16:22:36.026 -> 1008
16:22:37.012 -> 1008
16:22:38.024 -> 1008
16:22:38.939 -> 1008
16:22:39.802 -> 906
16:22:40.638 -> 906
16:22:41.508 -> 844
16:22:42.345 -> 844
16:22:43.189 -> 842
16:22:44.059 -> 842
16:22:44.905 -> 843
16:22:45.750 -> 843
16:22:46.593 -> 842
16:22:47.428 -> 842
16:22:48.305 -> 842
16:22:49.139 -> 842
16:22:50.011 -> 845
16:22:50.839 -> 845
16:22:51.707 -> 842
16:22:52.539 -> 842
16:22:53.419 -> 842
16:22:54.260 -> 842
16:22:55.111 -> 842
16:22:55.975 -> 842
16:22:56.791 -> 842
16:22:57.642 -> 842
16:22:58.492 -> 842
16:22:59.372 -> 842
16:23:00.212 -> 842
16:23:01.046 -> 842
16:23:01.918 -> 842
16:23:02.775 -> 842
16:23:03.600 -> 849
16:23:04.473 -> 849
16:23:05.329 -> 842
16:23:06.159 -> 842
16:23:07.022 -> 842
16:23:07.862 -> 842
16:23:08.709 -> 842
16:23:09.574 -> 842
16:23:10.412 -> 843
16:23:11.292 -> 843
16:23:12.116 -> 848
16:23:12.996 -> 848
16:23:13.899 -> 848
16:23:14.779 -> 848

```

The output I am expecting is 1000 as the connection to the PCINT is directly form the digital pin13 of the Arduino and it is made to blink at that interval

I want to know

 - What mistake I am making here in measuring the counts
 - How can I generalise this method for measuring width of 6 channels simultaneously.

===== Edit after input from Edgar Bonet ===========

I have written a program , can you please tell me is this a good way to accomplish my requirement

```
volatile uint32_t ovfCount = 0;

struct Pulse {
  uint32_t last_toggle;
  uint32_t width;
  bool stateHigh;
  bool input_is_high;
  uint32_t get_width() {
    noInterrupts();
    uint32_t width_copy = width;
    interrupts();
    return width_copy;
  }
};

Pulse ch1, ch2, ch3, ch4, ch5, ch6;

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

  /*
     Pin Change Interupt for
     measuring the pulse width
     from the receiver

  */

  DDRK = 0; // A8:A15 -> direction as Input
  PORTK = B00111111; // A8:A15 -> pullupResistor

  PCIFR = 0; // resetting the flags
  PCMSK2 = B00111111; // activating from A8:21 :: 6
  PCICR = B00000100; // activating 2 nd PCINT

  /*
     8 bit timer setup for counting
     timer 2 is used
  */
  TCCR2B = 0x00;
  TCCR2A = 0x00; // wave generation is normal:: all zeros
  TCNT2 = 0x00;
  TIFR2 = 0x00; // resetting all flags
  TIMSK2 = 0x01; //timer overflow enable
  TCCR2B = 0x01; // no prescaling

  DDRH = B00111000;
  fastPWM_init();

}

void fastPWM_init() {
  //    clearing
  TCCR4A = 0; TCCR4B = 0; TCCR4C = 0;
  //    Initializing
  TCCR4A = B10101010; // OC4A, OC4B, OC4C : ICR-WGM
  TCCR4B = B00011010; // ICR-WGM prescalar : 8
  //    Setting frequency
  ICR4 = 39999;
  //    Setting PWM
  OCR4A = 2000; OCR4B = 2000; OCR4C = 2000;
}

ISR(TIMER2_OVF_vect) {
  ovfCount++;
}

ISR(PCINT2_vect) {
  uint8_t tcnt2 = TCNT2;
  uint32_t ovf_count = ovfCount;

  if ( bit_is_set(TIFR2, TOV2) && tcnt2 < 128 ) {
    ovf_count ++;
  }

  uint32_t time = ovf_count << 8 | tcnt2;

  pinChangeFunction(&ch1, time, PK0);
  pinChangeFunction(&ch2, time, PK1);
  pinChangeFunction(&ch3, time, PK2);
  pinChangeFunction(&ch4, time, PK3);
  pinChangeFunction(&ch5, time, PK4);
  pinChangeFunction(&ch6, time, PK5);

}

void pinChangeFunction(Pulse *channel, uint32_t time, uint8_t pin){
  channel->input_is_high = bit_is_set(PINK, pin);
  if (channel->input_is_high && !channel->stateHigh) {
    channel->stateHigh = true;
  } else if (! channel->input_is_high && channel->stateHigh) {
    channel->width = time - channel->last_toggle;
    channel->stateHigh = false;
  }
  channel->last_toggle = time;
}

void loop() {

  if(Serial.available() > 0){
    OCR4A = Serial.parseInt();
  }

  Serial.print(ch1.get_width() / 16e3);Serial.print("\t");
  Serial.println(ch6.get_width() / 16e3);

}

```

The PWM is only used for testing.

body:
There are quite a few issues with this program. The most obvious is the
use of floating point calculations in interrupt context. Interrupts
should be served as fast as possible, and floating point is really slow
on the AVR.

Some other issues:

* Interrupt flags should be cleared by writing a logic 1 to them,
  however silly it may sound.

* A couple if `&` operators in `ISR(PCINT2_vect)` are probably meant to
  be `&&`.

* The logic for detecting rising and falling edges is all wrong.

* There is no need to store so much data in the `Pulse` objects.

* `ch1.width` should be read with interrupts disabled in order to avoid
  a data race.

* There is a subtle race condition when reading `ovfCount` and `TCNT2`:
  if the timer overflows right when `ISR(PCINT2_vect)` starts running,
  that overflow will not be counted.

Here is a version of the program that attempts to fix all these points.
I also changed it for running on an Uno (with pin 13 = `PB5` =
`PCINT5`), so that I could test it:

```c++
/*
 * Pulse width via PCINT.
 *
 * https://arduino.stackexchange.com/questions/81688
 */

volatile uint32_t ovfCount = 0;

struct Pulse {
    uint32_t last_toggle;
    uint32_t width;
    bool stateHigh;
    uint32_t get_width() {
        noInterrupts();
        uint32_t width_copy = width;
        interrupts();
        return width_copy;
    }
};

Pulse ch1, ch2, ch3, ch4, ch5, ch6;

void setup() {
    Serial.begin(115200);
    pinMode(13, OUTPUT);

    /* Setup Pin Change Interrupt for detecting pulses. */
    PCMSK0 = _BV(PCINT5);  // sense change on pin 13 = PB5 = PCINT5
    PCIFR  = _BV(PCIF0);   // reset interrupt flag
    PCICR  = _BV(PCIE0);   // enable PCINT0_vect: pins PCINT[7:0]

    /* Setup Timer 2 for counting. */
    TCCR2B = 0;           // stop
    TCCR2A = 0;           // normal mode
    TCNT2  = 0;           // reset timer
    TIFR2  = _BV(TOV2);   // reset interrupt flag
    TIMSK2 = _BV(TOIE2);  // enable timer overflow interrupt
    TCCR2B = _BV(CS20);   // count at F_CPU/1
}

ISR(TIMER2_OVF_vect) {
    ovfCount++;
}

ISR(PCINT0_vect) {
    uint8_t tcnt2 = TCNT2;
    uint32_t ovf_count = ovfCount;

    // Was there an overflow that has not yet been accounted for?
    if (bit_is_set(TIFR2, TOV2) && tcnt2 < 128) {
        ovf_count++;
    }

    uint32_t time = ovf_count << 8 | tcnt2;

    bool input_is_high = bit_is_set(PINB, PB5);
    if (input_is_high && !ch1.stateHigh) {  // low -> high
        ch1.stateHigh = true;
    } else if (!input_is_high && ch1.stateHigh) {  // high -> low
        ch1.width = time - ch1.last_toggle;
        ch1.stateHigh = false;
    }
    ch1.last_toggle = time;
}

void loop() {
    digitalWrite(13, HIGH);
    delay(1000);
    digitalWrite(13, LOW);
    delay(200);
    Serial.println(ch1.get_width() / 16e3, 5);
}
```

And here is the output:

```text
1000.02349
1000.01959
1000.01916
1000.02496
1000.01959
1000.02032
1000.01947
1000.02795
1000.02642
1000.01855
1000.01916
1000.02105
1000.02490
1000.01782
1000.03033
1000.01898
...
```

The printed values are larger than 1000 because of the time needed to
execute `digitalWrite()`.

Also note that an 8-bit timer running at the full CPU speed overflows
every 16 µs. That's quite a lot of pressure on the CPU, and many
operations will take longer that expected because of these interrupts.
If I wanted to time something with single-cycle resolution, I would
reach for a 16-bit timer. And I would prefer using input capture,
although sadly only two input capture channels are available on the Mega
(on pins 48 and 49).

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

**Edit**: Answering the questions in the comments.

> please have a look at my question edits and please advice.

I did not test it, but it seems to me this code should work. I would
prefer, however, having a different interrupt for each channel.
Otherwise, the successive calls to `pinChangeFunction()` can make the
execution of this ISR quite long.

Also note that `Pulse::input_is_high` serves no useful purpose. Storing
this value in the object slows down the ISR, as it has to access memory,
whereas a local variable would be kept in a (much faster) internal CPU
register.

> what will we do if we have 8 channels as in the radio receiver?

You could use 6 external interrupts and 2 pin change
interrupts.

> Why did you take `tcnt2 < 128` when `tcnt2` max is 256?

This one is tricky. I'll try to explain the whole logic of the test.

Consider the following naive version of the ISR:

```c++
ISR(PCINT0_vect) {
    // ← A
    uint8_t tcnt2 = TCNT2;
    uint32_t ovf_count = ovfCount;
    uint32_t time = ovf_count << 8 | tcnt2;
    // ...
}
```

There is a small chance that Timer 2 overflows at point A, i.e.
while this ISR is executing its prologue and has not yet read `TCNT2`.
If this happens, the `TIMER2_OVF` ISR will not run immediately, because
we are already executing an ISR, and ISRs do not nest. Then, `ovfCount`
is not updated. If this happens, we then read a value of `TCNT2`
affected by the overflow, and a value of `ovfCount` that does not
account for that overflow. We then combine together those inconsistent
values into a `time` value that misses 256 timer ticks.

We can detect this situation by reading the `TOV2` flag in `TIFR2`. This
flag is set only when there is a pending interrupt request for
`TIMER2_OVF`, i.e. if the counter has overflowed and that overflow has
not yet been accounted for in `ovfCount`. Thus the “fixed” ISR looks
like this:

```c++
ISR(PCINT0_vect) {
    // ← A
    uint8_t tcnt2 = TCNT2;
    // ← B
    uint32_t ovf_count = ovfCount;
    // ← B
    if (bit_is_set(TIFR2, TOV2)) {
        ovf_count++;
    }
    uint32_t time = ovf_count << 8 | tcnt2;
    // ...
}
```

With this, if the overflow happens at point A, we manage to compute the
proper `time`. But consider now what would happen if the timer overflows
at either of the points marked B, i.e. after reading `TCNT2` but before
reading `TOV2`. If this happens, we read the pre-interrupt values of
both `TCNT2` and `ovfCount`. No correction is thus needed for computing
a consistent `time`. Yet, `TOV2` is raised when we test it: we then
apply an unneeded correction, and we end up with a `time` that is too
large by 256 ticks.

In order to fix this problem, we have to make sure the correction is
applied if the overflow happens at point A, but not if it happens at
point B. How can we tell apart those two situations? The answer is: by
looking at the value recorded in `tcnt2`. In case A, the counter was
read right after the overflow, so it had a very small value (close
to 0) when it was copied to `tcnt2`. In case B, the counter was
read when it was just about to reach the overflow, so it had a very
large value (close to 255). If `TOV2` is set when we read it, this
means an overflow happened during the very beginning of the current ISR,
very close to the point where we read `TCNT2`. So the value recorded in
`tcnt2` has to be either very small or very large. It cannot be in the
middle (close to 128).

So we have to decide whether `tcnt2` is very small or very large. There
are many possible values that could be used as a threshold. The most
natural is the mid range: 128. It is also the most efficient to compute,
as the compiler can optimize the comparison into a simple test of the
most significant bit. Thus the final version of the test:

```c++
    if (bit_is_set(TIFR2, TOV2) && tcnt2 < 128) {
        ovf_count++;
    }
```


message:
Wemos Mini & Pro Micro Serial connection

While using a 3.3v Pro Mini & Wemos mini to communicate via Serial was successful, when tried with a 5v Pro Micro it fails.

To overcome different logic level I used a 10K + 20K resistors to lower Pro-Micro's 5v to 3.3v successfully to `Tx` and `Rx` pins. Also since they are on the same PCB, `GND` pins are connected and `RAW` to `5V` at wemos mini  is also connected. At the moment, it is powered up using MCU's USB input ( tried to connect to Pro-Micro only, Wemos Only, and both ).

[![Schematics][1]][1]
What might be the problem ?

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

body:
You don't need a logic level conversion between 5 V Micro Arduino and 3.3 V Wemos D1 mini. The 5 V ATmega 328p reads 3.3 V as HIGH and the esp8266 can tolerate 5 V logic level for tests. For long term connection you can add logic level conversion with a voltage divider to convert the 5 V of ATmega TX to 3.3 V of esp8266 RX.

RX/TX pins on Arduino Mini are Serial.
RX/TX pins on Arduino Micro are **Serial1**.
Serial is only USB on Micro.


message:
Getting different numbers after sending an unsigned int 8-9 times between Arduinos via Serial

I am trying to transfer `unsigned int` values between 2 Arduinos. When sending `61805` for the first 8-9 times, I am getting 61805.  But after then after these numbers: 61937 28013 61937.

Sender's code:

```c++
unsigned int s = 0;

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

void loop()
{
  s = 61805;
  Serial.write(highByte(s)) ;
  Serial.write(lowByte(s));
}
```

Receiver's code:
```
unsigned int upperByte, lowerByte, r=0,p=0;

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

void loop ()
{
  if (Serial.available() > 1)
  {
    upperByte = Serial.read();
    lowerByte = Serial.read();
  }

  r = (upperByte << 8) + lowerByte;
  Serial.println(r);
}
```

body:
There's no flow control on the Uno and Nano serial and you are sending fast enough that bytes are being dropped, and there's no way your protocol or lack of one demarcates separate messages (separate numbers).

This will become more clear if you write your numbers in hexadecimal:

Dec   | Hex
------|-------
61805 | 0xf16d
61937 | 0xf1f1
28013 | 0x6d6d
61937 | 0xf1f1

Adding a delay between messages can serve to separate the messages if the receiving side makes use of a timeout and can prevent the receiving side from being overwhelmed with data.

If you don't want to use time to slow down and separate your data, you can change what is sent instead.  One idea is to have the receiver actively request data when it's ready to receive some. The receiver should expect only entire messages between requests, and if anything gets garbled, it can just read whatever data has come in and throw it out before the next request.

Your messages can also be separated by some characters that aren't part of the messages themselves.  A common way to do that is just to encode your numbers as separate text lines, the line terminator `\n` serving as the separator between messages.

I have not tested these yet, but here are some very minimal modifications to your code that approach having a protocol with fewer of these problems:

Sender:
```c++
void setup () {
  Serial.begin(9600);
}

void loop() {
  // await message request
  while(Serial.read() != '.') {
  }

  //
  const unsigned int s = 61805;
  Serial.write(highByte(s)) ;
  Serial.write(lowByte(s));
}
```

Receiver:
```c++
void setup() {
  Serial.begin(9600);
}

void loop () {
  // request message
  Serial.write('.');

  // await two-byte response
  const unsigned long request_sent = millis();
  while (Serial.available() < 2 && millis() - request_sent < 1000) {
  }

  if (Serial.available() != 0) {
    if (Serial.available() == 2) {
      // two byte response receive
      const unsigned upperByte = Serial.read();
      const unsigned lowerByte = Serial.read();
      const unsigned r = (upperByte << 8) + lowerByte;
      Serial.println(r);
    }  else {
      // Something went wrong, too or too few bytes received;
      // throw them out and start over.
      delay(100);
      while (Serial.read() != -1) {}
    }
  }
}
```

It's a long way from doing it properly, but it should behave at least better than what you started with.  There's a lot to designing even simple protocols.  Typically there are start and end frame bytes, a checksum or CRC, a message number counter, etc.


body:
This line of the receiver's code:

```c++
Serial.println(r);
```

is transmitting 7 bytes (5 digits, CR and LF). At 9600/8N1, each byte
takes 1.04 ms, so the whole message is transmitted in 7.28 ms. In the
meantime, the sender is sending 2-byte messages at full speed (no pause
between the bytes). The receiver thus gets a new message every 2.08 ms.

So, this receiver is given a new message to relay every 2.08 ms, and it
needs 7.28 ms to relay each message. Something has to give...

The reason it works in the beginning is that the receiver has a buffer
where it stores the bytes that have been received, and another one for
the bytes that have been made ready for transmission. As long as there
is room in those buffers, everything works fine. The transmit buffer
fill-up first, as it gets 7 bytes to transmit every 2.08 ms. Once it's
full, `Serial.println()` becomes a _blocking_ function: it has to wait
for the buffer to have enough room. Your `loop()` then slows down to
match the speed of the transmission, which means you do not read the
receive buffer often enough. Then the receive buffer fills up, and you
start loosing bytes.


message:
This website in Arduino lists language references like functions and structures. What makes structures there different from functions?

https://www.arduino.cc/reference/en/

**Language Reference**

Arduino programming language can be divided in three main parts: functions, values (variables and constants), and structure.

**functions**

For controlling the Arduino board and performing computations.

**variables**

Arduino data types and constants.

**structure**

The elements of Arduino (C++) code.

I find it really confusing that they had to separate the structures but also call them functions in their descriptions. I kind of want to get a visualization or organization of the different language references present in Arduino, but this just confuses me. Are structures in the website also functions, and mainly syntax can be classified into functions and variables? Can someone present a organization of language references that doesn't involve terminologies being mixed up?

body:
What the website names "Structures" are code building-blocks for the programs you write. The main part there are conditional (if-else) and loop instructions (for, while) as well as mathematical operators. You use these constructs _within_ your functions to control program flow or compute results. Functions, on the other hand, are sub-programs you can call to have certain tasks done. They might be pre-defined (such as the ones described on the language reference page) or written by yourself.

Now there are two exceptions to this rule, and maybe that's what's a bit confusing in the documentation: The functions `setup()` and `loop()`. These are functions, but make up the structure of your program. They are the main building blocks of an Arduino sketch, and that's probably why they're mentioned under "Structures".


message:
Deactivate pushbuttons at initial stage

Pl someone answer my question. I have 4 pushbuttons namely add/reject/start & finish. I want to

1.Deactivate add/reject buttons at initial stage until start button pressed &
2.Once add/reject activated, again should deactivate once finish button pressed &
3.Again if start button pressed, add/reject should be released.

with following code I able to do 2 & 3. However I still lack at 1.pl help on this.

    const int bt_Select = 2; // #define BUTTON_PIN 2
    const int bt_Reject = 3;
    const int bt_Start = 7;
    const int bt_Finish = 8;

    boolean decision=false;

    int bt_Select_state=0;
    int bt_Reject_state=0;
    int bt_Start_state;
    int bt_Finish_state;

    int selected;
    int rejected;
    int started;
    int finished;

    void setup() {
      // put your setup code here, to run once:
        Serial.begin(9600);
        pinMode(bt_Select, INPUT_PULLUP);
        pinMode(bt_Reject, INPUT_PULLUP);
        pinMode(bt_Finish, INPUT_PULLUP);
        pinMode(bt_Start, INPUT_PULLUP);
        Serial.println("Welcome to Nano");
        delay(1000);
      }
    //========================================================================
          void loop() {

            started=bt_Start_pressed();
            selected =bt_Select_pressed();
            rejected=bt_Reject_pressed();
            finished=bt_Finish_pressed();
            decision=Stop_Main();

              int x=0;
              int Lx=0;

           if (selected&&decision){x=1;}
           if (rejected&&decision){x=2;}
            if (started&&decision){x=3;}

           if (x!=Lx){
            switch(x) {
              case 1:Serial.println("Selected");delay(250);Serial.print("");
                     break;
              case 2:Serial.println("Rejected");delay(250);Serial.print("");
                     break;
              case 3:Serial.println("Started");delay(250);Serial.print("");
                     break;

              /*case 3://do something when var equals 1
                     Serial.println("Removed");
                     break; */
                 }//switch(x)
                     x=Lx;
          }//eof  if (x!=Lx)

          }
    //====================================================================
          int bt_Select_pressed(){
             bt_Select_state=digitalRead(bt_Select);
               if (bt_Select_state == LOW){return 1;}
               else {return 0;}
          }
    //====================================================================
          int bt_Reject_pressed(){
             bt_Reject_state=digitalRead(bt_Reject);
              if (bt_Reject_state == LOW){return 1;}
              else {return 0;}
               }
    //====================================================================
        int bt_Start_pressed(){
             bt_Start_state=digitalRead(bt_Start);
              if (bt_Start_state == LOW){return 1;}
              else{return 0;}
                }
    //====================================================================
          int bt_Finish_pressed(){
            bt_Finish_state=digitalRead(bt_Finish);
              if (bt_Finish_state == LOW){return 1;}
              else {return 0;}
          }
    //=====================================================================

          boolean Stop_Main(){
            bt_Start_state=digitalRead(bt_Start);
            bt_Finish_state=digitalRead(bt_Finish);

            if (bt_Finish_state == LOW){decision=false;return decision;}
            if (bt_Start_state == LOW){decision=true; return decision;}

           // else if (bt_Start_state ==HIGH  && bt_Finish_state == HIGH){decision=false;return decision;}
              }

    /*  boolean bt_Start_pressed(){
             bt_Start_state=digitalRead(bt_Start);
              if (bt_Start_state == LOW){started=true; return decision;}
              else{started=false; return decision;}
                }   */
        //===================

body: Keep a boolean that begins as `false`. Set it to `true` when the start button is pressed, and set it to `false` again when the finish button is pressed. Then you can read and respond to the `add` and `reject` buttons only if that boolean is `true`, and otherwise ignore them.


message:
5V pin out, 8 pins and micropython/circuitpython support: does such a board exist?

For a project, I am looking for a board to connect eight different neopixel-strips to, on eight different data pins. Because of the great length between the board and the first pixels of these strips, I'd like to have a board that operates on 5V instead of 3.3V. Then, the software that I have written to manage the LEDs is made in (micro)python. Finally, for simplicity's sake, I'd like to run this complete project on a single board without too many external components.

So, I have found 5V boards with enough pins, like the Arduino Mega. I have also found boards with enough pins and support for micropython or circuitpython, like the ESP32 or Arduino Zero.

However, I haven't quite found a board that matches all my requirements. The Arduino Mega doesn't support Python (or does it?) and the ESP32 and Arduino Zero operate at 3.3V, not 5V.

Of course, an ESP32 with a level shifter (as shown on https://github.com/Aircoookie/WLED/wiki) would work, but is there perhaps a board out there that fits all my requirements our of the box?

**Edit**: It seems I misunderstood some things about the hardware - sorry, I'm a software guy, not really a hardware guy :-) I fixed the question above as not to confuse future readers.

body:
Both your "requirements" for the board are non-requirements.

* You do not need PWM pins to drive Neopixel strips. The Neopixel uses its own custom protocol that has nothing at all to do with PWM.
* Your board only communicates with the *first* Neopixel. That one then communicates with the second, which then communicates with the third, etc. The length of the strip is completely irrelevant to what voltage you might want to drive it with.

You only care about having enough general IO pins and if the IO voltage is suitable to communicate with one Neopixel.

According to the WS2812B datasheet VIH is 0.7Vdd, which if you are powering the strips from 5V means 0.7 * 5 = 3.5V. However I think that is an overestimation and they are erring on the side of caution there, since I regularly drive WS2812B strips from a 3.3V microcontroller with no problems whatsoever (after all it's only 0.2V difference).

So just use your favourite 3.3V microcontroller that can run micropython and, if you really want to, drop the power supply voltage to the strips a fraction with a diode.


message:
ESP8266 ESP-01s Not Responding, No LED Blinking, Overheating

I have an ESP-01s that I want to use as a shield so my Arduino Uno project could communicate with my Blynk app through wi-fi. I used this [video][1] as reference.

This is the sketch. It is just the ESP8266_Shield example from the Blynk library.

    #define BLYNK_PRINT Serial

    #include <ESP8266_Lib.h>
    #include <BlynkSimpleShieldEsp8266.h>

    char auth[] = "-------";

    char ssid[] = "-------";
    char pass[] = "-------";

    #include <SoftwareSerial.h>
    SoftwareSerial EspSerial(2,3); // RX, TX

    // Your ESP8266 baud rate:
    #define ESP8266_BAUD 115200

    ESP8266 wifi(&EspSerial);

    void setup()
    {
      // Debug console
      Serial.begin(9600);

      delay(10);

      // Set ESP8266 baud rate
      EspSerial.begin(ESP8266_BAUD);
      delay(10);

      Blynk.begin(auth, wifi, ssid, pass);
    }

    void loop()
    {
      Blynk.run();
    }

This is the schematic:
[![enter image description here][2]][2]

What happens:

 1. The moment the Arduino is connected, the Blue LED flashes for a split second then all LEDs will remain off. No red led, no blue led, really just off.
 2. The ESP-01s becomes very hot to the touch
 3. Tried speaking to the ESP-01s through the Serial Monitor with BareMinimum example @115200 baud rate (Many Sources say that this is the default baud rate of the recent boards) however no response whatsoever.
 4. Running the code above will get this error:
[![enter image description here][3]][3]

What I've done:

 1. Tried using the HW-131 Breadboard Power Supply to supply the 3.3V (Common GND with Arduin) of the ESP-01s because I read that the ESP-01 could need more current than the Arduino Uno could provide. Still the same effect, no LEDs blinking, (even more) hot to touch, not responding to AT commands.
 2. Attempted to follow a [video][4] on how to flash the ESP-01s but when I tried to run the flasher, it could not communicate with the ESP-01s.
 3. Switching Rx Tx ESP-01s but no luck.
 4. Added a 10k ohm resistor from 3.3V to the Vcc and EN pins of the ESP-01s. Not heating up anymore but still no response.

I really thought this is a power problem but could it be the ESP-01s itself is defective?

This is what the ESP-01s look like
[![enter image description here][5]][5]

  [1]: https://youtu.be/6rx-iyUq1Po
  [2]: https://i.stack.imgur.com/wN3kM.png
  [3]: https://i.stack.imgur.com/qYuZV.png
  [4]: https://www.youtube.com/watch?v=QVhWVu8NnZc
  [5]: https://i.stack.imgur.com/8BYEi.jpg

body:
The ESP8266 is (highly likely) dead. The overheating is the giveaway.

Because you haven't mentioned it, please measure the 3.3V coming out of the Arduino with a multimeter. Unlikely to be the issue but it is easy to check.

You will need to buy a new ESP8266 and connect it up and give it a try with a fresh board. If all is good with the new board then the first thing you will notice is that there is no overheating. (If there is overheating, then you need to check your wiring.)

I notice that quite a lot of people add a 10K pull up resistor between the 3.3V line and the Enable pin. It certainly won't hurt to add a 100 ohm resistor between the Tx pin and D2 of the Arduino as a current limiting resistor, just in case.


message:
Stable amplitude of amplified signal

Is there any circuit with opamp where can be (by arduino) set constant output amplitude which doesn't depend on input signals amplitude?

body: Just a word of advice about AGC in general.  There is almost always an issue of attack (how fast the AGC reacts to a sudden increase in signal) and release (how fast it reacts to a decrease).  In most AGC cases you will need to make compromises on these two settings to avoid poor behavior from the AGC... it's not a drop-in solution with pre-determined optimum settings for every purpose.  Depending on the program material, you can get obnoxious artifacts like breathing and pumping for speech and music.  ACG is much better at slow drifting things like signal fade.  I just want you know what you might be getting into...


message:
I have five pushbuttons that refer to a specific pin number. I need an efficient code to set the variable for the pin with state 1. What can I use?

There are 5 push buttons each which correspond to a certain pin let us use 1 to 5 for an example. I want to set a variable, ActiveButton which will be set equal to the the only pin in the one state.

We make use of the concept that there can only be one active push button which means the pin of that would have a state of 1 and the rest would be 0. The long method for this would be to use if else and digitalRead(pin) == 1 for everything but that would be so long on code. I've considered using do while or while loops to stop until it reaches the push button with a state of 1, but I was wondering if there was a more efficient code. I was also thinking if there was something that made use of an array?

Though the idea of like having a simple array return the index which results to a corresponding value, like lets say Array[3] ==1 among all the indices from 0 to 4 feels easy to conceptualize, I believe this can be really taxing on the code and might not be able to be done in a short way.

I've also thought of possibly using switch case, where the variable would be the high state and the case values would be the digitalRead for each pin? But that would be wrong probably because I'm not sure but you can't set the switch variable to be a constant. It would be something like

switch (1)

case digitalRead(1):

case digitalRead(2):

body:
> There are 5 push buttons each which correspond to a certain pin let us use 1 to 5 for an example. I want to set a variable, ActiveButton which will be set equal to the the only pin in the one state.

Here is a short snippet of what I think, that you want. This is quite a long shot, since your question is not clear enough.

    int ActiveButton = -1; // Initialize ActiveButton with -1 (no button is active)
    int button_pins[] = {1, 2, 3, 4, 5}; //Array with pin numbers of the buttons

    void loop(){
        for(int i=0;i < sizeof(button_pins)/sizeof(button_pins[0]); i++){
            if(digitalRead(button_pins[i])){ //if the i-th button was pressed
                ActiveButton = button_pins[i]; // assign i-th button pin number to variable
                break; // Break, since we have found our pressed button, ignore all following pins
            }
        }
    }

This will assign the pin number of the pressed button to the variable. The condition in the for loop

    sizeof(button_pins)/sizeof(button_pins[0])

will make the code loop over all elements of the `button_pins` array. `sizeof(button_pins)` returns the number of bytes in the `button_pins` array. Then we divide through the number of bytes in the first element to get the number of elements in the array.


message:
Where to go after Arduino?

I apologise in advance if this question is not right for this Stack or if it has been answered before but here goes. I have been learning C/C++ using the Arduino Uno and have gotten the hang of it now (I have knowledge of other programming languages so it wasn't too difficult to get in the rhythm). I was wondering how I would go about creating a standalone solution if I wanted to display information on four or five displays similar to [These][1]. I would pull data from a network to display on them too so I would also need to accommodate an ethernet or WiFi shield.

I appreciate any help or pointers in the right direction that can get me started on my journey to creating some custom embedded systems (if that is indeed what I am describing).

  [1]: https://uk.banggood.com/Geekcreit-IIC-I2C-2004-204-20-x-4-Character-LCD-Display-Screen-Module-Blue-Geekcreit-for-Arduino-products-that-work-with-official-Arduino-boards-p-908616.html?akmClientCountry=GB&cur_warehouse=UK

body: You can use an ESP8266 or ESP32. This makes it easy to transmit data via WiFi. You can also use the Raspberry Pi, which is much more powerful.


body:
Uno's major limitation is it's 2KB of RAM. If your project can live within that, an Uno can host it.

The display you pointed to is an I2C device and can be bussed, so Uno pin count won't be a limitation. Current might be, and you may need to power the displays independently of the Uno.

The ESP-01 module makes a good Wifi accessory which you can build onto a proto-shield or wire separately. If your Uno is powered at 5v as most are, you'll need to provide 3.3v power to the ESP, and a voltage divider on the ESP's receive pin to reduce the serial input from the Uno to 3.3v.

Update:<br>Upon re-reading, your title suggests you *want* to move on from an Uno, and you've mentioned a stand-alone solution.

There are many more capable boards available. Arduino Mega is one which would be an easy, almost trivial, transition up from Uno, in flash memory, RAM, and available I/O.

If by "stand-alone" you meant "roll your own", there are any number of how-to projects on the web for rolling your own Atmega 328p-based clone of an Uno.

The direction you take really depends on your project needs and/or your personal preference.


body:
There are a lot of much more powerful boards available (especially if you move from ATmega to ARM).  I'm partial to the [Teensy](https://www.pjrc.com/teensy/) boards myself but Adafruit also makes some nice ARM-based boards.  For example, I'm currently developing a multi-user, Arduino-compatible Unix-ish OS on [one of the latter](https://www.adafruit.com/product/3010) (48MHz ARM, 256kB flash, 32kB SRAM) and it runs great.  Honestly, controlling 5 non-graphical LCDs over I²C is should be easily doable on an Uno but if you need more power there are lots of options available.

(No affiliation to either of those companies)


message:
Can you create an array for functions?

Let's say I want to create 10 functions, named Function1, Function2 until 10. Each function is used if a certain variable is equal to its number. Rather than using individual functions, I was wondering if its possible to use some sort of array concept for functions when it comes to naming? I tried reading about it and saw pointers but I honestly didn't understand what I saw about it because I'm not that adept to the language yet.

body:
Here's an example of how to do it:

**jump_table.ino**

``` lang-cpp
int func1(int arg)  { return arg + 1; }
int func2(int arg)  { return arg + 2; }
int func3(int arg)  { return arg + 3; }
int func4(int arg)  { return arg + 4; }
int func5(int arg)  { return arg + 5; }
int func6(int arg)  { return arg + 6; }
int func7(int arg)  { return arg + 7; }
int func8(int arg)  { return arg + 8; }
int func9(int arg)  { return arg + 9; }
int func10(int arg) { return arg + 10; }

int (*jump_table[10])(int) = { func1, func2, func3, func4, func5,
                               func6, func7, func8, func9, func10 };

void setup() {
}

void loop() {
  int index = 2;
  int argument = 42;
  int result = (*jump_table[index])(argument);
  // result is 45
}
```

All functions stored in the array must have the same signature.  This simply means that they must return the same type (e.g. `int`) and have the same arguments (a single `int` in the example above).

---

You can do the same with *static* class methods (but not instance methods).  For example you could use `MyClass::myStaticMethod` in the array above but not `MyClass::myInstanceMethod` nor `instance.myInstanceMethod`:

``` lang-cpp
class MyClass {
public:
  static int myStaticMethod(int foo)   { return foo + 17; }
  int        myInstanceMethod(int bar) { return bar + 17; }
}

MyClass instance;
```

There's a [similar question](https://stackoverflow.com/questions/252748/how-can-i-use-an-array-of-function-pointers) over on stackoverflow.


message:
How can I break the loop if it hasn't finished in 10 seconds?

Currently I am using [OneButton.h library](https://github.com/mathertel/OneButton) to code  my push button project.

When I press button1, it will loop for 10sec and print TRIG, and after that it will break the loop.

However, now I want to program it where when I pressed button1, it will jump to `void(singleclick)` function, but right now, during the 4th seconds (anytime before 10th sec) , I pressed other button, thus Arduino will break the 10sec loop and run other function.

Thus, I need help how to make sure Arduino actively read other button and when pressed, it will break the current loop/function to other related functions.

```
#include <OneButton.h>

OneButton button1(2, true);
OneButton button2(3, true);
OneButton button3(4, true);
OneButton button4(5, true);

int led1=12;
int led2=11;
int led3=10;
int led4=9;

int flag;

unsigned long mode;

void setup()
{

  Serial.begin(9600);
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
  pinMode(led4,OUTPUT);

  button1.attachClick(singleclick1);
  button1.attachLongPressStop(longclick);

  button2.attachClick(singleclick2);
  button3.attachClick(singleclick3);
  button4.attachClick(singleclick4);

   digitalWrite(led1,HIGH);
   digitalWrite(led2,HIGH);
   digitalWrite(led3,HIGH);
   digitalWrite(led4,HIGH);

}

void loop()
{
  button1.tick();
  delay(20);

  button2.tick();
  delay(20);

  button3.tick();
  delay(20);

  button4.tick();
  delay(20);

  Serial.println("No button");

}

void singleclick1()
{
   mode=millis();

   flag=1;

   while(flag==1)
   {
     Serial.println("button1");
     digitalWrite(led1,HIGH);
     digitalWrite(led2,LOW);
     digitalWrite(led3,LOW);
     digitalWrite(led4,LOW);

     if(millis()-mode>5000)
     {
      Serial.println("TRIG");
      flag=0;

      button2.tick();
      delay(20);

      button3.tick();
      delay(20);

      button4.tick();
      delay(20);

      return;
     }
   }
}

void singleclick2()
{
   Serial.println("button2");
   digitalWrite(led1,LOW);
   digitalWrite(led2,HIGH);
   digitalWrite(led3,LOW);
   digitalWrite(led4,LOW);
}

body:
This is just a rough, incomplete and untested code.

```
void singleclick1() { startTimer = true; }      // this only sets a flag

void singleclick2() { runTimer   = false;}      // this only clears a flag

void loop() {

   button1.tick();
   button2.tick();

   if startTimer {                 // this occurs once every click 1

      mode        = millis();
      runTimer    = true;
      startTimer  = false;         // run this block only once every click 1

      digitalWrite(led1, HIGH);
      digitalWrite(led2, LOW );
      digitalWrite(led3, LOW );
      digitalWrite(led4, LOW );
   }

   unsigned long currentMillis = millis();

   if (currentMillis - mode > 10000) {
      runTimer = false;                      // 10 second timer expired
   }

   if (runTimer) {

      Serial.println("TRIG");

   }
   else {
      // optional stuff to do
   }
}
```


message:
I have three pushbuttons where only one can be pushed at a time and want to set a variable for this. How?

Basically I have three push buttons that correspond to pins 1 to 3 and want to set an efficient code that sets a certain variable into the index whose digitalRead is equal to one. Let us assume that only one button can be pressed at a time.

```
void loop()
 {
 if(digitalRead(1) == 1)
  {
       Variable = 1;
  }
 if(digitalRead(2) == 1)
  {
       Variable = 2;
  }
 if(digitalRead(3) == 1)
  {
       Variable = 3;
  }
 }
```

Is there are more efficient way to do this, like for example using other loops?

I can't wrap around my head with doing this concept using the other loops such as for, do while, while and switch because the nature of the idea feels so unconventional for their uses.

body:
If you can only have one button pushed at a time, you can only end up with at most one of the if statements evaluate to true. In your code, you check button 2 and 3, even if button 1 is pressed. Your code can be a bit faster if you do this:

    if(digitalRead(1) == 1)
    {
      Variable = 1;
    }
    else if(digitalRead(2) == 1)
    {
      Variable = 2;
    }
    else if(digitalRead(3) == 1)
    {
      Variable = 3;
    }


message:
Arduino Yun not getting response from Azure API

I posted this on StackOverflow but figured I'd post it here too. Sorry in advance if thats not allowed.

I'm trying to get my Arduino Yun to talk to an API that I'm hosting on Azure. I would like to do more complex things in the future, but at the moment I'm just trying to make a GET request over wifi with a single integer as a parameter.

I'm basically just using the example found [here](https://www.arduino.cc/en/Tutorial/LibraryExamples/HttpClient) with the url changed. The example works fine, so as far as I'm aware the issue isn't with my board, its with the interaction with Azure.

HttpClient.get() returns an int as a response (not the regular HTTP response codes, its unique for the library). I got 60 initially, and changing my API to accept http calls (instead of just https) fixed this and made me get a response of 0 instead. 0 is the same response that I get from the working Arduino example, but for some reason I'm not actually getting anything in the body of my response, as the client.available() loop is never entered.

The API works as intended when I go to the url in chrome, so the issue arises somewhere due to how the arduino and azure talk to each other, but I don't know enough about either to figure it out and nowhere that I look seems to point me in the right direction.

Any help would be greatly appreciated, thanks.

body: Found the problem, even though I set azure to accept http requests, it was still redirecting to https which the arduino couldn't handle. I've written a python script to offload the requests to the linux processor, and now it works.


message:
Can't Turn Off Internal I2C Pull-Ups on ESP32

I've designed a custom ESP32 board around the WROVER-IE module. To keep power low, I'm using a GPIO-controlled high-side FET to turn off unused peripherals when in deep sleep mode.

The issue: I've pulled up an SSD1306 I2C OLED to this AUX rail. It works great when the device is awake. On setup() I start the OLED via ssd1306.begin() and from that point on, the SCL and SDA pins (22, 21) are always tied to 3.3V until I reset the ESP32.

The I2C bus always being tied to 3.3 ends up bleeding through the pull-up resistors and into the AUX rail, resulting unwanted current draw when in sleep mode.

Is there any way to turn off the internal I2C pullups on the ESP32?

Things I've tried so far:

 - Setting SDA, SCL as OUTPUT and writing LOW (does not work)
 - Setting SDA, SCL as INPUT and/or writing LOW (does nothing)
 - Calling `gpio_hold_dis(gpio_num_t(SDA));`(does nothing)

I'm now trying to dissect the esp32-hal-i2c.c lib but am not finding any fixes. Any help is greatly appreciated!

Edit, added diagram:
[![enter image description here][1]][1]

-N

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

body:
I have solved this problem. For anyone who would like to turn off the internal pullups on the I2C bus of the ESP32, you need to disable the entire driver before putting the device to sleep.

First, include the peripheral driver library from the IDF:

    #include "driver/periph_ctrl.h"

Next, call the following before sleep:

    rtc_gpio_isolate(gpio_num_t(SDA));
    rtc_gpio_isolate(gpio_num_t(SCL));
    periph_module_disable(PERIPH_I2C0_MODULE);
    digitalWrite(SDA, 0);
    digitalWrite(SCL, 0);
This will stop the ESP32 from pulling up pins 21 and 22 while in deep sleep. Calling display.begin() or wire.begin() will restartthe driver upon wake.


message:
I can't turn on the motor by Arduino IoT Cloud

I'm trying to turn ON/OFF a DC motor from Arduino Iot Cloud. I have to turn it ON/OFF physically and through the cloud, physically it works well but from the cloud it does nothing. I'm using an Arduino MKR WiFi 1010, a L298N Dual full bridge,9V DC motor and a push buttom. Mi circuit is like this [![enter image description here][1]][1]

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

My code is this

    #include "thingProperties.h"
    #include <FTDebouncer.h>

    #define MOTOR_PIN 2
    #define BUTTON_PIN 5

    FTDebouncer buttons;

    void setup() {
      pinMode(MOTOR_PIN, OUTPUT);
      buttons.addPin(BUTTON_PIN, LOW);
      buttons.init();

      setDebugMessageLevel(2);
      Serial.begin(9600);
      delay(1500);
      // Defined in thingProperties.h
      initProperties();
      // Connect to Arduino IoT Cloud
      ArduinoCloud.begin(ArduinoIoTPreferredConnection);
    }

    void loop() {
      buttons.update();
      ArduinoCloud.update();
      onMotorChange();
    }

    void onPinActivated(int pinNr) {
      // do something according to the _pinNR that is triggered. For instance:
      Serial.println(pinNr);
      toggle = !toggle;
    }

    void onPinDeactivated(int pinNr) {
      // do something according to the _pinNR that is triggered. For instance:
      Serial.println(pinNr);
    }
    void onMotorChange() {
      digitalWrite(MOTOR_PIN, toggle || motor);
      Serial.print("The motor is ");
      if (toggle) {
        Serial.println("ON");
      }
    }

 I tried with a LED and it worked very well, but with the motor doesn't.
This is the code that Arduino creates when I add things to the board, the part of

> thingProperties.h

    // Code generated by Arduino IoT Cloud, DO NOT EDIT.
    #include <ArduinoIoTCloud.h>
    #include <Arduino_ConnectionHandler.h>

    // x-ed id
    const char THING_ID[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    const char SSID[]     = SECRET_SSID;    // Network SSID (name)
    const char PASS[]     = SECRET_PASS;    // Network password (use for WPA, or
    use as
    key for WEP)

    void onMotorChange();

    bool toggle;
    bool motor;

    void initProperties(){

    ArduinoCloud.setThingId(THING_ID);
    ArduinoCloud.addProperty(toggle, READ, ON_CHANGE, NULL);
    ArduinoCloud.addProperty(motor, READWRITE, ON_CHANGE, onMotorChange);

    }

    WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);

Thanks for the help and suggestions. How should I connect the motor or what do I have to change in the code?

body:
The following code is an example. As I don't know the Arduino Cloud Thing configuration, and I don't have access to the cloud and the Hardware, the
programm is just a guess making some commented assumptions.

There are many assuptions I made, and I can not rely on the schematics you showed me. Eventually you have to redesign the circuit/hardware setup. A L298N is a so called H-Bridge. That needs at least two control pins in1 and in2 connected to arduino outputs to define the direction of the motor. You only connected one of them to an output of the arduino. And one of them to the button and an input of the arduino. (If that part of the schematics is correct.)

If you press the button in1 gets HIGH but the in2 may also get HIGH because your program switches the motor pin to HIGH. That turns the motor off. If one pin is HIGH the other must be LOW to drive the motor. Some L298N modules also need a PWM signal at the enA pin. That sets the speed of the motor with the duty cycle of the PWA signal. Most modules have a pullup at enA and enB so per default the motors are configured for full speed.

    #include "thingProperties.h"
    #include <FTDebouncer.h>

    #define MOTOR_PIN 2
    #define BUTTON_PIN 5

    FTDebouncer buttons;

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

      // !!! PPK: Handler methods added
      buttons.addPin(BUTTON_PIN, LOW, onPinActivated, onPinDeactivated);

      buttons.init();

      setDebugMessageLevel(2);
      Serial.begin(9600);
      delay(1500);
      // Defined in thingProperties.h
      initProperties();
      // Connect to Arduino IoT Cloud
      ArduinoCloud.begin(ArduinoIoTPreferredConnection);
    }

    void loop()
    {
      buttons.update();
      ArduinoCloud.update();
    }

    void onPinActivated(int pinNr)
    {
      if ( pinNr == BUTTON_PIN )
      {
         toggle = !toggle;
         // this assumes that the toggle triggers a change for
         // the motor variable in arduino cloud. If not,
         // the motor variable will not be changed and my code does not work.
         // uncommenting the following line may help, in that case
         // motor = toggle;
      }
    }

    void onPinDeactivated(int pinNr)
    {
      // Intentionally left empty, we only react to the rising edge.
    }

    void onMotorChange()
    {
      digitalWrite( MOTOR_PIN, motor );
      Serial.print("The motor is ");
      if ( motor )
      {
        Serial.println("ON");
      }
      else
      {
        Serial.println("OFF");
      }
    }


message:
Arduino Mega Clone CH340G Capacitor Values

I'm making my own Arduino Mega board with ATmega2560-16AU and CH340G. Jump to the end of the post to find the real question.

I have already ordered a PCB before and it didn't work when I soldered everything in place. I have already asked why that board didn't work on another post here: https://arduino.stackexchange.com/questions/81361/programming-custom-arduino-mega-with-arduino-uno

But I was not satisfied with the answers and started suspecting whether or not the capacitor values were right on my board.

I'm trying to make my own version of RobotDyn's Arduino Mega 2560 Pro so I tried taking the already programmed ch340g and soldering it on my own board and still failed. When I put a previously not programmed ch340g on the RobotDyn board and programmed it using Arduino UNO (Arduino as ISP) the board would work.

So now I ordered a new PCB but haven't ordered any of the passive components yet.

**If any of you could tell me where I could find the values from the schematic below I would really appreciate that.**

https://robotdyn.com/pub/media/0G-00005641==MEGA-PRO-CH340GATmega2560/DOCS/Schematic==0G-00005641==MEGA-PRO-CH340GATmega2560.pdf

body:
The values can be easy found for generic CH340g and ATmega2560 implementations:

C1,C2 = 100nF, C3,C4 = 22pf but depends on the crystal you use, all others excepting C12 are decoupling capacitors.

C12 has no sense where it's placed, it seems that the schematic is a bad combination of schematics, this capacitor should reset the board at power on but it breaks the reset pulse from CH340g so you cannot program the board without pressing manually the reset pushbutton. Don't place C12 at all.

Also place a short instead of R5 and R6 that are not in the CH340g manual (there is a special mention to connect the pins straight to USB bus), remove R8, is not needed for the same reason, R3 makes no sense, don't place-it.

R2,R4 = 1K, R7,R9 = 10K, R10,R11,R12,R13 = 1K, R14 = 10K , R15 = 1M.

Y1 = 12Mhz, Y2 = 16Mhz

A 22 ohm resistor is missing in your schematic between Y2 XTAL1 and ATMEGA XTAL2 but I don't think it's important.

I hope I didn't missed something

The bare minimum is to remove c12 and maybe R3 and check the values you used for R2, R4 against the above values.

If something would be wrong with CH340g the USB connection would fail but I see no mention about that in your post.


message:
Does HC-05 module buffers the data received?

I am using HC-05 bluetooth module for sending large data(80-100KByte) from my phone to arduino-uno.
I had found that this module has a flash chip of 8Mbit  (SST39VF800A) but the datasheet of HC-05 has nothing about buffering of the data to be transmitted or data received.
I need clarity about the buffering of data so that I can change the data rate from the phone for better communication.

body:
I didn't find any help in any data-sheets I could find, either. So I'd suggest a simple experiment, sending increasingly large packets before the other side attempts to read anything, until some data goes missing. The packets don't even need to be very sophisticated if all you want to know is whether N_received == N_sent and for what maximum 'N'.

Update:

> All bytes were received correctly if there is no delay but with
> increasing delay in reading from HC-05 data was not fully received and
> with delay greater than 800ms only 63Bytes were received.

If you're collecting data as it arrives, then you can't measure the buffering. When you wait until all data has been set before you try to read any, the number of bytes you receive is the buffer size. It sounds like a 63 byte buffer, probably only what the HC-05's hardware UART can buffer, without using any of its memory to increase that.


message:
Arduino while loop with or condition

How do I write a program to wait (delay) until one out of two buttons pressed? I have written a program to wait until a single button is pressed. It's working fine. However, if I extend it to second button it's not working. Pls help on this.

1. `while (digitalRead(bt_Select) == HIGH) {}` -- working.
2. `while (digitalRead(bt_Select) == HIGH || digitalRead(bt_Reject) == HIGH) {}` -- Not working.

Complete code:

```c++
const int bt_Select = 2;
const int bt_Reject = 3;

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

void loop() {
  Serial.println("Pl input:");

  while (digitalRead(bt_Select) == HIGH {} // This is the line I change

  if (digitalRead(bt_Select) == LOW) {
    Serial.println("Select Button pressed:");
    delay(250);
    Serial.println("");
  }

  if (digitalRead(bt_Reject) == LOW) {
    Serial.println("Reject Button pressed:");
    delay(250);
    Serial.println("");
  }
}
```

body:
`while (digitalRead(bt_Select)==HIGH||digitalRead(bt_Reject)==HIGH){}`

should be

`while (digitalRead(bt_Select)==HIGH&&digitalRead(bt_Reject)==HIGH){}`

The first loop would break only if you press both buttons at once. I believe you are trying to break if either button is pressed.


message:
DFRobot GSM / GPS shield with UNO init error

Apologies, but I have little experience of Arduino etc. Has the "Sim808 init error" been resolved anywhere please? I have tried every example I can find including the ones on these StackExchange pages without success. I started with the GPS test code from:

https://wiki.dfrobot.com/SIM808_GPS_GPRS_GSM_Shield_SKU__TEL0097

Parancey, Marcello, Pooya and Arslan and others have suggested mods to this code so I have tried all of them I think - none working.

Then I watched this video:

https://www.youtube.com/watch?v=fN8fwX3KmsM

which appears to show the code below or similar:

    /*
    ### Get GPS data
    1. This example is used to test SIM808 GPS/GPRS/GSM Shield's reading GPS data.
    2. Open the SIM808_GetGPS example or copy these code to your project
    3. Download and dial the function switch to Arduino
    4. open serial helper
    4. Place it outside, waiting for a few minutes and then it will send GPS data to serial

    create on 2016/09/23, version: 1.0
    by jason

    */
    #include <DFRobot_sim808.h>
    #include <SoftwareSerial.h>

    //#define PIN_TX    10
    //#define PIN_RX    11
    //SoftwareSerial mySerial(PIN_TX,PIN_RX);
    //DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

    DFRobot_SIM808 sim808(&Serial);

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

      //******** Initialize sim808 module *************
      //while(!sim808.init()) {
      while(!sim808.checkPowerUp()) {
          delay(1000);
          Serial.print("Sim808 init error\r\n");
      }

      //************* Turn on the GPS power************
      if( sim808.attachGPS())
          Serial.println("Open the GPS power success");
      else
          Serial.println("Open the GPS power failure");

    }

    void loop() {
       //************** Get GPS data *******************
       if (sim808.getGPS()) {
        Serial.print(sim808.GPSdata.year);
        Serial.print("/");
        Serial.print(sim808.GPSdata.month);
        Serial.print("/");
        Serial.print(sim808.GPSdata.day);
        Serial.print(" ");
        Serial.print(sim808.GPSdata.hour);
        Serial.print(":");
        Serial.print(sim808.GPSdata.minute);
        Serial.print(":");
        Serial.print(sim808.GPSdata.second);
        Serial.print(":");
        Serial.println(sim808.GPSdata.centisecond);

        Serial.print("latitude :");
        Serial.println(sim808.GPSdata.lat,6);

        sim808.latitudeConverToDMS();
        Serial.print("latitude :");
        Serial.print(sim808.latDMS.degrees);
        Serial.print("\^");
        Serial.print(sim808.latDMS.minutes);
        Serial.print("\'");
        Serial.print(sim808.latDMS.seconeds,6);
        Serial.println("\"");
        Serial.print("longitude :");
        Serial.println(sim808.GPSdata.lon,6);
        sim808.LongitudeConverToDMS();
        Serial.print("longitude :");
        Serial.print(sim808.longDMS.degrees);
        Serial.print("\^");
        Serial.print(sim808.longDMS.minutes);
        Serial.print("\'");
        Serial.print(sim808.longDMS.seconeds,6);
        Serial.println("\"");

        Serial.print("speed_kph :");
        Serial.println(sim808.GPSdata.speed_kph);
        Serial.print("heading :");
        Serial.println(sim808.GPSdata.heading);

        //************* Turn off the GPS power ************
        sim808.detachGPS();
      }

    }

I have mounted the DFRobot shield on a UNO and powered through the barrel connector with a 2_amp 5V stabilised power supply. The DFRobot shield shows a red LED power light and pressing reset flashes the blue LED next to it, but nothing else does anything - the serial monitor just repeats "Sim808 init error". In the video the blue "net" LED flashes even before the SIM card is inserted, but my card does not flash. Do I return the board to Farnell and ask for my money back?

Any help greatly appreciated!

body:
The dfrobot board has a weird boot button system that you need to follow to boot up the board. I spent ages attempting to get it to work before I finally achieved anything.

There is a blue led on the board that will flash continuously at different rates if the chip has been correctly powered and is searching for a mobile network.

I noticed that you commented it the while(!sim808.init()) line. This attempts to power the board on automatically, but I do remember something being funny about the implementation.

From doing a while load of research the dfrobot breakout board is not the best hardware implementation of this chip. Actually from memory there aren't any modules I have been able to find which satisfy all my requirements for a project. I'd recommend looking at all the documentation dfrobot provide on their website. Hopefully that should get you working.

Summary: it's an insanely fiddly process to get it working, but the boards are functional


message:
How can I read the data stored in EEPROM although is powered OFF based on the simple code I wrote?

I need help regarding on EEPROM library. Based on the code below, for every 2 sec, I want to store the int for ```increase``` where it will keep increasing by 1. Then, I upload to my Arduino Nano and open Serial Monitor to let it run for about 20 seconds. The serial monitor shows that ```Increase Count:10```.

Then I unplug the Arduino Nano, closed the Serial Monitor, wait for 5 sec, then plug back to computer and turn on the Serial Monitor, then the Serial Monitor start to shows ```Increase Count:1```, which indicated it start to recount again from 1,2,3,4.....

I thought that EEPROM will store the last number it counted which is 10, then when I unplug and plug back it should continue to count from 10, 11, 12, .......

So I would like to ask community whether my execution code and the method is correct or not. If not, can you advice me on how I can execute it correctly. Thank you in advance!

```
#include <EEPROM.h>

int addr=5;
int storagedata;
int increase;

void setup()
{
  storagedata=EEPROM.read(addr);
  Serial.begin(9600);

  timevalue=millis();
}

void loop()
{
  if (millis()-timevalue>=2000)
  {
    increase=increase+1;

    EEPROM.update(addr,increase);
    storagedata=EEPROM.read(addr);

    Serial.print("Increase Count:");
    Serial.println(storagedata);

    timevalue=millis();
  }
}

```

body: The problem is that you fail to initialize `increase` during `setup()`. The variable is undefined when the code enters the `loop()` function, even regardless of whether this is the first boot or not. You should change `storagedata` to a local variable in loop() and use `increase` to keep the value (or vice versa).


body:
`increase` is a global variable and will implicitly initialized with the value zero. Then you are reading the EEPROM data into the variable `storagedata` in `setup()`. And then in `loop()` you are increasing `increase` from zero to one and write that to EEPROM. This value then gets read back into `storagedata`. So now `increase` and `storagedata` have the same value: one. So the counting begins on every reset at 1.

It is unclear, why you even have 2 variables for this. One would be enough (unless you want to test the EEPROM for some reason). **In `setup()` read the data into `increase`.** Then the counting starts with the number in EEPROM.


body:
You never use the value you read in `setup()`.  Go through your `loop()` function one line at a time:

```c
// this does not use the value read in setup, variables are initialized to 0
// so the first time through this loop it will set 'increase' to 1
increase=increase+1;

// you are updating EEPROM with the value of 'increase' which is 1 the first
// time this is executed
EEPROM.update(addr,increase);

// you are reading the '1' that was just written into 'storagedata', you have
// never used the value you read in 'setup()' and have now overwritten it
storagedata=EEPROM.read(addr);
```

I'm not sure why you have two separate variables, but in `setup()` you just need to
initialize `increase` as the value read from EEPROM:

```c
storagedata=EEPROM.read(addr);
increase=storagedata; // start with stored value instead of default 0
```


message:
Generate a true analog signal using Arduino

I am looking for a way to create a true analog output with the arduino uno. I am constantly reading an analog input on a0 pin, all i want to do is send the same signal as output. I know arduino convert the signal into pwm so have can i convert it back to true analog signal.I have a dac too but not getting proper output.

secondly, i want to send same signal by converting it into bits through Ethernet so how do i send and receive the signal.

here is my code for dac.

    #include "Wire.h"
    #include "MCP4725.h"
    MCP4725 MCP(0x60);
    uint32_t microphonePin=A0;
    uint32_t threshold=800;
    const int ledPin=13;

    void setup() {
        Serial.begin(115200);
        pinMode (ledPin, OUTPUT);
        Serial.print("MCP4725 test program: ");
        Serial.println(MCP4725_VERSION);
        if (MCP.begin() == false)
         {
           Serial.println("Could not find sensor");
         }

        MCP.begin();
     }

    void loop() {
       uint32_t sensorValue=analogRead(microphonePin);
       MCP.writeDAC(sensorValue);
       Serial.println(MCP.getValue());
       if (MCP.getValue()>threshold)
        {
          digitalWrite (ledPin, HIGH);
        }
       else{ digitalWrite(ledPin, LOW); }

      }

here is my circuit for audio amplifier

![![here is my circuit for audio amplifier][1]][1]

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

and for the speaker it is connected on DAC out.

FYI:I am able to read the data on my serial monitor form mic and i am also able to so do some operation by just using mic and GUi. I just want to here what i am saying on speaker.

body:
I see that MCP4725 uses Wire library with the default clock of 100,000 kb/sec.

At a rough estimation each call to MCP.writeDAC or MCP.getValue will be at least 32 bits long and you use three of them in each loop.

This one:

       Serial.println(MCP.getValue());
       if (MCP.getValue()>threshold)

is redundant, you should store the value in a temporary variable and use-it in both "print" and "if".

With 10us for each bit that means 1060 us for each loop. The analog read also takes 100us to complete. Over all 1160us minimum.  Is the MCP.getValue() really needed?

That means that your maximum sample frequency is 860hz and the maximum bandwidth of 430hz. I doubt that this is an acceptable bandwidth for a microphone.

Even so, the output signal will not look similar at all, you need a higher bandwidth or to limit,  if possible, the bandwidth of the input signal.

In some limits you can modify the MCP4725 library to use fast wire clock four times faster if it suits your requirements. If you also drop the two MCP.getValue() calls that will be again almost three times faster, up to 5khz.

Also you might search for faster ADC on Arduino.

Update after OP microphone amplifier schematic.

The ADC works only with positive voltages. Short the output capacitor of the amplifier!


body:
**If you want something simpler than the transistor version you can use the following as well, for the other options skip to the --here-- mark**

Oldstyle analog out. this works like a vacuum tube and while I use a LDR you can also use heat or a actual vacuum tube.

You Will Need:

 1. A low resistance LDR or multiple in parallel.
 2. A cardboard box or other box to isolate it from outside interfearance.
 3. A Led or light bulb.

How this works: while a led flashes, a LDR needs a certain time to just to values(often up to around a few ms), so this will stabilize your adc signal.

You send the desired amplitude as a pwm signal to the light source(you probably want to invert your pwm signal) which aims at the LDR. you send your sound frequency through the LDR which now works as a variable resistor.

!!Use low resistance LDR's and a bright light source to get a as low as possible resistance. with (weak)lasers, you can get a normal LDR down to around 1 to 0 ohm. but you will most likely use a led since that has more precise intensity control.
[![Ancient style analog out like vacuum tubes][1]][1]

Another simple method is the inversed of analog read in an Arduino. you basically use multiple output ports with different resistances to get a different output when done right in this case you can get around 257 different volume levels with 8 pins for the amplitude and 1 for the frequency.

**--here--**

--added this here as a simple explaination/guide--
first start with getting your microphone working, see if analogread get's some high values. if it stays at 0, 1 or another low value, then you didn't include a transistor with your microphone to boost the signal.

-For your output start with a project without a microphone to see if it is working right.
you will need to use 2 pins to power your output(excluding ground, assuming single-channel audio).
-the first one you will need for your frequency signal output. the other one is for the amplitude/volume/gain.
-We will use any type of amplifier(transistor) to merge the signals, in this case, I assume a transistor since they are cheap, simple low power, have an easy dynamic range and you most likely have them already.

-this following part can be done in 2 ways I would suggest to try way 1 first since it is most simple, logic, and fast which is great on a slow which is great in a small microprocesssor. where method 2 might seem the exact different way around but is much more precise.

Method 1: connect the frequency output pin to the emmitor pin of the transistor where the + normally goes in.
Connect the amplitude output pin to the base pin of transistor(the trigger)
add a very small capacitor(or a bigger one for tests) between the base and ground this is to convert the adc in analog voltage instead of pulses.
the collector of the transistor which you would normally connect to ground is your output.
you might want to add a small resistor after it especially if you are using it for a audio cable. you can also directly connect a very small speaker to hear the sound
for a cable(be careful withconnection arduino IO to things like a pc) you connect the output as oudio signal and the ground as ground. but check what voltage the other devices audio port supports since arduino's IO pins generate 5v

method 2.
connect the frequency out pin to the base of the transistor,
connect the ADC of the amplitude pin to the emitter pin of the transistor,
connect a capacitor of larger capacity than described in method 1 between the emitter pin of the transistor and the ground of the Arduino.
the collector is again your output, you might to as a resistor to it.
connect a wire from an analog port to the emitter pin of the transistor to read out the voltage in the capacitor for precise voltage regulation.

tinker with the values of the capacitor size.
(you now have an energy pool in front of the transistor if you know the ampere on which you are outputting you can use this to regulate the pool, otherwise you can read it using the analog feedback loop).
important to know is that if you want precise volume you use a larger capacitor, if you want fast volume differences you use a small one and intentionally use more pins to charge it. for an Arduino Uno due to low analog read speeds, I would recommend a larger capacitor or this.

extra stuff when putting your complete system together you might run into speed issues. you should therefor connect the microphone to both a digital and a analog pin. the digital pin constantly monitors the frequency and the analog pin measures the amplitude sometimes(add a small capacitor get that average amplitude).
I would also recommend turning down the analog read precision to prevent checking for all 1024 possible voltages.

for method one you can also add a extra resistor from base to ground and from the amplitude pin to base so you can more precisely calculate the voltages.

**--end of simple version--**

You can try to use 2 pins for the output signal. one of them sends the frequency digital(3 pins if you also want negative polarity audio). this output signal should go to something like a transistor or a digitally controlled potentiometer or amplifier. I will assume you use a transistor since those are most common and quite fast.
the first digital output pin should go to the emitter pin of the transistor
the second pin is used for the volume and will go to the base of the transistor. you might want to add a very small capacitor between the base and ground to reduce frequency interference(to prevent the ADC frequency from showing up in your signal).
the Collector pin would be your analog output suitable for audio.

So in basic steps:

 1. split  the signal into a digital frequency and volume. (the digital frequency can be made by seeing a signal above a certain value as high and the other as low, this works best when you use both the positive and the negative side of the soundwave otherwise you will need to chose a very low number)(the analog frequency is literally your analog value for the positive only audio, and value-512 (*-1 for negative numbers to get only positive numbers) for the full audio if you include the negative audio)
 2. Send the frequency signal to the emitter pin of your diode.
 3. Send the amplitude signal to the base pin of your diode.
 4. Connect a small capacitance between the ground and the amplitude signal.

however What Dorian said are things you might want to keep track of as well since they often indeed tend to kill of such projects because you very easily run into speed limits(analog read in a arduino ar basically 1024 digital reads(literally)).

So some tips for your cirquit:

 1. If your microphone doesn't have a transistor connected to boost the signal add it since otherwise the analog port of the arduino uno is not sensitive enough to measure the signal. you can and should fist test this using a project where you constantly analogread and print it. you can add a small capacitor between the analog port and the ground to just measure the voltage.
 2. use diodes to rectify your microphone signal, your arduino can only read positive voltage, the microphone also sends negative voltage. redirect the negative voltage to the arduino ground (you can invert the negative voltage using a transistor or some other methods to read the negative voltages as well, but I would recommend just sending the negative signals to ground since this would give the near full range as well)
 3. use 2 microphones one for frequency and one for amplitude. or connect the output of your microphone to both a analog and a digital port. you might in the last case want to use resistors to lower the current going to them this makes sure both get a accurate voltage.
 4. avoid as manny analog reads as possible, storing it is better than calling it twice
 5. use c/c++ bitmanipulations for IO, not only is it more easy to program larger systems when using them, they are also a lot faster( arduino uno has the PORTB, PORTD, PIND, PINB, DDRD, DDRB, and the a and c version(however you most often only use the D and B) predefined. bitmanipulations require very little knowledge compared to other programming methods as long as you know the port addresses, which again for the arduino uno are predefined search: arduino uno bit manipulations or arduino uno PORTB.
 6. you can sample the sound frequency using a digital port at a higher frequency than the amplitude. since sound often doesn't jump to fast in amplitude in a way that you would clearly notice. this means you could read the sound with a IO pin and write it on another IO pin, additionally you could once every interval measure the amplitude to use which makes your code a lot faster.

there are way more ways but these are easy to do.
for sending it trough internet however you need to be careful that the module you use processes those things itself so that you do not just connect a internet port since that would slow your system down even more.

For those wanting a ms paint sketch:

version one:
[![Version one resistors are optional, feedback look can be added][2]][2]

version two:
[![Version 2 can be made without resistors or feedbackloop][3]][3]

note that I just used random images from the internet you can use any capacitor and transistor that works for this, I did not check if this transistor is right for this, but it had a nice layout description in the image. the capacitor doesn't need to be ceramic, but this way you see clear legs and I don't need to focus on polarity. in general, all cheap 5v compatible transistors should work and all capacitors if they are not way too big or too small for your load.

I used descriptions rather than logos, so anyone should be able to read it as long as they have software to tell the differences in colour if they are colourblind.

**How it works**
*The transistor sends the voltage from the emittor to the collector(or the other way around based on the transistor you use). so in method 2 which also works for mosfets. we send a adc signal to the capacitor to charge it to a voltage, you should however also add a resistor to ground or a cable to a analog port, because otherwise the voltage can just build up to 5v. this capacitor which we charge becomes a analog power source. we connect it to the emmitor(or pin which you normally connect on the + side). so if we where to open up the transistor(close the cirquit) by putting a positive voltage on the base or trigger pin then you would get a output of the voltage that you put into it. so if you play the frequency digital on the base completely opening and closing the transistor then you get a voltage output similar to the voltage in the capacitor.
method one works more difficult but a transistor opens up relative to the current going from base to exit, so we use the pwm and a small capacitor to get a analog voltage on it only partly opening it, then we send the digital audio signal into the pin that you normally connect to 5v and you get that frequency payed with the transistor acting as a variable resistor*
So method one uses a transistor as a variable resistor
And method two uses the transistor or fet as a switch which uses the voltage build up in the capacitor, doesn't actually need to use pwm if you use a feedback loop.
[![Basic True analog without the transistor to create the frequency(for method 2 only)][4]][4]

  [1]: https://i.stack.imgur.com/R3yEn.png
  [2]: https://i.stack.imgur.com/SW0ZB.png
  [3]: https://i.stack.imgur.com/aANAj.png
  [4]: https://i.stack.imgur.com/DsJum.png