message:
Wire.requestFrom() not a blocking function, even though it should be(?)

I'm working on creating a simple ACK/NACK handshake between 2 Arduino's that will essentially go like this:

1. Arduino 1 signals Arduino 0 it is available
2. Arduino 0 sends a connect byte to Arduino 1 (say, 'c')
3. Arduino 1 sends a confirmation byte to Arduino 0 (say, 's')

This seems simple enough, so what I'm doing to avoid any kind of multithreading or callback functions is to use `Wire.requestFrom()`. From the wiki, this function "requests" the device at the specified address to send data. From what I understand, this "request" simply entails the master device simply blocking until it receives the necessary data. It doesn't seem to send any signal to the slave device that it should send anything, just does a simple wait. As such, I created a simple demo of this handshake between the two devices as follows:

```
// slave
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin(1);
  Wire.requestFrom(0, 1, false);
  Serial.println("finished");
}
```

```
// master
#include <Wire.h>

bool last = false;

void setup() {
  Serial.begin(9600);
  Wire.begin(0);
  pinMode(2, INPUT);
}

void loop() {
  if (digitalRead(2) && !last) {
    Wire.beginTransmission(1);
    Wire.write('c');
    Wire.endTransmission(1);
  } else if (!digitalRead(2)) {
    last = false;
  }
  delay(1000);
}
```

Here, the master code waits on a signal (pin 2) (which is given by Arduino 1) that it is available, and then on connect, will send one connect byte to Arduino 1. In Arduino 1 (slave)'s code, I've placed the requestFrom call that should block until Arduino 0 sends that connect byte.

The problem here is that it's not actually blocking. Even before I've gotten a chance to run the master's code, the slave's "finished" output has instantly triggered. Am I understanding this function incorrectly or is there something wrong in my implementation?

body:
Masters request data from the slave, not the other way around.

See <http://gammon.com.au/i2c>

Slaves set up a "receive" handler to be told that there is incoming data.

    Wire.onReceive (receiveEvent);

>  From what I understand, this "request" simply entails the master device simply blocking until it receives the necessary data.

Yes, but you don't have this request on the master, you have it on the slave. There is your problem.


sender: user

sender: assistant

body:
You completely misunderstand how I2C communication (that's what the `Wire` library does) works. I won't explain the full I2C interface here, since that is a bit too much for this answer.

`Wire.requestFrom()` doesn't block until it receives data. It will configure the I2C interface as master (when previously in slave mode this will be temporary). Then it enforces a start condition on the bus, sends the address of the slave and then sends a clock pulse for the acknowledgement bit. During this clock pulse the slave can pull the SDA line low and signal that way, that it is reachable. After that the master continues to generate the clock for all the bytes it wants, expecting the slave to control the SDA line. If the slave doesn't do that (for example because you didn't connect the `onRequest()` callback), then the received data will just be 1s (so each byte 0xFF).

So `Wire.requestFrom()` does only block for the time, that the transmission needs. If the slave doesn't acknowledge its address, the function will exit after that. The transaction will only need a few milliseconds either way.

> avoid any kind of multithreading or callback functions

On AVR based Arduinos (like the Uno or Nano) multithreading isn't really a thing (besides using a time sharing library, but still on only one core), though callbacks from interrupts are. And as long as you use the `Wire` library (and with it the I2C hardware interface of the microcontroller) you have to use interrupts and thus callback functions. And honestly there is normally no reason not to do that.

---

Another problem with what you are currently doing it, that both Arduinos act as masters on the bus. No two masters can send on the bus at the same time. While the I2C protocol has a way to determine, which master can send first, this is often implemented rather buggy. I don't know how good the `Wire` library is with this currently, but you should avoid a multi-master setup if possible.

---

A minor problem: The I2C address space has some reserved sections for special use. You can start your slave addresses at 8 (refer to the I2C specification on the web). Address 0 is meant as a general call address, so for master-write transactions, which target every slave on the bus. You shouldn't have a slave with that address.

---

**What to do now?** Just implement the code with the `Wire` library as it is meant, including the `onRequest()` callback function. Refer to the master-read example of the `Wire` library. Set the second Arduino as master and the first as slave. On the second Arduino you can call `Wire.requestFrom()` with the slaves address. This will trigger the `onReqest()` callback function on the first Arduino, where you can use `Wire.write()` to let the library send the desired data back to the master. On the master (Arduino 2) you an then read that data via `Wire.read()`. And thats it.


message:
ESP32 Rebooting while converting String to Hex Array

I wrote [this][1] code to convert String to Hex Array.

    const char* hexstring = "0x21 0x73 0x10 0xfa 0x7a 0x00 0xff .../*40995 character long string*/....0xaa"
    void setup() {
        char* temp;
        //Serial.printf("%s",hexstring);
        unsigned int number[8199];

        number[0] = strtoul (hexstring,&temp,16);
        for(int i=1;i<8199;i++)
         number[i]= (int)strtoul(temp, &temp, 16);

        for(int i=0;i<8199;i++)
            {
                if(id)
                    printf("\n");
                printf("%d, ",number[i]);
            }
    }

    void loop(){
    }

But it is causing ESP32 to reboot.
[![enter image description here][2]][2]

Could anyone help me with the reason why?

  [1]: https://drive.google.com/file/d/12ImK6y2eZ9eO5znS2TJ3GHKRzaxjviwI/view?usp=sharing
  [2]: https://i.stack.imgur.com/K03W3.png

body:
```c++
void setup() {
    char* temp;
    //Serial.printf("%s",hexstring);
    unsigned int number[8199]; <----- too much.
```

So, you're trying to put a 32796 byte object on the stack. I don't know exactly why you're seeing the manifestation that you are, but I'm not surprised.

I just took an ESP32-CAM and started playing with different sizes and found that around 1800 (`unsigned int`s) is where things start to go sideways, failing occasionally rather than constantly.  By a 2000 count, it continually reboots with `rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)` transitioning to `rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
`  and later to very roughly around 5000 it becomes `rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)`

I _may_ fill out some details later if I look into it deeper. The ESP32 and SDK is complicated enough that there may well be a function can call that will permit a higher stack level. But this is mostly to satisfy curiosity.

Putting very large things (relative to the system size) on the stack is usually not done. I hesitate to try to tell you what exactly you should do; it wouldn't surprise me if you don't need this array at all for what you ultimately want to do, but that's a _different_ question). So, I'll just say get it off the stack through either dynamic memory allocation (e.g. through `new` or `malloc`), possibly using a smart pointer (e.g. `std::unique_ptr`) to manage that since those are available on the ESP32, or perhaps just making the variable either a `static` local or global. Or again if possible finding out why you might not need this array.

### Simple minimal change

So, I'm not going to tell you that this is a good idea, but a minimal change would be to `static` qualify this as `static unsigned int number[8199];` Then you won't get that reset cause, here, for this reason.

---

### Some details for anyone curious

If you want to see some of the guts, you look in the ESP32 core for Arduino where it [creates the task][1] that [ultimately runs `setup()`][2] for you. You can see that it calls [`getArduinoLoopTaskStackSize()`][3] returning [`ARDUINO_LOOP_STACK_SIZE`][4] which by default is `8192`. 8192 **bytes,** not `unsigned int`s. With `sizeof(unsigned int)` being 4, this is _very roughly_ in the vicinity of the 1800 `unsigned int`s where things started to fall apart in my testing above. Rather than chase down the configurion I just made a sketch that does `Serial.println(getArduinoLoopTaskStackSize());` and yeah, it prints 8192.

`getArduinoLoopTaskStackSize` is a [weakly defined][5] function which would allow something to redefine in elsewhere in the program to overload the default one. So, just out of curiosity I wrote one as follows:

```c++
size_t getArduinoLoopTaskStackSize(void) {
  size_t r_size = sizeof(unsigned int [8199]); // exactly the size your array
  r_size += r_size >> 3; // add about 1/8 (or 12.5%) extra
  return r_size;
}
```

It no longer crashes. Should you do this? Probably not. But, if you ever have a legitimate reason to put a 32K array on the stack on an ESP32 it _may_ be an option. I mostly just did this to see what would happen. It's barely been tested.

  [1]: https://github.com/espressif/arduino-esp32/blob/2.0.5/cores/esp32/main.cpp#L71
  [2]: https://github.com/espressif/arduino-esp32/blob/2.0.5/cores/esp32/main.cpp#L42
  [3]: https://github.com/espressif/arduino-esp32/blob/2.0.5/cores/esp32/main.cpp#L36-L38
  [4]: https://github.com/espressif/arduino-esp32/blob/2.0.5/cores/esp32/main.cpp#L14
  [5]: https://en.wikipedia.org/wiki/Weak_symbol


message:
Arduino outputting 4.7V instead of 3.3V when using I2C communication/sensor?

TOF050C-VL6180X Sensor was not responding, so I checked it with a multi-meter, and the VIN, GND solder pins on it read 4.7V. Double-checked Mega voltage, without anything connected, and it shows stable 3.6V. Connected a different ToF and it works perfectly, with a 3.6V on it.

So that proves that sensor is damaged (might've powered it with 5V at first), but I don't understand how is it taking more than the regulated 3.3V? If it was shorted, it would read 0V, and if something burnt, it would be open circuit and show ~3.3V, right? So how is it just getting 4.7V out of nowhere? Any ideas on what I'm not understanding here?

Thank you!

**EDIT:** More info, tried to isolate issue as much as I could

**1)** The non-working sensor shows 4.7V
[![1) The non-working sensor shows 4.7V on multi-meter][1]][1]

**2)** The working sensor shows 3.4V and outputs distance to serial
[![Working sensor shows 3.4V on multi-meter][2]][2]

**3)** This is where it gets weird. I uploaded the simple blink sketch and now the working sensor shows 4.7V too

[![Working sensor shows 4.7V on multi-meter][3]][3]

**4)** So I tried **disconnecting the SDA/SCL**, while leaving power connected, with the blink sketch running, and it's back to 3.3V!

[![Arduino outputs 3.3V to sensor][4]][4]

**Tried the same steps with a different Mega, and **it always shows 3.3V, no matter the configuration!**

Now I'm very lost. So is the Arduino semi-damaged, with the I2C communication acting weird? Is it still safe to use with the project, if it *technically* works?

  [1]: https://i.stack.imgur.com/DXhSZl.jpg
  [2]: https://i.stack.imgur.com/qzoAHm.jpg
  [3]: https://i.stack.imgur.com/JpmM5m.jpg
  [4]: https://i.stack.imgur.com/kwlBbm.jpg

body:
The Arduino Wire [enables the internal pullup resistor][1] on SDA and SDL. The internal pull-ups are specified at 20k to 50k. So you *are* providing 5V (or there about) to the sensor, though through a high resistance connection. So, the voltage isn't coming from nowhere.

It is not unlikely that there protection/clamp diodes in the sensor IC or on the sensor board that connect these signals forward through the diode to the IC's 3.3v connection.

So your SCL/SDA can be seen as very weakly (through roughly 35k) trying to backfeed your 3.3V regulator which is probably just blocking the current. If the sensor/board is using no current to speak of, either because it just doesn't normally or because it's dead, you would measure 5V minus a diode drop, or roughly the 4.7V you're seeing.

If you assume the internal resistors are both at 20K as a "worst" case scenario for a calculation, the current needed through one to drop 5v to 3.3v is 85uA. So with 170uA load on the board that would drop the 3.3V pin  connection back to its 3.3V level. About 170uA will flow through a 20k resistor with 3.3V across it. So if you want experiment take any resistor from about 470ohms all the way to just shy of 20k in parallel with your 3.3V / GND measurement and see if your 4.7V measurement doesn't drop right down to the normal 3.3V output.

  [1]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.5/libraries/Wire/src/utility/twi.c#L87-L89


message:
VP230 CAN Bus Transceiver

How does one read can packets from a VP230 Can Bus transceiver? I also have a MCP2515 which I've gotten to work, but the VP230 is a lot smaller.

I haven't been able to find any information about actually implementing the VP230, any help would be great.

body: Welcome. You are talking two compatible CAN parts but they have different functions. The VP230 is the CAN bus bidirectional interface. This converts the signals on the CAN bus to logic signals your CAN controller can use. The MPC2515 is a CAN controller chip that talks to your microprocessor and the bus transceiver. The MCP2515 has only logic signals and is not compatible with the CAN bus. Together they make a good CAN bus interface. Both parts are 3V3 compatible.


message:
Conversion from `const char* datac="0x21,0x10,0xfa,0x7a,0xff";` to `uint8_t datat[]={0x21, 0x10, 0xfa, 0x7a, 0xff}`

The below reading data from API:

    #include <WiFi.h>
    #include <HTTPClient.h>
    #include <ArduinoJson.h>

    const char* ssid = "****";
    const char* pass = "****";

    void setup()
    {
      Serial.begin(115200);
      WiFi.begin(ssid, pass);
      Serial.print("COnnecting");

      while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
      }

      Serial.print("\nIP Address");
      Serial.println(WiFi.localIP());
    }

    void loop() {
      const char* root_0_id ;
      const char* root_0_Title ;
      if (WiFi.status() == WL_CONNECTED)
      {
        long rnd = random(1, 3);
        HTTPClient client;

        client.begin("https://6336d6c365d1e8ef267481aa.mockapi.io/api/bitmap/images?id=1");
        int httpCode = client.GET();

        if (httpCode > 0) {
          String payload = client.getString();
          Serial.println("\nstatuscode: " + String(httpCode));
          if (payload == "[]")
            Serial.println("\nNOT FOUND");
          else
          {

            DynamicJsonDocument doc(49152);
            DeserializationError error = deserializeJson(doc, payload);
            if (error) {
              Serial.print("deserializeJson() failed: ");
              Serial.println(error.c_str());
              return;
            }

            root_0_id = doc[0]["id"]; // "41"
            root_0_Title = doc[0]["Bitmap"];

            Serial.print("\n\nData : ");
            Serial.println(root_0_Title);

            Serial.println(sizeof(root_0_Title));
            client.end();
            dataReceived = 1;
            delay(10000);

          }

        }
        else {
          Serial.println("Error on HTTP request");
        }
      }
    }

I need help with parsing the `const char* root_0_Title="0x21,0x10,0xfa,0x7a,0xff"`, to uint8_t[5]={0x21, 0x10, 0xfa, 0x7a, 0xff}?

body:
you can use [strtok][1] (string tokenizer) and [strtol][2] (string to long) C functions.

```
  int count = 0;
  uint8_t bytes[MAX_SIZE];
  char* tok = strtok(root_0_Title, ",");
  while (tok != NULL) {
    bytes[count++] = strtol(tok, NULL, 16);
    tok = strtok(NULL, ",");
  }
```

  [1]: https://cplusplus.com/reference/cstring/strtok/
  [2]: https://cplusplus.com/reference/cstdlib/strtol/


message:
Function call only works if called once

I have 3 LED chains which are all mapped to concentric rings. Each ring has a its own 2D array with the chain number & LED number. I have a function that is passed a ring array and then lights the appropriate LED. I'm using `FastLED`

    void lightUp(int ring_arr[][2], int i, int col){

      if(ring_arr[i][0] == 0){
          L0[ring_arr[i][1]] = CHSV(col, 255, 255);
        }
        if(ring_arr[i][0] == 1){
          L1[ring_arr[i][1]] = CHSV(col, 255, 255);
        }
        if(ring_arr[i][0] == 2){
          L2[ring_arr[i][1]] = CHSV(col, 255, 255);
      }
    }

This works fine BUT only if its called once in `loop()` if I make a 2nd call none of the LEDs light up. So I can light up 1 ring at a time but if I try to light up 2 or more then nothing lights up. Anyone see anything obvious that I'm overlooking?

The full code listing,

    #include <FastLED.h>

    #define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))
    #define DATA_0 5
    #define DATA_1 6
    #define DATA_2 7
    #define NUM_LEDS 50

    CRGB L0[NUM_LEDS];
    CRGB L1[NUM_LEDS];
    CRGB L2[NUM_LEDS];

    // Rings
    int ring_1[][2] = {{0,0}, {0,1},  {0,2},  {0,3},  {1,49},
                       {1,28}, {1,29}, {1,30}, {1,31}, {1,32},
                       {1,23}, {1,24}, {1,25}, {1,26}, {1,27},
                       {1,2},  {1,3},  {1,4},  {1,5},  {1,6},
                       {1,0},  {1,1},  {2,0},  {2,1},  {2,2},
                       {2,19}, {2,20}, {2,21}, {2,22}, {2,23},
                       {2,24}, {2,25}, {2,26}, {2,27}, {2,28},
                       {2,45}, {2,46}, {2,47}, {2,48}, {2,49},
                       {0,29}, {0,28}, {0,27}, {0,26}, {0,25},
                       {0,4},  {0,5},  {0,6},  {0,7},  {0,8}};

    int ring_2[][2] = {{1,48}, {1,33}, {1,22}, {1,7},  {2,3},
                       {2,18}, {2,29}, {2,44}, {0,24}, {0,9}};

    int ring_3[][2] = {{1,47}, {1,34}, {1,21}, {1,8},  {2,4},
                       {2,17}, {2,30}, {2,43}, {0,23}, {0,10}};

    int ring_4[][2] = {{1,46}, {1,35}, {1,20}, {1,9}, {2,5},
                       {2,16}, {2,31}, {2,42}, {0,22}, {0,11}};

    int ring_5[][2] = {{1,45}, {1,36}, {1,19}, {1,10}, {2,6},
                       {2,15}, {2,32}, {2,41}, {0,21}, {0,12}};

    int ring_6[][2] = {{1,44}, {1,37}, {1,18}, {1,11}, {2,7},
                       {2,14}, {2,33}, {2,40}, {0,20}, {0,13}};

    int ring_7[][2] = {{1,43}, {1,38}, {1,17}, {1,12}, {2,8},
                       {2,13}, {2,34}, {2,39}, {0,19}, {0,14}};

    int ring_8[][2] = {{1,42}, {1,39}, {1,16}, {1,13}, {2,9},
                       {2,12}, {2,35}, {2,38}, {0,18}, {0,15}};

    int ring_9[][2] = {{1,41}, {1,40}, {1,15}, {1,14}, {2,10},
                       {2,11}, {2,36}, {2,37}, {0,17}, {0,16}};
    // Colours
    int col_1 = 0;
    int col_2 = 160;
    int col_3 = 96;

    void setup(){

       // LED set up
       FastLED.addLeds<WS2811,DATA_0,RGB>(L0, NUM_LEDS);
       FastLED.addLeds<WS2811,DATA_1,RGB>(L1, NUM_LEDS);
       FastLED.addLeds<WS2811,DATA_2,RGB>(L2, NUM_LEDS);
       FastLED.setBrightness(255);
       clearAll();
    }

    void loop()
    {

      for(int i; i < NELEMS(ring_1); i++){
        lightUp(ring_1, i, col_1);
      }

      for(int i; i < NELEMS(ring_2); i++){

    //    lightUp(ring_2, i, col_2); // if I uncomment any of these
    //    lightUp(ring_3, i, col_3); // no LEDs light up
    //    lightUp(ring_4, i, col_1);
    //    lightUp(ring_5, i, col_2);
    //    lightUp(ring_6, i, col_3);
    //    lightUp(ring_7, i, col_1);
    //    lightUp(ring_8, i, col_2);
    //    lightUp(ring_9, i, col_3);

      }

      FastLED.show();
      delay(1000);
    }

    void clearAll(){
      for(int i; i < NUM_LEDS; i++){
        L0[i] = CHSV(0, 0, 0);
        L1[i] = CHSV(0, 0, 0);
        L2[i] = CHSV(0, 0, 0);
      }
      FastLED.show();
    }

    void lightUp(int ring_arr[][2], int i, int col){

      if(ring_arr[i][0] == 0){
          L0[ring_arr[i][1]] = CHSV(col, 255, 255);
        }
        if(ring_arr[i][0] == 1){
          L1[ring_arr[i][1]] = CHSV(col, 255, 255);
        }
        if(ring_arr[i][0] == 2){
          L2[ring_arr[i][1]] = CHSV(col, 255, 255);
      }
    }

body:
Your `for` loops are missing an initialization. You should write

```c++
for (int i = 0; i < NELEMS(ring_1); i++)
```

but you missed the `= 0` part. This means the `i` variable ends up
uninitialized, and contains whatever was left in this memory location by
whatever used that memory before. The behavior in such situation is
generally unpredictable. However, one may guess that the `i` of the
second loop could be allocated in the same spot as the `i` of the first
loop. If this happens, then the second loop starts at `i=3` and ends up
being an empty loop.

As a (completely unrelated) side note, you could gather your three `L*`
arrays into a single 2D array. This would make `lightUp()` significantly
simpler:

```c++
void lightUp(int ring_arr[][2], int i, int col) {
    L[ring_arr[i][0]][ring_arr[i][1]] = CHSV(col, 255, 255);
}
```

or maybe it would be clearer like this:

```c++
void lightUp(int *location, int col) {
    L[location[0]][location[1]] = CHSV(col, 255, 255);
}
```

To be called as `lightUp(ring_1[i], col_1);`.


message:
Shiftout only handles one shift register at a time

I am making a 7x10 led matrix and I am having problems with the shiftout function. It is only able to show me the output in one shiftout register at a time. How can I fix it?
[![enter image description here][1]][1]

For example:
```arduino
void setup(){
    // PORTB as output.
    // Pin 13: Clock 74HC595
    // Pin 12: Latch
    // Pin 11: Data
    // Pin 10: Reset
    // Pin 9: Clock CD4017
    DDRB = 0b111111;
    // Makes sure the 4017 value is 0.
    PORTB = 0b100;
    delayMicroseconds(5);
    PORTB = 0;
}

void loop(){
  shiftOut(11, 13, LSBFIRST, 0b1000111101);
  PORTB = 0b10000;
  delayMicroseconds(800);
  PORTB = 0;
  delay(10000);
}
```
This is the output it produces:

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

But with numbers of 8 bits or less the output is displayed correctly.

shiftOut(11, 13, LSBFIRST, 0b10001111);
[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/uxGrU.png
  [2]: https://i.stack.imgur.com/9AXCu.png
  [3]: https://i.stack.imgur.com/DBcas.png

body:
Have a look at the implementation of `shiftOut()` (you can find it where you installed the Arduino IDE in the file `hardware/arduino/avr/cores/arduino/wiring_shift.c`):

    void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
    {
      uint8_t i;

      for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST) {
          digitalWrite(dataPin, val & 1);
          val >>= 1;
        } else {
          digitalWrite(dataPin, (val & 128) != 0);
          val <<= 1;
        }

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
      }
    }

Do you see, that the value (parameter `val`) is of type `uint8_t`, so only 1 byte big? And do you see, that the for loop only counts to 8 (one iteration for each bit in a byte)? This means, that the `shiftOut()` function only handles one byte at a time. When you want to shift out more bits than 8, you need to call it repeatedly.

In your first example the code behaves accordingly. The provided data gets cast to `uint8_t`, cutting away the upper 2 bits.


body:
`shiftOut` works on bytes. To do more than one byte you have to do more than one `shiftOut`. Also you have to take note of the bit ordering. You should shift the most significant bit first, not the least.

For example, this:

```c++
  shiftOut(11, 13, LSBFIRST, 0b1000111101);
```
should be:
```c++
  shiftOut(11, 13, MSBFIRST, 0b10);
  shiftOut(11, 13, MSBFIRST, 0b00111101);
```


message:
How do I control the speed of a 2-wire fan with an Arduino and only a potentiometer?

I am trying to vary the speed of a 2-wire fan by using a Arduino Uno and only a potentiometer.

Initially, I assumed that I could go about doing so by using a code that I used for dimming an LED. When I have run the code and varied the potentiometer, the LED on the power supply changed but, the fan did not come on. I assume that this was due to an error in the first code.

In the second code, the fan also did not come on. I am unsure if it was my wiring. I have an voltage supply connected to a breadboard to power the fan.

Additionally, would I require a mosfet or transistor despite using a potentiometer? This could have also be the problem regarding my second attempt.

**First Code Attempt:**
```
int potPin=A2;
int gPin=9;
int potVal;
float LEDVal;
int dt=250;
void setup() {
  // put your setup code here, to run once:
pinMode(potPin, INPUT);
pinMode(gPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
potVal=analogRead(potPin);
LEDVal=(255./1023.)*potVal;
analogWrite(gPin,LEDVal);
Serial.println(LEDVal);
delay(dt);
}
```
**Second Code:**

```const byte CONTROL = 9;
int reading;
int value;

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

void loop() {
  reading = analogRead(POTENTIOMETER);
  value = map(reading, 0, 1024, 0, 255);
  analogWrite(CONTROL, value);
}```

body:
Like people have already mentioned in the comments, you likely need to add a FET to drive the fan. The Arduino simply can't put provide the current required to drive the fan. According to the Arduino documentation, the microcontroller can only provide 20mA per output pin, which is enough to drive LEDs but not fan motors.

Luckily, there is a tutorial on the Arduino website for driving motors with PWM through a FET.
https://docs.arduino.cc/learn/electronics/transistor-motor-control

The following program is adapted from the ["Analog In, Out Serial" built-in example][1] and should be sufficient to control the speed of the motor.

<!-- language-all: lang-C++ -->

    // These constants won't change. They're used to give names to the pins used:

    const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to

    const int analogOutPin = 9; // Analog output pin that the FET is attached to

    int sensorValue = 0;        // value read from the pot
    int outputValue = 0;        // value output to the PWM (analog out)

    void setup() {

    // declare the ledPin as an OUTPUT:
    pinMode(analogOutPin, OUTPUT);
    }

    void loop() {

    // read the analog in value:
    sensorValue = analogRead(analogInPin);

    // map it to the range of the analog out:
    outputValue = map(sensorValue, 0, 1023, 0, 255);

    // change the analog out value:
    analogWrite(analogOutPin, outputValue);

    // wait 2 milliseconds before the next loop for the analog-to-digital
    // converter to settle after the last reading:
    delay(2);
    }

This program has not been tested and is intended as an example. Make sure that the output for the FET is wired to a pin that can output PWM. Then make sure that your program is referencing the correct pin.

Make sure that your power supply has enough power to control the fan motor as well.

Here are some wiring diagrams from the tutorial webpage.

[![Transistor Motor Control Diagram][2]][2]
[![Transistor Motor Schematic][3]][3]

Note: The particular fan that you are using might not be able to be driven by PWM and you should seek out and read the relevant documentation for the fan.

  [1]: https://docs.arduino.cc/built-in-examples/analog/AnalogInOutSerial
  [2]: https://i.stack.imgur.com/tve31.png
  [3]: https://i.stack.imgur.com/3WuXI.png


message:
"Cast" BluetoothSerial to HardwareSerial

I have a function that accept an `HardwareSerial` class as argument:

    void ProcessLine(HardwareSerial *serial, char *line)
    {
        // do something
        serial->write("blablabla");
    }

In my code I also have a `BluetoothSerial` that shares the required functions (i.e. `write()`) with `HardwareSerial`.

To avoid to duplicate the code of my `ProcessLine()` that is quite long, is there a way to "cast" a `BlutoothSerial` to a `HardwareSerial`?

body:
No, you don't "cast" between them. Instead you make use of *polymorphism*.

In the Arduino framework most classes fit into a "tree" with similar classes "hanging off" a common parent "branch".  In this case both `BluetoothSerial` and `HardwareSerial`, being both serial classes, are both children of the `Stream` class.  Indeed it is this `Stream` class (which itself is a child of the `Print` class) which gives these objects most of their functions.

So unless you *need* access to some function that is specific to the `HardwareSerial` class (such as the `.begin(...)` function) you should always work up the tree to the class that provides the most restrictive set of functions that suit your needs. In this case, since you are only printing data, it would be the `Print` class.  If you were reading data you would choose the `Stream` class.

So if you change your function to accept `Print *serial` instead of `HardwareSerial *serial` then it will accept *any* object that ultimately inherits from the `Print` object - so any serial objects, any network stream objects, etc.


message:
Why does Serial.print(1) cost 228 bytes more program memory compared to Serial.print((char)(48+1))?

Just discovered this. When I cast an int to a char inside a Serial.print statement it costs way less program memory. I'm not sure why. Could someone explain this to me?
In the following example the difference is 228 bytes!

```
Serial.print(1); // 1676 bytes program storage space. 184 bytes of dynamic memory.
```

```
Serial.print((char) (48 + 1)); // 1448 bytes program storage space. 184 bytes of dynamic memory.
```
EDIT: Adding from different comments:
```
Serial.print('1'); // Sketch uses 1448 bytes program memory, 184 bytes dynamic memory
```
```
Serial.write(48 + 1); // Sketch uses 1448 bytes program memory, 184 bytes dynamic memory
```
EDIT: For an int > 9, adding quotes in following example saves 218 bytes program memory but adds 4 bytes to dynamic memory usage.
```
Serial.print(123); // 1676/184 bytes
Serial.print("123"); // 1458/188 bytes
Serial.print(String(123)); // 2772/194 bytes
```
EDIT2: Max digits in Arduino-uno int is 5(?). You save 80 bytes by converting it to a char array, in comparison to just printing the integer:
```
Serial.print(12345); // 1676/184 bytes
```
```
char digits[5];
int number = 12345;
for (int i = 4; i >= 0; i--) {
  digits[i] = (number ) + 48;
  number /= 10;
}
Serial.print(digits); // 1596/184 bytes
```
To test for yourself, uncommenting one or the other:

```
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print(1); // uses 1676/184 bytes
  //. Serial.print((char) (48 + 1)); // uses 1448/184 bytes
  //  Serial.print('1'); // uses 1448/184 bytes
  //  Serial.write(48 + 1); // 1448/184 bytes
  //  Serial.print(123); // 1676/184 bytes
  //  Serial.print("123"); // 1458/188 bytes
  //  Serial.print(String(123)); // 2772/194 bytes
  //  Serial.print(12345); // 1676/184 bytes | 1676/184
  //  Serial.print("12345"); // 1458/188 bytes | 1460/190
  //  char buff[5];
  //  itoa(12345, buff, 10);
  //  Serial.print(buff); // 1604/184 bytes
  char digits[5];
  int number = 12345;
  for (int i = 4; i >= 0; i--) {
    digits[i] = (number ) + 48;
    number /= 10;
  }
  Serial.print(digits); // 1596/184 bytes
}
void loop() {
  // put your main code here, to run repeatedly:

}
```
EDIT: Second question: Shouldn't this be optimised somehow? Or should I always take care of this myself? And why/how? ;)

**the chars 0-9 have a decimal value of 48-57 in the Ascii table, hence (char)(48 + 0-9) prints 0-9*

body:
The difference is simply this:

* Print this character

and

* Interpret this integer as a sequence of digits, work out the ASCII characters that represent each digit in turn, and print them.

As you can see even just writing out what the second one does takes more words. Printing an integer is a lot more work than just printing one character.  Think about what it takes to print the value 2034578 and how you would do that given that you can only output individual numbers 0-9 and the data isn't stored as the numbers 0-9 but a series of just 0 and 1...

It takes work. Lots of work.


message:
ESP_ATMod and its many library dependencies

I'm trying to install https://github.com/JiriBilek/ESP_ATMod onto an ESP8266. The sketch has Includes to many libraries. Those libraries have includes to other libraries and so on. Do I have to manually follow all these dependencies and download them to compile and upload my sketch? Or is there an easier way.

body:
An Arduino sketch is a folder not a file. The ESP_ATMod sketch has 11 files:
```
asnDecode.cpp
asnDecode.h
command.cpp
command.h
debug.h
ESP_ATMod.h
ESP_ATMod.ino
settings.cpp
settings.h
WifiEvents.cpp
WifiEvents.h
```

The sketch doesn't include libraries which would require installation. It uses only libraries bundled with the esp8266 platform: EEPROM, ESP8266mDNS, ESP8266WiFi and LittleFS. You don't have to install any libraries.

You can download all the files at once with "Download ZIP":

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

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


message:
Display issues with 4 Digit, 14 segment

I have this HT16K33 4 Digit 14-segment display I got brand new.
I connected it to my Arduino UNO, wired it up and uploaded some quick test code.
However, the display looks completely broken (see image below), only some segments turn on.

[![broken display][1]][1]

I soldered the connection pins to the HT16K33 board (see picture below). My solder isn't the best but it also shouldn't be too bad.

[![Solder][2]][2]

I did a quick resistance check on the connection pins to see if the pins were soldered correctly, and they seemed good. I'm not too sure how to test the ji2c pin though...

[![multimeter_test][3]][3]

Here is the Wiring on my breadboard:

[![Wiring][4]][4]

Finally here is the code i'm currently using:

    #include "HT16K33.h"
    #include <Wire.h>
    HT16K33 seg(0x070);

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      Wire.begin();
      if(!seg.begin()){
        Serial.println("ERROR");
        while(1);
      }
      Wire.setClock(100000);

      Serial.println("displayTest()");
      seg.displayOff();
      delay(1000);

      seg.displayOn();
      seg.displayClear();
      seg.displayInt(5);
    }

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

    }

I'm a bit troubled here and confused at what's going on... Help would be greatly appreciated

  [1]: https://i.stack.imgur.com/ylxVf.jpg
  [2]: https://i.stack.imgur.com/ECc5T.jpg
  [3]: https://i.stack.imgur.com/wYMke.jpg
  [4]: https://i.stack.imgur.com/Qmdv8.jpg

body:
so @6v6gt's comment made me re-search for a library for a 14-segment HT16K33. It seems he/she was in the money since it started working after switching library. While I couldn't find any yesterday, I found this page today which covers 7-segment and 14-segment HT16K33:
https://learn.adafruit.com/adafruit-led-backpack/0-54-alphanumeric?view=all#library-reference-3052482

So I switched from the HT16K33 library to the "Adafruit_LEDBackpack" and "Adafruit_GFX" Libraries.

[![leds working][1]][1]

Code for those wondering:

    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include "Adafruit_LEDBackpack.h"

    Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();

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

    alpha4.begin(0x70);  // pass in the address

    alpha4.writeDigitAscii(0, 'A');
    alpha4.writeDigitAscii(1, 'B');
    alpha4.writeDigitAscii(2, 'C');
    alpha4.writeDigitAscii(3, 'D');
    alpha4.writeDisplay();
    }

    void loop() {
    }

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

One question I have is (which is an entirely different subject), how do I go from here to rotate the letters and alphabet 180 degrees?


message:
Voltage drop when power from AA batteries

I am using a **Arduino MKR 1010 Wifi** board to control **4 servo** (PS-1109MG). All the circuit is powered by **4 AA rechargeable batteries** (1.2V * 4). Arduino is powered through the **Vin port**.

Below is a circuit just to show how they are connected (board type and other details is not correct).
[![circuit][1]][1]

When all the servos move, the arduino's LED oscillates in intensity. I deduced that the servos have a high instantaneous current consumption and the voltage of the batteries drops too much. I measured this with an oscilloscope.

[![scope image][2]][2]

The voltage drops to around 4V when the servos try to move. When the Arduino MKR is powered from the usb port and the servos from the batteries, everything works fine.

How can I reduce the voltage drop on the batteries, to use them as the only power source?
Could I use some electrolytic capacitors to reduce the voltage drop?

  [1]: https://i.stack.imgur.com/dnUag.jpg
  [2]: https://i.stack.imgur.com/Dw7r4.png

body:
Consider several options:
 1. Larger batteries.  The type of battery was not specified.  For comparison [a NiMH AA is on average about 800 mAh where a NiMH D is on average about 6600 mAh][1].
 2. Use two sets of batteries.  Connect both battery grounds, all the servo grounds and the Arduino ground together.  Only connect the positive of one set of batteries to the Arduino.  Only connect the positive of the other set of batteries to the servos.  Do not connect the positive Arduino terminal with the positive servo terminals!
 3. Using software, only operate one servo at a time.  Some (most) servos will stop moving if the position pulse is not seen by the servo.

  [1]: https://en.wikipedia.org/wiki/List_of_battery_sizes


body:
You have a 1V drop from about 5V or a 25% load regulation error you know that you have excessive load and for active servos this is a result of the DC coil resistance of the motors that are active.

- If you knew the motor coil resistance then for a transient servo seek, the surge voltage drop can be predicted from the ratio of the load to total resistance (Load+Rs of batteries)
- the main Rule of Thumb to learn is the series resistance adds with batteries in series and reduces with batteries in parallel and thus larger capacity. So you expect the product or Rs and Ah to be constant within some family of same chemistry and brand name.

But there may be sources of deviations to test results so the method must be specified or the same to compare.

- the Rs of batteries rises sharply as state of charge SoC drops below 10%  and gradually with repeated sweep tests but lowers gradually with rising temperature.

Let's compare different brands of NiMH (AA vs C) and see how close this is.  You can try your own plots to measure the slope of bulk resistance from the VI plots  ΔV / ΔI = Rs [Ω]

 1. https://eneloop101.com/batteries/eneloop-test-results/
 2. https://lygte-info.dk/review/batteries2012/Enesense C 4300mAh (White) UK.html
 3. http://lygte-info.dk/review/batteries2012/Eneloop AA BK-3MCCE 1900mAh (White) UK.html

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

This means changing these products from AA to C results in 31% Rs which equates to a voltage drop and 226% of the AA's Ah capacity.

Eneloop is known to be a reliable high-performance NiMH brand.
Your batteries may have less performance.  You can measure your motor resistance and see if upgrading size or quality and/or cost of batteries to get the performance you need.

The LED fluctuation is a different problem from not using a constant current driver.

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


body: Welcome! You picked a good place to connect the batteries when fully charged but it is the wrong place. You can use the Vin pin to Power your Arduino with an regulated or unregulated 7 to 12-volt power source. Like several AA batteries in series or a wall adapter that is in the range of 7 to 12 volts. Alternatively, you can power your Arduino through the 5V pin with an external regulated 5V power supply. Leave the 9V batteries for the smoke detectors they do not work very well.


message:
Arduino Mega, 6 push buttons for each analog input (A0-A9) - closing one results in reading by other

On day to day basis I'm more of a high level programmer, with little electronics knowledge, apologies in advance if I lack some nomenclature or basics. I communicate with my Arduino Mega via firmata, so won't really bother with code as I believe my issue is 100% hardware issue (if proven wrong I'll share details surely)

I'm creating a 'keyboard' with 60 arcade style push buttons (2pin), and I distinguish them by different resistance when circuit closes with A0-A9 (10 analog pins, 6 buttons each), and I need the rest of the pins for other functionalities.

I've created a circuit similar to this fritzting schema:
[![enter image description here][1]][1]

So my issue is: when press button A0/button 1, pins A1 & A2 also read the same value. If I press A0/button 2, I get a different value and can determine which button in A0 was pressed, but again - A1 & A2 also read this, even though I didn't press them.

I suspect I might've taken a different approach or even out of the box "keyboard" chips, but this is the route I've taken.

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

How do I make it so when I press A0/button 1, A1/A2 doesn't read the value? Do I need separate V5? Or I simply need to put the wires differently somehow?

Update: as per **chrisl** comment

I've updated the circuit by adding a resistor for each button group:

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

And that has solved my issue.

  [1]: https://i.stack.imgur.com/2p9W2.jpg
  [2]: https://i.stack.imgur.com/5i4SO.jpg
  [3]: https://i.stack.imgur.com/iYPke.jpg

body:
Of course all three analog inputs show the same value. You have literally connected them to each other. Each green wire is connected to a red wire, which leads to the resistor at the bottom. Thus all three inputs are tied together.

You can fix this by using one bottom resistor for each group of 2 buttons, each connected between 5V and the analog input/button system.

And when using analog inputs for multiple buttons the binary resistor latter is an interesting concept, which might give you more buttons per analog input (depending on the noise in your environment). Though the typical way to read so many buttons would be using an additional chip/microcontroller to scan the buttons in a matrix style arrangement. With your current circuit you still need 30 analog inputs.


message:
Lag in sensor reading when Arduino Powered with 12V adaptor

So I am trying to power an arduino to measure water flow. It works all fine and dandy when I am powering it with laptop, but when I directly power it with 12V 1.5A adaptor the readings take a second to come to the LCD even though the pump starts running. Also when they come, I can see that sometimes it hangs. Why is that?

Before taking the readings I am switching on a motor which is also directly powered by the adaptor just like the arduino.

Below is a block diagram.

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

Would adding a voltage regulator that steps down 12V to 9v between arduino and adaptor help?

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

body:
Your power supply is actually advertised at 1.2 Amps.  It's assumed you are powering the Arduino, the Relay, the Water Valve Solenoid and the Water-Pump-Motor all w/the same 1.2A power supply.  It is within reason that the sum of all those loads exceeds your power supply's capabilities.

> It works all fine and dandy when I am powering it with laptop ...

It is assumed you were only powering the Arduino with the laptop.  Providing the Arudino with an independent power source is a common solution to this type of problem.  Obtaining a larger power supply (more Amps) is another possible solution.

Why does it eventually work?

Motors require more Amps when under a physical load.  If the water is stationary, the motor will have to "get it moving" requiring more current. The term "locked motor current" is used [here in this article][1].

Also, inductor loads require more Amps when ever the voltage potential is suddenly changed.  The motor and relay are likely both seen as inductive loads.  This is referred to as [inrush current][2].

Both of these can be assumed transitory.  Once the motor is moving and after the potential across the inductive loads are closer to zero, the initial current demand will subside and the power supply may then be capable of sustaining the constant voltage needed by the Arduino's processor.

Alternate solution:

Obtaining a larger power supply is likely the better solution.  Another option involves filtering the power only for the Arduino.  This option is discussed [in this thread][3] on forum.arduino.cc where a diode and capacitor are used to somewhat isolate the power for the motor, relay and solenoid from the Arduino.

  [1]: https://www.jadelearning.com/blog/understanding-motor-starting-inrush-currents-nec-article-430-52/
  [2]: https://www.sunpower-uk.com/glossary/what-is-inrush-current/
  [3]: https://forum.arduino.cc/t/noise-filter-for-uno-power-supply/228542


body: Welcome. Your pump is turning on as soon as the power is turned on because the relay is connected to 5V. Your processor needs to initialize itself and then the display, the pump is up and running. On your laptop the pump was powered from the power supply and the Arduino by the laptop. The arduino was on and up and running when the pump was started. Hope this helps. I will take a SWAG and say this is powered up when the pump is needed and powered down when it is not needed.


message:
Library files multiple users

I want to place all of my libraries on the server. Currently the sketches work fine and as far as I know the libraries are coming from the individual linux mint machines using cinnamon, releases vary depending on machine. I can move the libraries etc but what do I do to the IDE 1.8.18 and 1.8.19? to make it follow that path.

body:
Arduino IDE can use libraries only from 3 locations.

1) libraries folder in sketchbook folder
2) libraries folder of selected board's platform
3) libraries folder in IDE installation folder (only IDE 1, not IDE 2)

There is no option to configure other paths and absolute or relative paths don't work in `#include` directive with the Arduino build process.

The only way to use libraries from a different location is to link with means of the operating system the folder with the library into one of the searched locations.


message:
Coorect syntax for setCACert ESP8266

I am trying to use a cert with an ESP8266 the identical code works fine on ESP32 but for the ESP8266 I am getting errors.

I set the cert as follows

```
const char *ROOT_CERT PROGMEM = R"EOF(= "-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
...
-----END CERTIFICATE--------)EOF";
```
For the ESP32 I use

```
wifiClient.setCACert(ROOT_CERT)
```
Which works fine but on the 8266 I get.

```
no matching function for call to 'BearSSL::WiFiClientSecure::setCACert(const char*&)'
```
I have done some research and there is some suggestions the length is required so I tried that also

```
 wifiClient.setCACert(ROOT_CERT,sizeof(ROOT_CERT)-1);
```
But that produces the following error.

```
invalid conversion from 'const char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]
```
I am using the 2.7.4 8266 board library as I have heard the 3.X has similar issues.

I have tried V 3.X but I get the following
```
class BearSSL::WiFiClientSecure' has no member named 'setCACert'
```

body:
i could not use setCACert with 8266.  you need to do it differently and i had to do some web hunting.
But finally i did get my telegram test working from esp32 to 8266,
 here is what i did and hope that you can adapt it

you need :

    #include <ESP8266WiFi.h>

after your defines add:

    X509List cert(TELEGRAM_CERTIFICATE_ROOT);
    WiFiClientSecure client;
    UniversalTelegramBot bot(BOTtokenValue,client);

in setup i had to add BOTH of these lines (i initially didnt think i needed the 1st line, but apparently you do) :

    configTime(0, 0, "pool.ntp.org");   // get UTC time via NTP
    client.setTrustAnchors(&cert);      // Add root certificate for api.telegram.org

this got my ESP32 code converted from ESP32 to 8266


message:
Blue pill acting as if it had 10bit ADC

I just got myself a STM32F103C8 Blue pill board. I am having funny behaviour with the analog readings. It behaves as if the unit was 10bits and not 12 bits.

I uploaded the very trivial Arduino code below. Just to read the analog input A0.

    void setup() {
      Serial.begin(38400);
    }
    void loop() {
      Serial.println(analogRead(A0));
      delay(1000);
    }

If I connect pin A0 to the 3.3v I get this output below.

    1022
    1022
    1023
    1022
    1022
    etc...

If I connect to a 1.5V source the above values becomes around 500.

It all behaves as if it was 10bits really which I fail to understand. Any ideas why?

body:
If you run Arduino code on it, maybe it makes sense to have 10-bit ADC readings on this platform too like on all other Arduino platforms. Unless you configure the libraries to return full 12 bit, if even possible.

This is more an Arduino platform question though.


body:
Adding the following line in the setup() section solves the problem.

    analogReadResolution(12)


message:
Creating an AC pulse with arduino and perhaps components

I want to create an AC PWM pulse with arduino. The microcontoller, will be also responsible for specifying the frequency (which will be around 500 Hz).

External electronic components can also be used. Like an H-Bridge perhaps.

EDIT: This is the final waveform I want to produce:
[![enter image description here][1]][1]

I know the arduino is not capable of producing 36 V output. I plan to just create this waveform, with whatever the arduino can output  and then step up the voltage. But this is the final waveform that I want produced.

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

body:
Yes, you want a H-bridge. That is the simplest way to make that "negative*" voltage.

But you can't just create a square wave and throw it blindly at a H-bridge, you have to be much more careful, otherwise you will cause short circuits and dissipate massive amounts of power.

You will need a "discrete" H-bridge where you have proper control over each transistor, and the best way of doing that is with discrete transistors (MOSFETs are best).

The important thing to remember though is than no transistor ever turns off or on instantaneously - so you have to add a "dead zone" into your waveform.  Turn one pair of MOSFETs off, then wait a moment, before turning the other pair on. Otherwise you get a brief overlap in the switching where massive currents can flow straight through everything as all the MOSFETs are turned on (or partially on) at the same time.

Some microcontrollers have programmable dead zones in their PWM outputs, but I am not sure if the AVR chips do - you'll have to check the datasheet - but it's not too hard to arrange a suitable waveform in software or using timers and interrupts (you could look at the `tone()` function and support code for some ideas for the latter).

The programming sequence, if you have 4 outputs H1/H2/L1/L2 for the HIGH and LOW sides of the H bridge pairs 1 and 2, would be:

1. Turn on H1 and L2
2. Pause
3. Turn off H1 and L2
4. Brief Pause
5. Turn on H2 and L1
6. Pause
7. Turn off H2 and L1
8. Brief Pause
9. Repeat

You haven't specified what your load is, but with an H-bridge it is important to remember that the output is not referenced directly to ground but ground alternates from side to side. If you want to properly isolate it from the Arduino ground a transformer can be used as the load to the H-bridge then use the output of the transformer to drive your real load. You can also use the transformer to change the output voltage (the ratio of windings is the same as the ratio of input to output voltage - so a 1:1 winding transformer will give the same voltage out as it gets in).

----
* "Negative" only that the current flows the opposite way through the load, not an actual negative voltage WRT to Arduino GND.


message:
1Hz & 32Hz from 32.768 kHz on ATmega328P at 8MHz & DS3231 32K

I have a 32.768 kHz signal at the ATmega328P input.
I need to get 2 signals from this signal: 1Hz and 32Hz.
How well will it work?
How to do this with a ATmega328P Timer/Counter?
What gain will the Timer/Counter give compared to my solution?

    void setup() {
       pinMode(S32768Hz_PIN, INPUT_PULLUP); // 32.768 kHz signal
       attachInterrupt(digitalPinToInterrupt(S32768Hz_PIN), s32768Isr, FALLING); // Pin 3
    }

    volatile bool s32768IsrWasCalled = false;  // ISR flag 32768Hz
    void s32768Isr() {
       s32768IsrWasCalled = true;
    }
    uint16_t s32Counter = 0;
    uint16_t s1Counter = 0;

    void loop() {
      if (s32768IsrWasCalled) {
          s32768IsrWasCalled = false;
          s32Counter++;
          if (s32Counter == 1024) {
            s32Counter = 0;
            // 32Hz
          }

          s1Counter++;
          if (s1Counter == 32768) {
            s1Counter = 0;
            // 1Hz
          }
      }
    }

Update 24.10.2022
I wrote my first timer 1 setup code. Will this run 32 times per second, indefinitely?

    // ATmega328P 3.3V 8MHz, Timer 1 & DS3231 32768 Hz
    void setupTimer1() {
        // Disables all interrupts
        cli();
        // Reset bits
        TCCR1A = 0;
        TCCR1B = 0;
        // Enable Timer 1 overflow interrupt (TOIE1)
        TIMSK1 = (1 << TOIE1);
        // PWM mode. Mode #7 (fast PWM, top is fixed at 10 bits = 1024)
        TCCR1A |= _BV(WGM10) | _BV(WGM11);
        TCCR1B |= _BV(WGM12);
        // External clock on T1 pin, on falling edge (DS3231 32768Hz pin)
        TCCR1B |= (1 << CS11) | (1 << CS12);
        // Enables interrupts
        sei();
        // pinMode(T1_pin, INPUT_PULLUP); ?
    }

    void loop() {
        // So get 1 Hz from 32 Hz?
        // There will be no data races here?
        if((pulse_counter % 32) == 0) {
            callback1Hz();
        }

        if((pulse_counter % 2) == 0) {
            callback16Hz();
        }
    }

    volatile uint8_t pulse_counter;
    // Timer 1 Overflow (32 Hz)
    ISR(TIMER1_OVF_vect) {
        pulse_counter++;
    }

Thank you!

body:
I did not test your program but, just by looking at it, I would expect
it to work... provided you do not add more code! Obviously you will need
to add more code in order to do something useful with those signals, and
then thinks might break.

The problem with this approach is that the interrupt rate is pretty
high: the program gets interrupted every 30.5 µs. You may miss an
interrupt if either:

 1. it fires while there is already an interrupt (or other critical
    section) being processed, and that interrupt (maybe combined with
    some other pending interrupt) takes more than 30.5 µs to
    complete

 2. you add more code to `loop()` and that function ends up taking more
    than 30.5 µs.

The first condition should be obvious, but I would assume the risk is
quite low, as only a very poorly written ISR would take that long to
complete. Beware however of library code, as that might bring surprises.

The second condition is a bigger risk, although maybe less obvious. The
problem is that this `loop()` assumes the code within
`if (s32768IsrWasCalled)` is going to be called exactly once per
interrupt. This may not be the case: if the program gets bigger, you may
miss interrupts, and get the frequencies wrong.

A simple way to avoid the issue number 2 is to count the pulses within
the ISR, as PMF suggests in a comment. I would use a single counter for
this, and make it unsigned in order to guarantee that it wraps around
reliably:

```c++
volatile uint16_t pulse_counter;
void s32768Isr() {
    pulse_counter++;
}

void loop() {
    int signal_32Hz = (pulse_counter >> 9) & 1;
    int signal_1Hz = (pulse_counter >> 14) & 1;
}
```

Note that this is one of the few cases when you can access the volatile
multi-byte variable without disabling interrupts: since you only ever
care about one bit, there is no data race.

A better option, though, would be to use a hardware timer for this job.
I would suggest using Timer 1 in “counter” mode (external clock
source on pin T1). Using mode 7 (fast PWM, 10-bit) you get the
32 Hz signal entirely generated by the hardware. And then you can
use the timer overflow interrupt to generate 1 Hz. The interrupt
rate is now 1024 times lower. I let you check the datasheet for the
details.


message:
Generate a sine wave with a predefined frequency and amplitude via DAC0 or DAC1 with Arduino Due

Good Morning to everyone,
I am a PhD Student in experimental fluid mechanics at the University of Naples "Federico II", Italy. I am working on Arduino Due card and i am novel in applications using it. First, I need to generate a sine wave with variable frequency and amplitude. I tried to download several codes which are able to generate sine waves with a pre-defined frequency, but I would like to change this value of frequency at the beginning of the execution of the code. How could i do this ?
Second, I would like to change, in real-time, the output voltage of Arduino DAC0 or DAC1 at high speed to generate an arbitrary waveshape.. Is it possible?
Thank you in advance for your answers.

Dr. Alessandro Scala

body:
The formula commonly used to represent a sinusoidal signal is

  V = A cos(ωt)

where A is the amplitude and ω is the angular frequency. This formula
should cope well with a variable amplitude. It is, however, not suitable
for a signal with variable frequency, because a discontinuity of the
frequency is not supposed to create a discontinuity in the signal.

The correct formula for a signal where both the amplitude and the
frequency can vary is

  V = A(t) cos(φ(t))

where the phase is computed as

  φ(t) = ∫ ω(t)dt

In terms of code, this means you need a static variable to keep track of
the current phase, and you have to update it periodically in order to
perform the numerical integration.

Here is a tentative implementation. I have qualified some variables as
`extern` only to hint that you are responsible for managing them. You
can remove the qualifier if you integrate this into your own code:

```c++
// Defined and updated elsewhere.
extern const uint8_t output_channel;
extern float angular_frequency;  // in rad/us
extern float amplitude, offset;  // in ADC steps

// Call this as often as practical.
void update_output()
{
    // Compute the time delta.
    static uint32_t time_of_last_update;
    uint32_t now = micros();
    uint32_t dt = now - time_of_last_update;
    time_of_last_update = now;

    // Update the phase.
    static float phase;
    phase += angular_frequency * dt;
    while (phase >= 2 * M_PI) phase -= 2 * M_PI;  // unwrap

    // Output the signal.
    float output = offset + amplitude * cos(phase);
    analogWrite(output_channel, round(output));
}
```

Regarding the second part of the question (about arbitrary waveshapes),
it is, of course, feasible. You just have to pass arbitrary values to
`analogWrite()`.


message:
Temperature sensors are heating themselves

I have 2 IoT devices for measuring room temperature. Room does not have direct sunlight (it is north oriented and have tree in front of window). One is ESP8266 with DHT11 and next one is ESP8266 with DS18B20. DHT is on the table, away from PC. DS18B20 is on the top of bookshelf next to plant. Both of them shows temperature around 32-33 deg. celsius. It is not that hot in the room for sure. My home thermostat shows 23-24 deg. celsius. Outside temperature is about 15 deg. When I open the window and cool down the room, I can see temerature drop on both sensors, but still ony to around 26-28 celsius. I think, they are overheating themselves.

Code is almost same on both devices. Sampling every minute, so it should not be an issue of overloading sensors. Supply voltage is 3,3V. Not parasitic with 2k2 pull-up resistor.

What should I do to get correct temperature reading from these sensors?

EDIT: I have tired to get sensor out of PCB. First, I have just raised it for lengt of its legs (about 1cm) above board. It helped little, but it is visible, that sensor started cold, and slowly saturated heat from wires. So I took quite thick cables (0,25mm^2) and put sensor about 10cm away from board. And it helped! Temperature is about 23 degrees, what is somwhere in expected range. Most important is, that temperature curve was dropping before stabilizing. Spikes are just 85°C first reading. [![enter image description here][1]][1]

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

body:
It does not surprise me that a sensor needs a correction to calculate the correct value. I have had the same problems with a range of sensors.

Because linearity is not really important when you need to measure only a room temperature, it would be sufficient to measure room temperature with a reliable thermometer and see how much you need to subtract to correct the value from your sensor.
When still in doubt, you could cover the sensor with a plastic bag and measure the temperature dipped in a bowl of water with crushed ice cubes in it.


body: It seems, that problem is in heat transfer from ESP chip to thermometer via wires. Worst it was, when chip was on board itself, little bit better when it was raised about 1cm out of board. I have achieved correct readings only when I put sensor on longer and quite thick leads to avoid heat transfer as much as possible.


message:
Call functions of one class from another class - Callback

I am new to C++ & I need to call functions of one class from another class. And so that the classes do not know anything about each other. How to do it in Arduino environment?

    class Encoder {
      using CallBack2 = void( * )(const int, const int);
      using CallBack0 = void( * )();
      private:
        CallBack2 callbackUpDown;
        CallBack0 callbackTab;
        CallBack0 callbackLongPress;
      public:
        Encoder() {}

      void Setup(CallBack2 updown, CallBack0 tab, CallBack0 cbLongPress) {
        callbackUpDown = updown;
        callbackTab = tab;
        callbackLongPress = cbLongPress;
      }

      void Loop() {
        if (true) {
          callbackUpDown(-1, 300);
          callbackTab();
          callbackLongPress();
        }
      }
    };

    class Menu {
      public:
        void UpDown(const int direction,
          const int count) {}
          void Tab() {}
    };

    class RTC {
      public:
        void Setup() {}
        void Toggle() {}
    };

    class Display {
      public:
        void Toggle() {}
    };

    Encoder encoder = Encoder();
    RTC rtc = RTC();
    Menu menu = Menu();
    Display display = Display();

    void setup() {
      rtc.Setup();
      encoder.Setup(menu.UpDown, menu.Tab, []{display.Toggle();rtc.Toggle();});
    }

    void loop() {
      encoder.Loop();
    }

Output:

    In file included from sun.ino:47:0:
    callback.h: In function 'void setup()':
    callback.h:52:75: error: invalid use of non-static member function 'void Menu::UpDown(int, int)'
       encoder.Setup(menu.UpDown, menu.Tab, []{display.Toggle(); rtc.Toggle();});
                                                                               ^
    callback.h:28:7: note: declared here
      void UpDown(const int direction, const int count) {}
           ^~~~~~

Thank you!

body:
What you are doing here

```cpp
encoder.Setup(menu.UpDown, menu.Tab, []{display.Toggle();rtc.Toggle();});
```

is not only passing a function pointer. You are passing a member function pointer. This is 2 levels more difficult than function pointers on their own.

1. The syntax of declaring a member function pointer is different. You need to include the class name in the function pointer declaration. It would look like

    ```cpp
    using CallBack2 = void( Menu::* )(const int, const int);
    ```

2. When calling a member function pointer, you need an object to call the function on.

Unfortunately, this is so hard that I can't turn your code into a working example. If you want to be able to read your code in 3 months or if you want others to be able to read your code, stick to normal function pointers. They are hard enough.

Suggestion: implement free functions that do what you want:

```cpp
void menuUpDown(const int dir, const int count)
{
  menu.UpDown(dir, count);
}
void menuTab()
{
  menu.Tab();
}

void setup() {
  rtc.Setup();
  encoder.Setup(menuUpDown, menuTab, []{display.Toggle();rtc.Toggle();});
}
```

Or, since you're already using lambdas (are you aware of that?), you can also

```cpp
void setup() {
  rtc.Setup();
  encoder.Setup(
    [](const int dir, const int count){menu.UpDown(dir, count);},
    []{menu.Tab();},
    []{display.Toggle();rtc.Toggle();}
  );
}
```

Note that pupils and students might not have been introduced to the concept of lambdas. If you publish such code online, people might not be able to change it themselves because they don't understand it.


body:
Also, [Using Static Methods Or Non-Member Functions (C-Style)][1]

    class MyClass {
      public:
        static void onMsg(int num1, int num2) {
          // NOTE: Can't call any non-static method functions here!
        }
    };

    class LibraryClass {
      using CallBack = void( * )(int, int);
      private:
        CallBack callBack;
      public:
        void Setup(CallBack callBackFunc) {
          callBack = callBackFunc;
        }
        void Loop() {
          callBack(1, 2);
        }
    };

    MyClass myClass;
    LibraryClass libraryClass;

    void setup() {
      libraryClass.Setup(&myClass.onMsg); // Provide the instance and function to call
    }

    void loop() {
      libraryClass.Loop();
    }

  [1]: https://blog.mbedded.ninja/programming/languages/c-plus-plus/callbacks/


message:
How real-time is an arduino (react to sensor)?

New to arduino here, sorry for asking what may be a trivial question.

I need to simulate an industrial machine at home. It operates in a cyclic motion, creating an event for every rotation / cycle. Imagine a turntable or wheel with a marker in one place.

What I would like is:

  * Have a physical wheel which I turn one rotation every 300 msec. This is the length in time of a cycle.
  * Read a marker on this wheel using a sensor, such as Sick or Omron. I have this already. Sensor can be PNP or NPN, providing a closed or open connection. I can go via an optocoupler if needed.
  * Once a signal is seen, the arduino should send a (sequential) string using RS232 to a PC. Approximately 90 characters.  It is not needed to wait for response.

My question is: would be time for arduino to do this be relatively constant - ie, send out the data at approximately same point in the cycle. Example: signal read at "12" on the clock, data sent around "5".

If possible, what sort of Arduino would I be looking at ?

Or do I need something more real-time for such project, like a PLC ?

body:
TLDR: any Arduino is probably sufficient for your purpose when done properly.

I'll assume a proper HIGH/LOW binary signal from the sensor, HIGH when it "sees" the marker, LOW when it doesn't.

What could go wrong?

1. You use `digitalRead()` to get the state of the digital input. Depending on the pulse width, you might not catch the high state. Use interrupts instead.
2. Sending the data over Serial port takes longer than a turn of the machine. 90 bytes at 9600 bit/s needs (90 bytes * 10 bits/byte / (9600 kbit/s) = 93ms. In 300ms, there's enough time to send the 90 bytes. And 9600 bit/s is quite slow: you can probably use 115200 bit/s on short or shielded wires.
3. "Approximately 90 characters": calculate everything for the maximum data that will eventually be sent
4. Getting the data on Arduino side takes too long. You didn't give details on where those 90 bytes come from. Asking 90 devices to each give you a byte of data might not be possible in 300ms.
5. Receiving the data on the PC side (or whatever) might be delayed, because it is buffered. Especially USB to Serial adapters have no guaranteed timing. Doing the math for USB devices is hard.
6. Threading on the PC side: due to the OS Thread scheduling, the application that shall receive the data might not get CPU time for several milliseconds, 16ms (1/64s) is quite common. Doing the math is impossible (try running 8 real time threads that do something else and your PC is basically frozen)
7. Processing on the PC side: unknown
8. Displaying: after processing until a signal is displayed on the screen, that may take another 16 ms (at 60 Hz refresh rate).

> would be time for Arduino to do this be relatively constant

Relatively: yes. It certainly depends on the implementation (the Arduino C++ code).

If the data to send is hard coded 90 characters, I would expect the complete signal has been sent at before the 4 o'clock mark (94ms /300ms * 12 hours ~ 3 hours) . I see the problem more on the receiving side (see points 5., 6., 7. and 8.).

> what sort of Arduino would I be looking at ?

I don't know all of them, but an Uno will certainly work. If you only have that one digital input, even smaller ones are probably ok. Just start with an Uno or what you have available and see how it goes.

> do I need something more real-time for such project, like a PLC?

I don't see a need for a PLC in your project.


body:
> one rotation every 300 msec.

300 ms is a _very long time_ for an Arduino, even for an AVR-based
one, like an Uno.

I did a little experiment. I generated (with an Arduino...) a periodic
signal consisting of a 96 µs-wide negative pulse repeating every
300 ms. I sent that signal to an Arduino Uno running the following
code:

```c++
const uint8_t sensor_pin = 3;

// 90-byte message.
const char message[] = "Korem ipsum dolor sit amet, consectetur "
        "adipiscing elit sed do eiusmod tempor incididunt\r\n";

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

void loop() {
    if (digitalRead(sensor_pin) == LOW) {
        Serial.write(message);

        // Wait until the signal rises again.
        while (digitalRead(sensor_pin) == LOW)
            continue;
    }
}
```

This is not the nicest way to do edge detection, but for this simple
test it will do. You may notice that I am not using interrupts for
capturing the pulse: 96 µs is long enough to be captured with this
simple `digitalRead()`. I then captured the input and output signals
with a dual-channel pocket oscilloscope. Here is a screen capture:

[![Oscilloscope screen capture][1]][1]

The cyan trace at the top is the received pulse. The yellow trace below
is the output of the serial port. The negative pulse on this trace that
is almost coincident with the received pulse is the start bit. Then the
signal rises to transmit the first data bit, which is a 1 (that's
why I chose “K” rather than “L” as the first letter).

What you can see in this capture is that the latency of the Arduino is
tiny at this scale: a small fraction of the duration of the start bit.
What you cannot see is the jitter, which is quite large in _relative_
terms, but still small compared to the time scales relevant to you. In
short, the delay between the falling edge on the input and the falling
edge of the serial port start bit fluctuates roughly between 10 and
20 µs. Yes, those are **micro**seconds. This delay is roughly
20,000 times shorter than the rotation period. If the signal is read at
“12” on the clock, the start bit fires at 12 hours with
0 minutes and 2 seconds.

Note that, on the other hand, the time needed to send the message at
9600 b/s is 93.6 ms, a significant fraction of the rotation
period. And I didn't look at the behavior of the USB-to-serial converter
chip, which is another can of worms...

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


message:
Seeeduino XIAO read PWM duration (period) using timers change Pins freom D2 to D1

I designed a circuitboard and need to proof the function.Therefore i have to modify the code to read from Pins D1 instead of D2.
Unfourtunatly i am not that familar with the high level programming so im not sure if i got all changes.
Basically all PINS on the circuit are used.

Basecode foud here:
https://arduino.stackexchange.com/questions/85741/seeeduino-xiao-write-and-read-pwm-duration-period-using-timers

Reading short square waves with Seeeduino XIAO pin D2

```
// Setup TC4 to capture pulse-width and period on digital pin D2 on Seeeduino Xiao
volatile boolean periodComplete;
volatile uint32_t isrPeriod;
volatile uint32_t isrPulsewidth;
uint32_t period;
uint32_t pulsewidth;

void setup()   {
  SerialUSB.begin(115200);                         // Initialise the native serial port
  while(!SerialUSB);                               // Wait for the console to open

  PM->APBCMASK.reg |= PM_APBCMASK_EVSYS;           // Switch on the event system peripheral

  GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) |          // Divide the 48MHz system clock by 1 = 48MHz
                     GCLK_GENDIV_ID(4);            // Set division on Generic Clock Generator (GCLK) 4

  GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC |           // Set the duty cycle to 50/50 HIGH/LOW
                      GCLK_GENCTRL_GENEN |         // Enable GCLK 4
                      GCLK_GENCTRL_SRC_DFLL48M |   // Set the clock source to 48MHz
                      GCLK_GENCTRL_ID(4);          // Set clock source on GCLK 4
  while (GCLK->STATUS.bit.SYNCBUSY);               // Wait for synchronization

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |         // Route GCLK4 to TC4 and TC5
                      GCLK_CLKCTRL_GEN_GCLK4 |
                      GCLK_CLKCTRL_ID_TC4_TC5;

  // Enable the port multiplexer on port pin PA10
  PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
  // Set-up the pin as an EIC (interrupt) on port pin PA10
  PORT->Group[PORTA].PMUX[10 >> 1].reg |= PORT_PMUX_PMUXE_A;

  EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO10;                                // Enable event output on external interrupt 10
  EIC->CONFIG[1].reg |= EIC_CONFIG_SENSE2_HIGH;                            // Set event detecting a HIGH level
  EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT10;                               // Disable interrupts on external interrupt 10
  EIC->CTRL.reg |= EIC_CTRL_ENABLE;                                        // Enable EIC peripheral
  while (EIC->STATUS.bit.SYNCBUSY);                                        // Wait for synchronization

  EVSYS->USER.reg = EVSYS_USER_CHANNEL(1) |                                // Attach the event user (receiver) to channel 0 (n + 1)
                    EVSYS_USER_USER(EVSYS_ID_USER_TC4_EVU);                // Set the event user (receiver) as timer TC4

  EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT |                // No event edge detection
                       EVSYS_CHANNEL_PATH_ASYNCHRONOUS |                   // Set event path as asynchronous
                       EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_10) |   // Set event generator (sender) as external interrupt 10
                       EVSYS_CHANNEL_CHANNEL(0);                           // Attach the generator (sender) to channel 0

  TC4->COUNT32.EVCTRL.reg = TC_EVCTRL_TCEI |               // Enable the TC event input
                            //TC_EVCTRL_TCINV |              // Invert the event input
                            TC_EVCTRL_EVACT_PPW;           // Set up the timer for capture: CC0 period, CC1 pulsewidth

  TC4->COUNT32.CTRLC.reg = TC_CTRLC_CPTEN1 |               // Enable capture on CC1
                           TC_CTRLC_CPTEN0;                // Enable capture on CC0
  while (TC4->COUNT32.STATUS.bit.SYNCBUSY);                // Wait for synchronization

  NVIC_SetPriority(TC4_IRQn, 0);      // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest)
  NVIC_EnableIRQ(TC4_IRQn);           // Connect the TC4 timer to the Nested Vector Interrupt Controller (NVIC)

  TC4->COUNT32.INTENSET.reg = TC_INTENSET_MC1 |            // Enable compare channel 1 (CC1) interrupts
                              TC_INTENSET_MC0;             // Enable compare channel 0 (CC0) interrupts

  TC4->COUNT32.CTRLA.reg = //TC_CTRLA_PRESCSYNC_PRESC |      // Overflow on precaler clock, (rather than the GCLK)
                           TC_CTRLA_PRESCALER_DIV1  |      // Set prescaler to 1, 48MHz/1 = 48MHz
                           TC_CTRLA_MODE_COUNT32;          // Set TC4/TC5 to 32-bit timer mode

  TC4->COUNT32.CTRLA.bit.ENABLE = 1;                       // Enable TC4
  while (TC4->COUNT32.STATUS.bit.SYNCBUSY);                // Wait for synchronization
}

void loop() {
  if (periodComplete)                             // Check if the period is complete
  {
    noInterrupts();                               // Read the new period and pulse-width
    period = isrPeriod;
    pulsewidth = isrPulsewidth;
    interrupts();
    SerialUSB.print("PW: ");
    SerialUSB.print(pulsewidth);
    SerialUSB.print(F("   "));
    SerialUSB.print("P: ");
    SerialUSB.println(period);
    periodComplete = false;                       // Start a new period
  }
}

void TC4_Handler()                                // Interrupt Service Routine (ISR) for timer TC4
{
  // Check for match counter 0 (MC0) interrupt
  if (TC4->COUNT32.INTFLAG.bit.MC0)
  {
    TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ |           // Enable a read request
                               TC_READREQ_ADDR(0x18);      // Offset address of the CC0 register
    while (TC4->COUNT32.STATUS.bit.SYNCBUSY);              // Wait for (read) synchronization
    isrPeriod = TC4->COUNT32.CC[0].reg;                    // Copy the period
    periodComplete = true;                                 // Indicate that the period is complete
  }

  // Check for match counter 1 (MC1) interrupt
  if (TC4->COUNT32.INTFLAG.bit.MC1)
  {
    TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ |           // Enable a read request
                               TC_READREQ_ADDR(0x1A);      // Offset address of the CC1 register
    while (TC4->COUNT32.STATUS.bit.SYNCBUSY);              // Wait for (read) synchronization
    isrPulsewidth = TC4->COUNT32.CC[1].reg;                // Copy the pulse-width
  }
}
```

Do i only have to change the IOs:
from:
 PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
 PORT->Group[PORTA].PMUX[10 >> 1].reg |= PORT_PMUX_PMUXE_A;
to:
 PORT->Group[PORTA].PINCFG[4].bit.PMUXEN = 1;
 PORT->Group[PORTA].PMUX[4 >> 1].reg |= PORT_PMUX_PMUXE_A;

or do i need to mod more code?

Thanks for helping.

body:
In addition to the changes you mentioned, your `EIC_EVCTRL_EXTINTEO10`, `EIC_INTENCLR_EXTINT10`, and `EVSYS_ID_GEN_EIC_EXTINT_10` usages will need to be changed to `EIC_EVCTRL_EXTINTE4`, `EIC_INTENCLR_EXTINT4` and to `EVSYS_ID_GEN_EIC_EXTINT_4`, to re-target the event system source, because `PORT_PMUX_PMUXE_A` on both [these pins][1] routes the signal to the EIC, but not to the exact same interrupt number.  The `EIC->CONFIG` line needs to change to the first group of 8 (`[0]`) and fourth SENSE within that group (`EIC_CONFIG_SENSE4_HIGH`) to the change to D1 (PA04) uses EXTINT4.  This is something I'd left out of the first edit before I'd been able to test. I did eventually find a XIAO to test with and these modifications seem to make it work just fine on digital pin 1 now instead of digital pin 2.

```c++
EIC->EVCTRL.reg    |= EIC_EVCTRL_EXTINTE4;
EIC->CONFIG[0].reg |= EIC_CONFIG_SENSE4_HIGH;
EIC->INTENCLR.reg   = EIC_INTENCLR_EXTINT4;
EIC->CTRL.reg      |= EIC_CTRL_ENABLE;
while (EIC->STATUS.bit.SYNCBUSY);
```
   ...
```c++
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT |
                     EVSYS_CHANNEL_PATH_ASYNCHRONOUS |
                     EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_4) |
                     EVSYS_CHANNEL_CHANNEL(0);
```

---

The changes you'd mentioned and those I've said above as diff:

```Diff
--- original.ino
+++ modified.ino
@@ -24,14 +24,14 @@
                       GCLK_CLKCTRL_GEN_GCLK4 |
                       GCLK_CLKCTRL_ID_TC4_TC5;

-  // Enable the port multiplexer on port pin PA10
-  PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
-  // Set-up the pin as an EIC (interrupt) on port pin PA10
-  PORT->Group[PORTA].PMUX[10 >> 1].reg |= PORT_PMUX_PMUXE_A;
+  // Enable the port multiplexer on port pin PA04
+  PORT->Group[PORTA].PINCFG[4].bit.PMUXEN = 1;
+  // Set-up the pin as an EIC (interrupt) on port pin PA04
+  PORT->Group[PORTA].PMUX[4 >> 1].reg |= PORT_PMUX_PMUXE_A;

-  EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO10;                                // Enable event output on external interrupt 10
-  EIC->CONFIG[1].reg |= EIC_CONFIG_SENSE2_HIGH;                            // Set event detecting a HIGH level
-  EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT10;                               // Disable interrupts on external interrupt 10
+  EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO4;                                 // Enable event output on external interrupt 4
+  EIC->CONFIG[0].reg |= EIC_CONFIG_SENSE4_HIGH;                            // Set event detecting a HIGH level
+  EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT4;                                // Disable interrupts on external interrupt 4
   EIC->CTRL.reg |= EIC_CTRL_ENABLE;                                        // Enable EIC peripheral
   while (EIC->STATUS.bit.SYNCBUSY);                                        // Wait for synchronization

@@ -40,7 +40,7 @@

   EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT |                // No event edge detection
                        EVSYS_CHANNEL_PATH_ASYNCHRONOUS |                   // Set event path as asynchronous
-                       EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_10) |   // Set event generator (sender) as external interrupt 10
+                       EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_4) |    // Set event generator (sender) as external interrupt 4
                        EVSYS_CHANNEL_CHANNEL(0);                           // Attach the generator (sender) to channel 0

   TC4->COUNT32.EVCTRL.reg = TC_EVCTRL_TCEI |               // Enable the TC event input
```

  [1]: https://github.com/Seeed-Studio/ArduinoCore-samd/blob/v1.8.3/variants/XIAO_m0/variant.cpp#L28-L29


message:
Best practice for wiring two sensors that have SCL and SDA connections

I have two different sensors which have SCL and SDA connections which I am trying to connect to an Arduino nano. From what I understand, connecting both of these sensor to the A5 and A4 pins doesn't make any sense, considering that I need to collect data continuously from both sensors. Moreover, there are no other pins with the same functionality as A5 and A4. I am a beginner learning about microcontrollers, but it seems to me like the best practice to follow here would be to use two Arduino nanos. Is this this the only way, or is there another method I am not aware of?

body:
The whole point of the I2C bus is to allow multiple sensors or devices to be connected, as long as they have different I2C addresses. The addresses are usually built into the part, and often they have some provision for selecting an address from a range.

Whilst you can't *simultaneously* collect data from two sensors at once, you can certainly query them in quick succession. You need to connect SDA, SCL, Ground and +5V to each sensor, and the Arduino.

Your code would do something like:

* Query sensor at address 42
* Query sensor at address 43
* Do something with the data
* Wait a bit before doing it again

You could look at Wikipedia for some general information about I2C, and I also have [a page about I2c](http://gammon.com.au/i2c) that might help you.

Note that you also need a pull-up resistor on both SDA and SCL (that is, two resistors), a typical value would be 4.7k (connect the 4.7k resistors between SDA/SCL and your +5V line).


message:
How to upload code to Arduino without a laptop

I would like to know is there a way of burning programs to microcontrollers like that on Arduino without using a computer? Like a pendrive or something? Suppose you want to update firmware on a utility end, must you carry the editable source code with you? How do the big companies do it?

body:
One good way to update Uno/Nano/Mini without connecting it to a computer is to use SD bootloader. SD bootloader reads at boot the bin file with the update from the attached SD card and copies it to flash memory.

There are not many SD bootloader for ATmega. I use [avr_boot][2] by zevero. It works well. The downside is that it doesn't support upload over USB.

zevero doesn't offer built binaries of the bootloader so you have to compile it with the avr toolchain.

avr_boot requires a bin file, not a hex file, but it is simple to set Arduino IDE to create a bin file along with the hex file. You create platform.local.txt file next to platform.txt in the avr boards package, and put this line into the file:
```
## Create output (bin file)
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" -O binary {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
```
Then you can use "Export compiled binary" from Sketch menu in Arduino IDE and you will find the binary file next to your ino file in the sketch folder.

----------

There are different ways how to update an Arduino without connecting it to computer. For small ATmega328p on Uno/Nano/Mini there is not enough flash space to do a self update. The code required to do the update takes more than half of the flash so there is no space left to store the update binary before applying it. (The updated sketch of course must have to have the code for the self update too.)

For illustration what is possible, [here is a sketch][1] for Arduino Mega which does a self update from SD card reading a hex file. It requires a modified Optiboot available in MegaCore.

  [1]: https://github.com/JAndrassy/ArduinoOTA/blob/master/examples/Advanced/SD2Flash2BootAVRHex/SD2Flash2BootAVRHex.ino
  [2]: https://github.com/zevero/avr_boot


message:
No matching function for call to'DS3231 (const uint8_t &, const uint8_t &)

This was supposed to be the code for automatic pet feeder
Got it from here[1]

The problem is that I always got a "No matching function for call to'DS3231 (const uint8_t &, const uint8_t &)"

Here's the error code

```
Arduino: 1.8.19 (Windows 10), Board: "Arduino Uno"

ANA_FEEDER_PROJECT:53:18: error: no matching function for call to 'DS3231::DS3231(const uint8_t&, const uint8_t&)'

 DS3231 rtc(A4, A5);

                  ^

In file included from C:\Users\SERIES\Desktop\ANA_FEEDER_PROJECT\ANA_FEEDER_PROJECT.ino:1:0:

D:\Documents\Arduino\libraries\DS3231/DS3231.h:67:3: note: candidate: DS3231::DS3231(TwoWire&)

   DS3231(TwoWire & w);

   ^~~~~~

D:\Documents\Arduino\libraries\DS3231/DS3231.h:67:3: note:   candidate expects 1 argument, 2 provided

D:\Documents\Arduino\libraries\DS3231/DS3231.h:66:3: note: candidate: DS3231::DS3231()

   DS3231();

   ^~~~~~

D:\Documents\Arduino\libraries\DS3231/DS3231.h:66:3: note:   candidate expects 0 arguments, 2 provided

D:\Documents\Arduino\libraries\DS3231/DS3231.h:62:7: note: candidate: constexpr DS3231::DS3231(const DS3231&)

 class DS3231 {

       ^~~~~~

D:\Documents\Arduino\libraries\DS3231/DS3231.h:62:7: note:   candidate expects 1 argument, 2 provided

D:\Documents\Arduino\libraries\DS3231/DS3231.h:62:7: note: candidate: constexpr DS3231::DS3231(DS3231&&)

D:\Documents\Arduino\libraries\DS3231/DS3231.h:62:7: note:   candidate expects 1 argument, 2 provided

C:\Users\SERIES\Desktop\ANA_FEEDER_PROJECT\ANA_FEEDER_PROJECT.ino: In function 'void setup()':

ANA_FEEDER_PROJECT:84:7: error: 'class DS3231' has no member named 'begin'

   rtc.begin();

       ^~~~~

C:\Users\SERIES\Desktop\ANA_FEEDER_PROJECT\ANA_FEEDER_PROJECT.ino: In function 'void loop()':

ANA_FEEDER_PROJECT:130:10: error: 'class DS3231' has no member named 'getTimeStr'; did you mean 'getMinute'?

  t = rtc.getTimeStr();

          ^~~~~~~~~~

          getMinute

ANA_FEEDER_PROJECT:146:16: error: 'class DS3231' has no member named 'getTimeStr'; did you mean 'getMinute'?

  lcd.print(rtc.getTimeStr());

                ^~~~~~~~~~

                getMinute

ANA_FEEDER_PROJECT:152:16: error: 'class DS3231' has no member named 'getDateStr'; did you mean 'getDate'?

  lcd.print(rtc.getDateStr());

                ^~~~~~~~~~

                getDate

exit status 1

no matching function for call to 'DS3231::DS3231(const uint8_t&, const uint8_t&)'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

The problem is that I always got a "No matching function for call to'DS3231 (const uint8_t &, const uint8_t &)"

Here's the error code

  [1]: https://circuitdigest.com/microcontroller-projects/automatic-pet-feeder-using-arduino

body:
You are using the wrong DS3231 library. Unfortunately, you can often find incompatible libraries that share the same name. The sketch you downloaded has been written for a specific version of the DS3231 library. Thus your choices are:

 * either you use that specific version (linked to in the page you gave as reference)
 * or you adapt the code to work with the version you have installed.


message:
How to turn off the display of line numbers on Mac Arduino IDE?

I'm trying to turn off line numbers on the Mac Arduino IDE but don't see the option for it after navigating to `Arduino IDE > Preferences`. Below is a screenshot of what I am seeing.

[![Arduino Preferences][1]][1]

I saw [this question][2] asked previously, but there is no `File > Preferences` path on Mac. I am using Version 2.0.0 on macOS (10.14 or newer).

  [1]: https://i.stack.imgur.com/7cIA5.jpg
  [2]: https://arduino.stackexchange.com/questions/52161/arduino-ide-display-code-line-numbers

body:
I don't see a proper place to do this in the 2.0.0 IDE preferences. However, modifying the .arduinoIDE/setting.json file to include `"editor.lineNumbers": "off",` seems to work.

```json
{
 "editor.lineNumbers": "off",
 "editor.fontSize": 14,
 ...
}
```

[![Shows IDE 2.0.0 with and without line numbers.][1]][1]

Edgar Bonet pointed out in a comment that there's still a bunch of empty space in that region. The image above doesn't do a good of showing why though. In the below screenshots I've told the IDE to set a breakout and hovered over where folding region so it displays the fold indicators to make somewhat easier to see that and compare what effect on width results from disabling these things.

If you want to save a bit more space you can add turn off the code folding feature, which removes the spaced that would be used for fold indicators with an additional `"editor.folding": "false",` in the settings.json file.

For comparison, here's everything enabled, numbers but no folding, folding but no numbers, no folding and no numbers:

[![Comparison of widths with different combinations of folding and line number settings.][2]][2]

I haven't yet found out how to turn off the display of break-point indicators. I assume that it is possible though.

  [1]: https://i.stack.imgur.com/qYfDd.png
  [2]: https://i.stack.imgur.com/Hf7hD.png


message:
How to install FTDI Serial Drivers on Mac?

[I'm following this tutorial on how to install FTDI drivers on macOS][1], but am facing some issues. After downloading the USB Serial Driver version 2.4.4 (for OS X 10.14) from [FTDI Chip's virtual COM port (VCP) driver page][2] (recommended by the tutorial), I still don't see any `usbserial` option listed under the Serial Port tab, shown below.

[![Missing USB Serial Port][3]][3]

Because I'm running macOS Monterrey (12.0.1), I also tried downloading the Beta driver release (version 1.5.0) for OS X 10.15 and macOS 11/12. After running the installer from my Applications folder (as recommended), I get the following result, indicating success, but the options list remains the same as shown above.

[![Successful Installation][4]][4]

Are there any workarounds? For reference, I am using Arduino IDE 2.0.0.

  [1]: https://learn.sparkfun.com/tutorials/how-to-install-ftdi-drivers/all#mac
  [2]: https://ftdichip.com/drivers/vcp-drivers/
  [3]: https://i.stack.imgur.com/xc9zp.png
  [4]: https://i.stack.imgur.com/Nd8IO.png

body:
I have just managed to get the FTDI set up for my M1 mac using the Pro Mini. I think the issue is that newer macs automatically block the FTDI serial connection from being used as a com port. You need to install a program called **D2XXHelper** to prevent this behaviour.

I did the following, hopefully this will work for you too:

1. Install **FTDI VCP Driver**, found [here][1]: Scroll down to first table and find the latest Mac OS drivers. There are 2, the 2.4.4 version and the 1.5 version. I think you need to use the 1.5 version for the M1 but I’m not sure because I installed both before I did the next steps to get it working.
2. Install the **D2XXHelper** found [here][2]: Scroll down to first table and look in the comments column for the Mac OS row to find the download link.
 4. After installing the D2XXHelper, you should get a security prompt saying **system extension blocked**. Follow [this][3] guide which shows how to provide permission for the system extension to be applied – this requires going into recovery mode and requires several computer restarts.
 5. After following the steps in the guide, you should have enabled the D2XXHelper system extensions to be applied, in which case when you connect your Arduino to your computer via the FTDI connector, the Arduino IDE 2 should now recognise that a device has been connected via the FTDI virtual com port.
 6. **optional** – to check that your FTDI is connected correctly to your Arduino, connect it up, Open a Terminal window and type “ls /dev/tty.*” and run this command. If the FTDI is connected properly then a usb serial device should show up in the results to this command.

  [1]: https://ftdichip.com/drivers/vcp-drivers/
  [2]: https://ftdichip.com/drivers/d2xx-drivers/
  [3]: https://support.techsmith.com/hc/en-us/articles/360056384711-M1-M2-Chip-and-the-Snagit-System-Audio-Capture-Component#:~:text=To enable system extensions, you,from the Security Policy button.


message:
Bluetooth Arduino Data Type Error

In my code I want to send some float values from my phone to the Arduino's Bluetooth which I will then split using the substring function. it will then print that split value to the serial monitor.

I don't even know what is wrong but there is no error and it just spits out the ascii code of those numbers (not split). Please help if anyone has any idea.
Here is my code:

    #include <Wire.h>
    #include<SoftwareSerial.h>
    #define TxD 3
    #define RxD 2
    SoftwareSerial bluetoothSerial(TxD,RxD);

    String Sstring;
    String arrayOne;

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

    void loop()
    {

     if(bluetoothSerial.available()>0)
     {

      arrayOne=bluetoothSerial.read();

      Sstring=arrayOne.substring(0);
      Serial.println(Sstring);
     }
    }

body:
I'm guessing the line `arrayOne=bluetoothSerial.read();`
is converting the received value to a string (character array of ASCII charachters terminated with the '\0' character).
Then, you copy that string to another string variable. If you want to split the string you should:
- define a starting character > 0
- and/or: define an ending character < the total string size.

See [this link][1] for more info.

You could try the following. I'm sure it's far from perfect but it might get you a bit further.
```
void setup()
{
    bluetoothSerial.begin(9600);
    Serial.begin(9600);
}

void loop()
{
    if (bluetoothSerial.available)
    {
        delay(100); // wait a little for the serial buffer to saturate. This value should be as short as possible

        // Save the buffer bytes as the float (Big Endian!)
        double received_float = (bluetoothSerial.read() << 24) | (bluetoothSerial.read() << 16) | (bluetoothSerial.read() << 8) | (bluetoothSerial.read());
        Serial.println(received_float);
    }
}
```
Some conciderations:
- The nr of bytes a float occupies may differ on your phone and your Arduino. The example above uses a 32-bit float
- If possible you'd want to start the transmission with a sequency of starting characters. That way, you can be sure to read the proper value.

  [1]: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/substring/


body:
First thing, you have to decide what data format the phone application
will use for sending the data to the Arduino: define a “language” of
sorts. Then you have to program both the phone and the Arduino to speak
that same language.

Unless the data throughput is critical, I strongly advise you to use a
text-based format, where each “message” is followed by a dedicated
character that signals the end of the message. Popular choices for the
message terminator are `'\n'` (ASCII line feed, numeric value 0x0a =
10), `'\r'` (carriage return = 0x0d = 13) and `';'` (semicolon = 0x3b =
59). The semicolon is often used as a second-level separator, to split a
message into smaller fields.

Here is a simple example that reads one-line messages, using a line feed
as a delimiter:

```c++
void loop() {
    if (bluetoothSerial.available() > 0) {
        String message = bluetoothSerial.readStringUntil('\n');
        Serial.println(message);
    }
}
```

If you want to send the data as binary, then message framing becomes a
tricky problem. Since every possible byte value can legitimately appear
within the message (any byte can appear within a float), you cannot
simply reserve one byte to serve as a terminator. This is why, unless
you are an advanced programmer, I strongly encourage you to send
whatever data you want to send as text. Text also makes debugging much
easier.

Finally, I have to warn you that the `String` class is not friendly to
the memory of your Arduino, and can lead to instabilities if used
extensively. If you have time, I encourage you to study the robust way
to read text from the serial port: see the article [Reading Serial on
the Arduino][majenko], by Majenko.

[majenko]: https://majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27


message:
Duinotech ATTINY85 Pinout

I'm sure this is a super nooby question but,

what is the pinout of the Digispark ATTINY85 Development Board

The board looks like this:
[![Board][1]][1]

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

Now the reason why I'm asking this question, when I do ```digitalWrite(1, HIGH);```, the test light will come on. My question is then, what is the virtual number for PB1 (P1 in photo).

Also, does that arduino output + or -?

Any help is appreciated. Thank You!

body:
[This][1] seems to show an obvious pinout with an LED connected to p1 (digital pin 1).
With "virtual number" I guess you mean the Arduino pin nr. As your code shows you, it's Arduino pin 1.

  [1]: https://create.arduino.cc/projecthub/alaspuresujay/use-an-attiny85-with-arduino-ide-07740c