message:
Seting up registers in Samd based arduino board

I'm trying to setup the BOD33 for Samd51 MCU in th .ino file as a first thing, even before the #include lines in the .ino

    // Define the base address for t_SUPC
    #define T_SUPC_BASE 0x40001800UL

    // Define the offsets for t_BOD33 and t_STATUS
    #define T_BOD33_OFFSET 0x10
    #define T_STATUS_OFFSET 0x0C

    // Set the t_SUPC register
    volatile uint32_t *t_SUPC = (volatile uint32_t *)T_SUPC_BASE;

    // Set the t_BOD33 register
    volatile uint32_t *t_BOD33 = (volatile uint32_t *)(T_SUPC_BASE + T_BOD33_OFFSET);

    // Set the t_STATUS register
    volatile uint32_t *t_STATUS = (volatile uint32_t *)(T_SUPC_BASE + T_STATUS_OFFSET);

    // Clear bit 1 in t_BOD33 and then set it to 1
    *t_BOD33 &= ~(1u << 1); // Clear bit 1

    // Check bit 0 in t_STATUS and loop while it is 0
    while ((*t_STATUS & 0x01) == 0)
    {
    }

    *t_BOD33 &= (0x7D0300u << 1);

    *t_BOD33 |= (1u << 1); // Set bit 1 to 1
    while ((*t_STATUS & 0x01) == 0)
    {
    }

    while ((*t_STATUS & 0x02) != 0)
    {
    }

    // Clear bit 1 in t_BOD33 and then set it to 1
    *t_BOD33 &= ~(1u << 1); // Clear bit 1
    while ((*t_STATUS & 0x01) == 0)
    {
    }
    *t_BOD33 |= (1u << 2);
    *t_BOD33 &= ~(1u << 3);
    *t_BOD33 |= (1u << 1); // Set bit 1 to 1

but I'm getting a compile problem and VScode is throwing those error, which I have no clue why since I never encountered it before
the errors are :

""

    0_2.ino:28:10: error: expected constructor, destructor, or type conversion before '&=' token
       28 | *t_BOD33 &= ~(1u << 1); // Clear bit 1
          |          ^~
    0_2.ino:31:1: error: expected unqualified-id before 'while'
       31 | while ((*t_STATUS & 0x01) == 0)
          | ^~~~~
    0_2.ino:35:10: error: expected constructor, destructor, or type conversion before '&=' token
       35 | *t_BOD33 &= (0x7D0300u << 1);
          |          ^~
    0_2.ino:37:10: error: expected constructor, destructor, or type conversion before '|=' token
       37 | *t_BOD33 |= (1u << 1); // Set bit 1 to 1
          |          ^~
    0_2.ino:38:1: error: expected unqualified-id before 'while'
       38 | while ((*t_STATUS & 0x01) == 0)
          | ^~~~~
    0_2.ino:42:1: error: expected unqualified-id before 'while'
       42 | while ((*t_STATUS & 0x02) != 0)
          | ^~~~~
    0_2.ino:47:10: error: expected constructor, destructor, or type conversion before '&=' token
       47 | *t_BOD33 &= ~(1u << 1); // Clear bit 1
          |          ^~
    0_2.ino:48:1: error: expected unqualified-id before 'while'
       48 | while ((*t_STATUS & 0x01) == 0)
          | ^~~~~
    0_2.ino:51:10: error: expected constructor, destructor, or type conversion before '|=' token
       51 | *t_BOD33 |= (1u << 2);
          |          ^~
    0_2.ino:52:10: error: expected constructor, destructor, or type conversion before '&=' token
       52 | *t_BOD33 &= ~(1u << 3);
          |          ^~
    0_2.ino:53:10: error: expected constructor, destructor, or type conversion before '|=' token
       53 | *t_BOD33 |= (1u << 1); // Set bit 1 to 1
          |          ^~

thank you in advance.

body:
The line where the error starts should go to a function e.g. `setup()`. You can compile the code below.

    // Define the base address for t_SUPC
    #define T_SUPC_BASE 0x40001800UL
    // Define the offsets for t_BOD33 and t_STATUS
    #define T_BOD33_OFFSET 0x10
    #define T_STATUS_OFFSET 0x0C

    // Set the t_SUPC register
    volatile uint32_t *t_SUPC = (volatile uint32_t *)T_SUPC_BASE;
    // Set the t_BOD33 register
    volatile uint32_t *t_BOD33 = (volatile uint32_t *)(T_SUPC_BASE + T_BOD33_OFFSET);
    // Set the t_STATUS register
    volatile uint32_t *t_STATUS = (volatile uint32_t *)(T_SUPC_BASE + T_STATUS_OFFSET);

    void setup()
    {
        // Clear bit 1 in t_BOD33 and then set it to 1
        *t_BOD33 &= ~(1u << 1); // Clear bit 1

        // Check bit 0 in t_STATUS and loop while it is 0
        while ((*t_STATUS & 0x01) == 0)
        {
        }

        *t_BOD33 &= (0x7D0300u << 1);

        *t_BOD33 |= (1u << 1); // Set bit 1 to 1
        while ((*t_STATUS & 0x01) == 0)
        {
        }

        while ((*t_STATUS & 0x02) != 0)
        {
        }

        // Clear bit 1 in t_BOD33 and then set it to 1
        *t_BOD33 &= ~(1u << 1); // Clear bit 1
        while ((*t_STATUS & 0x01) == 0)
        {
        }
        *t_BOD33 |= (1u << 2);
        *t_BOD33 &= ~(1u << 3);
        *t_BOD33 |= (1u << 1); // Set bit 1 to 1
    }


sender: user

message:
ATMEGA2560 died inside a arcade game circuit

I am building arcade game with 10 player buttons (5 for each player) and one start button. All buttons have build in LED inside. Player buttons has LED for 12V and start button has led for 5V. I am using ATMEGA2560 pro boar. I have also 4 TM1637 displays (two for each player) showing time and score. I am using 12V adapter. This is my schematic:

[![schematics][1]][1]

This is test code which I had:

    #include <Arduino.h>
    #include <TM1637Display.h>

    #define BTN_A1_PIN 16
    #define BTN_A2_PIN 18
    #define BTN_A3_PIN 28
    #define BTN_A4_PIN 26
    #define BTN_A5_PIN 47

    #define BTN_B1_PIN 44
    #define BTN_B2_PIN 36
    #define BTN_B3_PIN 39
    #define BTN_B4_PIN 46
    #define BTN_B5_PIN 37

    #define LED_A1_PIN 13
    #define LED_A2_PIN 17
    #define LED_A3_PIN 11
    #define LED_A4_PIN 15
    #define LED_A5_PIN 19

    #define LED_B1_PIN 25
    #define LED_B2_PIN 27
    #define LED_B3_PIN 23
    #define LED_B4_PIN 21
    #define LED_B5_PIN 29

    #define BTN_START_PIN 32
    #define LED_START_PIN 35

    #define DISPLAY_A_SCORE_CLK 20
    #define DISPLAY_A_SCORE_DIO 10

    #define DISPLAY_A_TIME_CLK 40
    #define DISPLAY_A_TIME_DIO 43

    #define DISPLAY_B_SCORE_CLK 42
    #define DISPLAY_B_SCORE_DIO 33

    #define DISPLAY_B_TIME_CLK 34
    #define DISPLAY_B_TIME_DIO 38

    typedef struct
    {
      uint8_t btnIn;
      uint8_t ledOut;
    } btn_t;

    btn_t btn[] = {
        {
            .btnIn = BTN_A1_PIN,
            .ledOut = LED_A1_PIN,
        },
        {
            .btnIn = BTN_A2_PIN,
            .ledOut = LED_A2_PIN,
        },
        {
            .btnIn = BTN_A3_PIN,
            .ledOut = LED_A3_PIN,
        },
        {
            .btnIn = BTN_A4_PIN,
            .ledOut = LED_A4_PIN,
        },
        {
            .btnIn = BTN_A5_PIN,
            .ledOut = LED_A5_PIN,
        },
        {
            .btnIn = BTN_B1_PIN,
            .ledOut = LED_B1_PIN,
        },
        {
            .btnIn = BTN_B2_PIN,
            .ledOut = LED_B2_PIN,
        },
        {
            .btnIn = BTN_B3_PIN,
            .ledOut = LED_B3_PIN,
        },
        {
            .btnIn = BTN_B4_PIN,
            .ledOut = LED_B4_PIN,
        },
        {
            .btnIn = BTN_B5_PIN,
            .ledOut = LED_B5_PIN,
        },
        {
            .btnIn = BTN_START_PIN,
            .ledOut = LED_START_PIN,
        },
    };

    TM1637Display displayAScore(DISPLAY_A_SCORE_CLK, DISPLAY_A_SCORE_DIO);
    TM1637Display displayATime(DISPLAY_A_TIME_CLK, DISPLAY_A_TIME_DIO);
    TM1637Display displayBScore(DISPLAY_B_SCORE_CLK, DISPLAY_B_SCORE_DIO);
    TM1637Display displayBTime(DISPLAY_B_TIME_CLK, DISPLAY_B_TIME_DIO);

    void setup()
    {
      for (int i = 0; i < 11; i++)
      {
        pinMode(btn[i].btnIn, INPUT_PULLUP);
        pinMode(btn[i].ledOut, OUTPUT);
      }
      displayAScore.setBrightness(0x0f);
      displayATime.setBrightness(0x0f);
      displayBScore.setBrightness(0x0f);
      displayBTime.setBrightness(0x0f);

      displayAScore.showNumberDec(1111, false);
      displayATime.showNumberDec(2222, false);
      displayBScore.showNumberDec(3333, false);
      displayBTime.showNumberDec(4444, false);
    }

    void loop()
    {
      for (size_t i = 0; i < 11; i++)
      {
        if(0 == digitalRead(btn[i].btnIn))
        {
          digitalWrite(btn[i].ledOut, HIGH);
        }
        else
        {
          digitalWrite(btn[i].ledOut, LOW);
        }
      }
    }

And this is what it looks like inside:

[![arcade box inside][2]][2]

[![arcade box front][3]][3]

The problem is **ATMEGA2560** just burned. I was testing it firstly without TM1637 (they were connected to power but I did not use lib for them at that time) and it was working okay (buttons were lighting up upon pressing).

Then I added lib for TM1637 to code and for 2 seconds I saw "1111" "2222" ... so on as it is in code, so there is no bad connection. But after 2 seconds it started buzzing (probably linear regulator temp protection was kicking in) and ATMEGA just burned.

Now when I plug 12V in it MCU gets hot pretty fast. I can measure 5V on the linear regulator so it is not shorted. I had always connected only 12V and no power from USB. I know my wires are not the shortest but I would not expect that MCU dies. Could you help please? I don't want to plug the next 20€ chip just to see another expensive smoke.

  [1]: https://i.stack.imgur.com/ocdaM.png
  [2]: https://i.stack.imgur.com/Q5RMw.jpg
  [3]: https://i.stack.imgur.com/ikW0B.jpg

sender: assistant

body: You fried it because you broke rule #1: "A Power Supply the Arduino is NOT!". Your displays can pull 320 Ma in themselves. That is over 2 watts of power before anything else. When you get a new one purchase a buck converter and power the LEDs with the 5V output of that, use the 12V to feed it. As I understand it The suggested maximum power dissipation for the Mega regulator is 1 Watt. So with 12V into the regulator the max current is about 140 mA (1W / (12V - 5V)), This does not count your LEDs.


message:
How can I get the Arduino IDE v0021 running on Windows XP to communicate with the latest Nano v3.0

After reading another post
<https://arduino.stackexchange.com/questions/51729/ch340-nano-avrdude-stk500-getsync-not-in-sync-resp-0xa4>
I have discovered that the bootloader on current Nano v3.0 has been upgraded. However, the advice given to overcome this problem is based around a more modern version of the Arduino IDE communicating with an old bootloader. I have the reverse problem. I damaged my Arduino Nano that was working with a laptop running Windows XP and bought a replacement. It obviously has the latest bootloader installed so my version of the Arduino IDE v0021 (recommended to run on Windows XP) can no longer upload sketches to the board.

I have uploaded GRBL v1.1h to the Nano board from an Arduino IDE v1.8.19 installation on a Windows 7 computer but the older version of GRBL Control v0.8.1 running on Windows XP has compatibility issues with GRBL 1.1h. I need to upload an earlier version of GRBL that is compatible with GRBL Control v0.8.1 but the bootloader on the new Arduino Nano v3.0 runs at 115200 and the Arduino IDE v0021 expects a baud rate of 57600 so I get these errors

>stk500_getsync():not in sync: resp=0x09
>
>stk500_disable(): protocol error, expect=0x14, resp=0x51

Can I upload an older bootloader to a newer Arduino Nano so I can then flash an older version of GRBL that is compatible with GRBL Control v0.8.1 to run on Windows XP?

body:
I agree with Juraj that any bootloader can be uploaded to the newer version of the Nano. However, the process of doing so is not simple. With Windows XP SP3 installed on my laptop I was running Arduino IDE v0021. The process involves connecting an Arduino UNO R3 to the Arduino Nano v3.0 but first you have to communicate with both boards through the Arduino IDE v0021. This requires two different USB drivers. For Device Manager to recognise the UNO R3 I had to copy the "Drivers" folder from my Arduino IDE v1.8.19 installation on my Windows 7 computer to my Arduino IDE v0021 installation folder on my laptop. Inside that drivers folder is a file called "Old_Arduino_Drivers.zip". You need to expand that into the "Drivers" folder.
In Device Manager with the Arduino UNO R3 plugged in you can now update the driver for the "Unknown USB" device by searching in the "Drivers" folder. On my computer it installed it as Arduino UNO R3 on COM7. It may be a different COM port on your computer. ***NOTE: FTDI and CH340 drivers will NOT work on Windows XP with the Arduino UNO R3.***

Now disconnect the Arduino UNO R3 and connect the Arduino Nano v3.0. Once again Device Manager should not recognise it. Search the "Drivers" folder once again and it should find a driver. However, this time it will use an FTDI driver to install the Nano. It showed up in Device Manager as USB Serial Port on COM5.

After both these drivers were successfully installed my Arduino IDE v0021 could communicate with both Arduino boards and it could upload sketches to the Arduino UNO R3 but not the Nano...yet. I connected the Arduino UNO R3 and uploaded, "ArduinoISP" from the menu File >> Examples.

I then unplugged the USB cable from the Arduino UNO R3 and physically connected wires between the UNO and the Nano (see the connection diagram [here](https://support.arduino.cc/hc/en-us/articles/4841602539164-Burn-the-bootloader-on-UNO-Mega-and-classic-Nano-using-another-Arduino)).

With both boards wired correctly, plug the USB cable back into the Arduino UNO R3. You should see LEDs light up on both boards. Open the Arduino IDE v0021 and from the Tools menu select "Arduino Duemilanove or Nano w/ ATmega328" as the board. ***NOTE: Do NOT select "Arduino Uno" even though it is the board connected to your computer. You are about to burn a new bootloader to the Nano not the Uno.*** Next select whatever serial port has been allocated to the device. In my case COM7 was allocated to the UNO.
Now from the "Tools" menu select "Burn Bootloader >> w/ Arduino as ISP". This worked for me and I was finally able to upload sketches to the Arduino Nano v3.0 using the old version 0021 of the Arduino IDE on Windows XP.


message:
avrdude: ser_open(): can't open device "\\.\COM5": Access is denied

I'm getting the error as follows

>Sketch uses 2952 bytes (9%) of program storage space. Maximum is 32256 bytes.\
Global variables use 196 bytes (9%) of dynamic memory, leaving 1852 bytes for local variables. Maximum is 2048 bytes.\
avrdude: ser_open(): can't open device "\\.\COM5": Access is denied.\
Failed uploading: uploading error: exit status 1

The board I am using is Arduino Uno and checked the ports too. Also restarted and installed IDE again. But still not being able to deal with it.
I will be happy with the help!

body:
In Windows (if you are using windows), There are two things may caused the problem:
- go to device manager >> ports >> and Uninstall all ports related to Arduino (including the COM5). Then connect the arduino again and it install it again automatically.
- Make sure that you close all "serial monitor", before uploading the sketch.


message:
Connecting nRf24L01 to Atmega328PU with external 8Mhz Crystal problem

I am trying to fix the problem of communicating between two nRf24l01+ together, one connected to Arduino Uno and another connected to Atmega328PU with 8Mhz external crystal.

The bootloader on Atmega328PU is “Arduino Pro or Pro Mini” 3.3V 8Mhz. The problem is the nRf24L01+ on Atmega328PU is not responding (working). I am using the RF24 library as shown in the code below. There are several things that I already tried:
1. To make sure that both nRf24L01+ modules work, I connected one to Arduino Uno and another to Arduino Mega and they work perfectly. So, the problem is not from the nRf modules.
2. I changed the external crystal of atmega328PU to 16 Mhz and changed the bootloader to Arduino Uno. Didn’t work again.

The circuit diagram is shown below:

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

Transmitter Code:
```c++
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN

const byte address[6] = "00001";
const int btn = 4;
int buttonState = 0;
int programState = 0;

void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
  pinMode(btn, INPUT);
}

void loop() {
  buttonState = digitalRead(btn);
    // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
    if ((buttonState == LOW) && (programState == 0)) {
          programState = 1;
    }

    else if((buttonState == HIGH)&& (programState == 1)){
        const char text[] ="Hello World"; // you can customize this text to your wish
        radio.write(&text, sizeof(text));
        programState = 0;
        Serial.println("BUTTON");

        delay(1000);
  }

}
```

Receiver Code:

```c++
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
const int output = 2;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  pinMode(output,OUTPUT);
  digitalWrite(output, LOW);
  delay(1000);
}

void loop() {
  if (radio.available()) {
    char text[32] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text);
    if (strcmp(text,"Hello World")==0){

        Serial.println("CORRECT");
        digitalWrite(output, HIGH);
        delay(2000);
        digitalWrite(output, LOW);
        delay(2000);
    }
  }
}
```

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

body:
Assuming a basic test of the MCU works, say the blink sketch works at normal speed (0.5 Hz), try this format of the constructor:

`RF24 radio(7, 8, 4000000); // set SPI speed to 4MHz instead of default 10MHz`

The default of 10MHz maybe too high for your MCU configuration.

From https://github.com/nRF24/RF24/blob/master/COMMON_ISSUES.md

Some more things to try:

EDIT

Most Nrf24L01 problems are related to an inadequate power supply. Some 3.3 volt power supplies, say those of a Nano where the 3.3 volts is derived from the USB/UART adaptor, don't work well here. You could try adding two capacitors across the power rails at the point on the breadboard where the power for the nrf24L01 is taken. Use a 100nF ceramic and a 10 to 100uF electrolytic. You barebones atmega328p should anyway have its own decoupling capacitor as close as possible to the chip's power pins. Use a 100nF ceramic.

The link above has other trouble shooting measures.


message:
NodeMCU code that both display OLED and control WS2812 LED Ring

I'm trying to make a project using NodeMCU that show pictures in small OLED screen and also controlling WS2812 LED Ring.

I manage to do each of them separately but I'm not sure how to mix them together. The problem lies in the fact that most code examples for both the screen and the LED use sleep and that will of course only work for one of the other but not both.

[This is the first project I've looked at to display bitmaps with SSD1306  screen and nodemcu][1].

[This is the second project I've looked at to control NeoPixel WS2812 ring][2].

The main project was that both of them use `delay` as a way to wait for some amount of time to "progress". But, I couldn't just wait because then it will mess up both the screen and the NeoPixel.

One more thing is I have to also take reading input into account. I still not 100% sure about the input but it will probably be potentiometer and maybe a button.

I think I have found the solution which is to break the large "tasks" of reading input, controlling screen and controlling leds into smaller parts and do the waiting in a cooperative way.

[I've found this instructable which both explain how to do it and also provide code example][3].

I'll be glad to know if people how other ways to implement this.

  [1]: https://www.instructables.com/How-to-convert-bitmap-graphics-for-OLED-SSD1306-di/
  [2]: https://danielthepope.wordpress.com/2021/05/24/controlling-ws2812b-leds-with-nodemcu/
  [3]: https://www.instructables.com/Cooperative-Multitasking-on-Arduino-With-Pretty-Bl/

body:
You need to stop using `delay` and instead keep track of elapsed time. One of the comments under your question suggests looking at the BlinkWithoutDelay example, which is part of the Arduino IDE.

The jocular comment "how do you drink some water while eating dinner" suggests the solution. You do one thing for a moment, and then do another thing. When eating dinner you don't wait for the entire meal to be consumed before you can drink a glass of water.

Here's some example code that blinks two LEDs at different rates:

<!-- language: c++ -->

    // Which pins are connected to which LED
    const byte greenLED = 12;
    const byte redLED = 13;

    // Time periods of blinks in milliseconds (1000 to a second).
    const unsigned long greenLEDinterval = 500;
    const unsigned long redLEDinterval = 1000;

    // Variable holding the timer value so far. One for each "Timer"
    unsigned long greenLEDtimer;
    unsigned long redLEDtimer;

    void setup ()
      {
      pinMode (greenLED, OUTPUT);
      pinMode (redLED, OUTPUT);
      greenLEDtimer = millis ();
      redLEDtimer = millis ();
      }  // end of setup

    void toggleGreenLED ()
      {
       if (digitalRead (greenLED) == LOW)
          digitalWrite (greenLED, HIGH);
       else
          digitalWrite (greenLED, LOW);

      // remember when we toggled it
      greenLEDtimer = millis ();
      }  // end of toggleGreenLED

    void toggleRedLED ()
      {
       if (digitalRead (redLED) == LOW)
          digitalWrite (redLED, HIGH);
       else
          digitalWrite (redLED, LOW);

      // remember when we toggled it
      redLEDtimer = millis ();
      }  // end of toggleRedLED

    void loop ()
      {

      // Handling the blink of one LED.
      if ( (millis () - greenLEDtimer) >= greenLEDinterval)
         toggleGreenLED ();

      // The other LED is controlled the same way. Repeat for more LEDs
      if ( (millis () - redLEDtimer) >= redLEDinterval)
        toggleRedLED ();

    /* Other code that needs to execute goes here.
       It will be called many thousand times per second because the above code
       does not wait for the LED blink interval to finish. */

    }  // end of loop


message:
Arduino AVR Program with default ATMEGA32U4 bootloader instead

I’m working an Arduino program that uses the FastLED library and is all coded in the Arduino IDE (not my choice, just a result of this OOS library).

However, I don’t want to run this on an “Arduino” board. Instead, I want to flash this to a factory fresh ATMEGA32U4 as an MCU for the project. However, the ATMEGA32U4 doesn’t come with the Arduino boot loader, but instead, DFU. I have flashing procedures designed for the DFU boot loader already and I don’t want to go swapping bootloaders.

Would the Arduino program work fine without swapping to the Arduino bootloader? My understanding is *yes* since the bootloader only controls the boot sequence, and has nothing to do with runtime.

body:
> Would the Arduino program work fine without swapping to the Arduino bootloader?

Yes, the bootloader is only there for conveniently changing program memory via serial instructions.

Whatever method you use to put the "main" code there, it will be the same code and will operate the same.


message:
Changing SPI ports on an Arduino

My end goal is to read information from an nRF24l01 module connected to my Arduino UNO R3, and generate an interrupt whenever a message is sent to the Arduino.

Now, I have read that for Hardware interrupts, only pins D2 and D3 can be used to generate interrupts. However, while connecting the MISO line, I saw that [here](https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP) it was mentioned that
>On some Arduino boards (see table above), pins MOSI, MISO and SCK are the same pins as digital pin 11, 12 and 13, respectively. That is why many tutorials instruct you to hook up the target to these pins.

On every website I have searched, MISO is always connected to 12. <b>Is there any way to change the MISO line from 12 to 3, or will I have to resort to using Pin change interrupts?</b> Another way I can think of to bypass this is to connect D12 to D3, but I'm afraid this may cause complications in the circuit.

body:
>  I have read that for Hardware interrupts, only pins D2 and D3 can be used to generate interrupts

The pin-change interrupts, available on all pins of the Arduino Uno, are almost as good. I say "almost" because the only thing you have to do is work out which pin caused the interrupt, which can be trivial if you only set up one pin to generate interrupts.

>  Is there any way to change the MISO line from 12 to 3,

Not if you used the hardware SPI on the chip. If you use bit-banged SPI you can use any pins.

I did a project for a [temperature and humidity sensor](http://www.gammon.com.au/forum/?id=12106), which logs to a SD card (using SPI), and also displays on a 8-digit display (using SPI). For the latter case I used bit-banged SPI, as described there.

I have [a page about SPI](http://www.gammon.com.au/spi) and also [a similar one on Stack Exchange](https://arduino.stackexchange.com/questions/16348/how-do-you-use-spi-on-an-arduino/16349#16349).

My bit-banged SPI code is available [here](https://github.com/nickgammon/bitBangedSPI).

---

I'm not clear about why you don't just use the hardware SPI pins. Is that you want an interrupt when a SPI message arrives? There is a hardware interrupt for just that. See my posts about SPI for more details about that.


body:
# My second answer ...

Your question, in bold, is a good example of an XY Problem. You asked:

> Is there any way to change the MISO line from 12 to 3, or will I have to resort to using Pin change interrupts?

This is the X question. However the Y question is your goal:

> My end goal is to read information from an nRF24l01 module connected to my Arduino UNO ...

I answered, in another answer, first about changing the MISO line from pin 12, and also pointed out that SPI transactions can generate interrupts.

However, as Juraj pointed out in a comment, the Arduino in this case is the **master** and the nRF24l01 is the **slave** (from the SPI point of view).

There is no way that a slave can burst into life and generate a message, and hence cause an interrupt. That is the master's job.

As I read on [this page about the module](https://lastminuteengineers.com/nrf24l01-arduino-wireless-communication/) it has an IRQ pin described thus:

> IRQ is an interrupt pin that can notify the master when there is new data to process.

So, your job is simplified, really. You don't need to detect when an SPI transaction starts (the Arduino will start the transaction), you need to connect the IRQ pin to an Arduino pin and detect that data is ready. Simple! Then you can easily use pin 2 or pin 3 if you want to use the "hardware" interrupts rather than the pin-change interrupts. (The pin-change interrupts are hardware interrupts too, though).


message:
ESP8266 Wifi connection problem

I have a Feather Huzzah, aka ESP8266, that I am trying to connect to the Wifi.

One major thing is, that my landlord decided to use the worst Wifi SSID and PW.

The SSID contains an ä and a whitespace, and the PW an @.

I scanned successfully the Wifi with the board and the prewritten code and the Wifi shows up.

Now I am using the Wifi client basic, just to check if any connection can established.

I tried to write all special characters in Unicode, but still no change.

Here is my code:

    /*
    This sketch sends a string to a TCP server, and prints a one-line response.
    You must run a TCP server in your local network.
    For example, on Linux you can use this command: nc -v -l 3000
    */

    #include <ESP8266WiFi.h>
    #include <ESP8266WiFiMulti.h>

    #ifndef STASSID
    #define STASSID "XXX XXäXX"      //original SSID
    #define STASSID "XXX XX\u00e4XX" //Unicode SSID
    #define STAPSK "XXX@XXX"        //Orginal PW
    #define STAPSK "XXX@XXX"        //Unicode PW
    #endif

    const char* ssid = STASSID;
    const char* password = STAPSK;

    const char* host = "192.168.1.1";
    const uint16_t port = 3000;

    ESP8266WiFiMulti WiFiMulti;

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

      // We start by connecting to a WiFi network
      WiFi.mode(WIFI_STA);
      WiFiMulti.addAP(ssid, password);

      Serial.println();
      Serial.println();
      Serial.print("Wait for WiFi... ");

      while (WiFiMulti.run() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
      }

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

      delay(500);
    }

    void loop() {
      Serial.print("connecting to ");
      Serial.print(host);
      Serial.print(':');
      Serial.println(port);

      // Use WiFiClient class to create TCP connections
      WiFiClient client;

      if (!client.connect(host, port)) {
        Serial.println("connection failed");
        Serial.println("wait 5 sec...");
        delay(5000);
        return;
      }

      // This will send the request to the server
      client.println("hello from ESP8266");

      // read back one line from server
      Serial.println("receiving from remote server");
      String line = client.readStringUntil('\r');
      Serial.println(line);

      Serial.println("closing connection");
      client.stop();

      Serial.println("wait 5 sec...");
      delay(5000);
    }

Thank you for any help, and greetings from Sweden.

body:
Start with a known simple SSID, and try this:

    #define STASSID "mywifi" // For example this is the known SSID that connects
    ... ... ...
    const char ssid[] = "mywifi";

If that works, then you can replace the `char` with hex.

    const char ssid[] = {0x6D, 0x79, 0x77, 0x69, 0x66, 0x69};

If that works then you can replace the hex bytes with your actual SSID. And in the place of `ä` use those two hex bytes as jsotola mentioned, `0xC3` and `0xA4`.

---
Edit 1:

From the comment, it looks like the receiver never connects to the WiFi. In the receiver hardware, try something simple and see if it gets connected at all or not.

    #include <ESP8266WiFi.h>

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

      WiFi.begin("network-name", "pass-to-network");

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

      Serial.print("Connected, IP address: ");
      Serial.println(WiFi.localIP());
    }

    void loop() {}

Check what output you get.


body: I don't have enough reputation to comment, otherwise this would be a comment, but you could ask your landlord to change the password. If he says no, you could say one of your devices can't type that character.


message:
Problem when coding 4x4 keypad's key detection (without library)

Part of my current assignment involves reading the input from a 4x4 keypad connected to an Arduino UNO. While this may be done easily using <Keypad.h>, the project is being done with Tinkercad's online simulator, meaning I don't have access to that library. I have to do it the manual way.

This is the code I've got so far:

````
#include <Wire.h>
#define DIMENSIONS 4
const unsigned long period = 50;
unsigned long prevMillis = 0;
byte modo = 0;
const byte rowsPins[DIMENSIONS] = {11, 10, 9, 8};
const byte columnsPins[DIMENSIONS] = {7, 6, 5, 4};
char keys[DIMENSIONS][DIMENSIONS] = {
 {'1', '2', '3', 'A'},
 {'4', '5', '6', 'B'},
 {'7', '8', '9', 'C'},
 {'*', '0', '#', 'D'}
};

void setup()
{
 Serial.begin(9600);// debug
 for(byte i = 0; i < DIMENSIONS; i++){
  pinMode(columnsPins[i], INPUT);
  digitalWrite(columnsPins[i], HIGH);
  pinMode(rowsPins[i], INPUT_PULLUP);
 }
 Wire.begin();
}

void loop()
{
 switch(modo){
  case 0:
   Serial.print("Master (2) boot up\n");
   modo++;
   break;
  case 1:
   if(millis() >= 1000){
    modo++;
   }
   break;
  case 2:
   if (millis() - prevMillis > period){
    prevMillis = millis();
    for(byte c = 0; c < DIMENSIONS; c++){
     pinMode(columnsPins[c], OUTPUT);
     digitalWrite(columnsPins[c], LOW);
     for(byte r = 0; r < DIMENSIONS; r++){
      if(digitalRead(columnsPins[r]) == LOW){
       Serial.println(keys[r][c]);
      }
     }
     digitalWrite(columnsPins[c], HIGH);
     pinMode(columnsPins[c], INPUT);
    }
   }
   break;
  default:
   break;
 }
}
````

(the "modes" and Wire.h are a different part of the assignment and not related to my issue)

This code should, in theory, read the input from the connected 4x4 keypad and then print on the serial monitor which key was pressed. I've done a fair bit of searching, and other solutions for detecting key presses without the Keypad library aren't super different from what I've done here. However, for some reason, what I wrote is not working properly for me.

On starting the simulation, the serial monitor prints 1, 5, 9, D continuously and repeatedly on a loop. Pressing the keys does sometimes print the appropriate character, but it does not stop the flood of 1s, 5s, 9s and Ds.

I know for a fact that it's not a matter of the pins being misconnected, I've checked for that at least a dozen times by now. It's most certainly a matter of code... but I can't figure out where the problem lies.

body:
In case 2:

    digitalWrite(columnsPins[c], LOW);
    for(byte r = 0; r < DIMENSIONS; r++){
       if(digitalRead(columnsPins[r]) == LOW){
       Serial.println(keys[r][c]);
       }
    }

Since you just wrote one of the column pins low, you can guarantee that one is going to read low.  Did you mean to read the row pins?


message:
Instructables "Omnibot" -- using the "real" Uno R3 board

Step 4 of this instructable uses what seems to be a "knock-off" development version of the Uno R3 board, where an RF receiver is soldered to pads that don't exist on the R3 or R3 SMD boards:

https://www.instructables.com/OmniBot-Easy-Arduino-RC-Robots/

> ...
>
> 4. Locate available Gnd, Vcc, and Rx holes on your Arduino. (if using the recommended Arduino they can be found all near each other just below the ICSP pins.)
> 5. Insert the tinned wires through their respective holes and solder on the back side. White to RX, red to 5V, black to GND.
>
> ...

I am completely new to Arduino, so I'm a little puzzled by the lack of VCC. Sounds like this is just power. Is there any reason I can't hook the RF receiver to the D0 (RX) pin, 5v out, and GND headers?

body: Yes, the holes they are showing it connected to are physically connected to the pins you mention.  Connecting directly to those pins would be equivalent.


message:
Expose two HID Joystick devices with single RP2040 board (Waveshare Pi Pico Zero)

I want to use a Waveshare Pi Pico Zero to connect two standard NES controllers to a computer over a single USB port.

I'm using the `Waveshare RP2040 Zero` board definition from https://github.com/earlephilhower/arduino-pico which seems to provide a `Joystick` HID library that was compatible with this Teensy targeted [NES_to_USB](https://github.com/GadgetReboot/Arduino/tree/master/Teensy/NES_To_USB) sketch. However, that only works for a single NES controller.

I found [Arduino-USB-HID-RetroJoystickAdapter](https://github.com/mcgurk/Arduino-USB-HID-RetroJoystickAdapter/blob/master/README.md) that supports two joysticks or NES controllers using a single board using the [MHeironimus ArduinoJoystickLibrary](https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-1.0). Unfortunately it seems that particular Joystick library only supports ATmega32u4 based Arduino boards (e.g. Leonardo, Pro Micro).

## Ask
A solution for exposing two USB HID Joystick devices on a single Pi Pico Zero board. First prize is a drop-in library like [MHeironimus ArduinoJoystickLibrary](https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-1.0) that is compatible with https://github.com/earlephilhower/arduino-pico's RP2040 core. Happy to hear of more DIY solutions too, not sure if I'll be able to follow though :)

body:
By selecting the Adafruit TinyUSB USB stack option (Tools->USB Stack->Adafruit TinyUSB) of the `arduino-pico` core instead of the default (Pico SDK) the USB HID descriptors can be configured directly to expose two HID gamepads.

The disadvantage of this approach is that the easy to use preconfigured devices (e.g. `Joystick`, `Mouse` and `Keyboard`) are not configured, but this gives you the option to use the full flexibility of TinyUSB to configure USB devices. While I've used it with my Waveshare Pi Pico Zero board it should work with any Arduino board that [Adafruit TinyUSB](https://github.com/adafruit/Adafruit_TinyUSB_Arduino/tree/master) supports.

Here is a test sketch that sets up a HID device with two gamepads similar to the "Hey how about two players?" example in https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/. I modified the [Adafruit TinyUSB hid_gamepad.ino example](https://github.com/adafruit/Adafruit_TinyUSB_Arduino/blob/ffaa85e9e7cff1b5cc87451082f8fa0a829dae7b/examples/HID/hid_gamepad/hid_gamepad.ino) by adding a second Gamepad report and shortening the "demo" loop to save space:

```c
/*********************************************************************
 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 Copyright (c) 2021 NeKuNeKo for Adafruit Industries
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

#include "Adafruit_TinyUSB.h"

// NB NB!!! Select "Adafruit TinyUSB" for USB stack

// HID report descriptor using TinyUSB's template
uint8_t const desc_hid_report[] =
{
  TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(1)), // First gamepad report-id 1
  TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(2))  // Second gamepad report-id 2
};

// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_NONE, 2, false);

// Report payload defined in src/class/hid/hid.h
// - For Gamepad Button Bit Mask see  hid_gamepad_button_bm_t
// - For Gamepad Hat    Bit Mask see  hid_gamepad_hat_t
hid_gamepad_report_t   gp[2]; // Two gamepad descriptors

void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
  // Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
  TinyUSB_Device_Init(0);
#endif

  Serial.begin(115200);
  usb_hid.begin();

  // wait until device mounted
  while( !TinyUSBDevice.mounted() ) delay(1);
  Serial.println("Adafruit TinyUSB HID multi-gamepad example");
}

uint8_t gp_i = 0;

void loop()
{
  if ( !usb_hid.ready() ) return;

  Serial.print("Testing gamepad nr: ");
  Serial.println(gp_i);

  // Reset buttons
  Serial.println("No pressing buttons");
  gp[gp_i].x       = 0;
  gp[gp_i].y       = 0;
  gp[gp_i].z       = 0;
  gp[gp_i].rz      = 0;
  gp[gp_i].rx      = 0;
  gp[gp_i].ry      = 0;
  gp[gp_i].hat     = 0;
  gp[gp_i].buttons = 0;
  // gp_i + 1 is the HID report-id, i.e. 1 for first gamepad and 2 for the
  // second, as defined in desc_hid_report[] above.
  usb_hid.sendReport(gp_i + 1, &gp[gp_i], sizeof(gp[gp_i]));
  delay(2000);

  // Random touch
  Serial.println("Random touch");
  gp[gp_i].x       = random(-127, 128);
  gp[gp_i].y       = random(-127, 128);
  gp[gp_i].z       = random(-127, 128);
  gp[gp_i].rz      = random(-127, 128);
  gp[gp_i].rx      = random(-127, 128);
  gp[gp_i].ry      = random(-127, 128);
  gp[gp_i].hat     = random(0,      9);
  gp[gp_i].buttons = random(0, 0xffff);
  usb_hid.sendReport(gp_i + 1, &gp[gp_i], sizeof(gp[gp_i]));
  delay(2000);

  // select the other gamepad
  gp_i = (gp_i + 1) % 2;
}

```

## Linux HID Malarkey
For some reason the Linux kernel by default ignores multiple reports of the same type of HID device. I.e. a device with a mouse, keyboard and joystick device reports are no problem, but if a device has multiple of the same HID reports, say, two gamepads, Linux will only see the first instance. To enable multiple instances the `HID_QUIRK_MULTI_INPUT` setting must be enabled for the specific USB device.

These instructions worked on Ubuntu 22.04, you may need to adjust them for your distro.

After programming the example sketch I could see the ID of my Pi Pico USB device with `lsusb:

```
$ lsusb
...
Bus 001 Device 011: ID 239a:cafe Adafruit RP2040 Zero
...
```

Note down the USB device identifier (`239a:cafe`) and create a file in `/etc/modprobe.d` to configure the `usbhid` module:

```
$ echo "options usbhid quirks=0x239a:0xcafe:0x040" | sudo tee /etc/modprobe.d/adafruit_hid_quirk.conf

$ sudo update-initramfs -u

# Requires a reboot to take effect, e.g.:

$ sudo shutdown -r now

```
The `0x239a:0xcafe` is from the `lsusb` output and `0x040` is the magic number to enable `HID_QUIRK_MULTI_INPUT` mode. We need `update-initramfs` since `usbhid` is usually loaded too early in the boot process for the settings from `/etc/modprobe.d` to take effect without it being in the `initrd`.

Once you have rebooted you can check if the `usbhid` setting took effect:

```
$ cat /sys/module/usbhid/parameters/quirks
0x239a:0xcafe:0x040,(null),(null),(null)

```

and you should see two joystick devices after programming the sketch:

```
ls /dev/input/js*
/dev/input/js0  /dev/input/js1

```

## Testing
An easy way to test is to navigate to https://gamepad-tester.com/. After a short period you should see something like:

[![Player 1 and Player 2 Gamepads][1]][1]

You should see Player1's values toggle and then Player2's values until you unplug your pico.

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


message:
Can't install to arduino mega 2560 using arduino-cli, but can using IDE

I have a MKS GEN L v1.0 3dprinter board that works fine uploading using the IDE. But I need to install to it using the arduino-cli.

For some reason, the command `arduino-cli board list` says that the board has an unknown FQBN. Which is fine, I guess. I guess I don't know how to compile & upload without the FQBN.

The options I need selected (which work in the IDE) are:
 - Board: Arduino/Genuino Mega or Mega 2560
 - Processor: ATmega2560
 - Programmer: AVRISP mkII

I don't understand why these options aren't clearly available in the arduino-cli.

I ran these commands: `arduino-cli core install arduino:avr and arduino-cli core install arduino:megaavr`

I ran ` arduino-cli board list`. It says /dev/ttyUSB0, serial, Serial Port (USB), "Unknown" for FQBN....

I run `arduino-cli compile Marlin`. It says "unknown FQBN".

So how do I install using the same parameters in the IDE?

body:
I would guess, that the arduino-cli doesn't recognize your boards FQBN, since it is not a genuine Arduino board. My Arduino Nano clones (with the CH340 USB-Serial-chip) aren't recognized as Arduino Nanos either. For me that's the same with the Arduino IDE.

Though, since you already know what board you have, you can find the FQBN yourself by looking through the list in the output of

    arduino-cli board listall

or if you want to narrow the list down a bit:

    arduino-cli board listall avr

There you will find the line with the Megas FQBN:

    Arduino Mega or Mega 2560        arduino:avr:mega

Then you need to know, which Serial interface/COM port your Arduino has. This is done analog to the Arduino IDE: Check the list of connected boards via

    arduino-cli board list

If you cannot identify it directly from the list, you might want to disconnect and connect it again, to see, what entry in this list reappears again.

Then compile and upload can be done like this (be sure to input your own COM port/Serial interface, if it differs from this):

    arduino-cli compile --fqbn arduino:avr:mega
    arduino-cli upload --fqbn arduino:avr:mega --port /dev/ttyUSB0

while being in the sketch folder.


message:
Communicating via Serial Monitor but not able to get comms via Terminal outside of Arduino IDE

I am using Arduino Nano 33 BLE. I am able to communicate via Serial Monitor within Arduino IDE, but not able to communicate via Terminal, outside of Arduino IDE. I am using Teraterm, do I need to do any additional setting?

No error messages. It does work on the Serial Monitor of Arduino IDE at 115200 baud rate with the default settings ("SERIAL_8N1"). The serial port Setup on Teraterm is the following:

`Speed: 115200 Data: 8 bit Parity: none. Stop bits: 1 bit. Flow control: none`

The thing is that it does what it has to do writing one command that is one letter, I mean, in my Arduino sketch if you write "$" on Serial Monitor it does a reset, and through Teraterm if you write "$" It does a reset as well,.. but on Teraterm if I type a command longer than one letter It doesn't even show what I type on Teraterm and doesn't recognize.

body:
In TeraTerm the local echo is off by default. So you won't see anything while you type something. Here are the settings:

1) First connect to the serial port.

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

2) Then go to `Setup`->`Terminal`.

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

3) Based on your code select what you are expecting to receive at the end of a transmission from Arduino and what you need to send at the end of your command to Arduino to tell it is the end of the command. Usually, it can be Carriage Return (CR: 0x0D) or Line Feed (LF: 0x13), or both.

Also, check `Local echo`. That will print whatever you are typing on the terminal.

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

4) Then `Setup`->`Serial port...`.

[![enter image description here][4]][4]

5) And configure your serial port accordingly.

[![enter image description here][5]][5]

  [1]: https://i.stack.imgur.com/WvAdx.png
  [2]: https://i.stack.imgur.com/LdEiw.png
  [3]: https://i.stack.imgur.com/sN7hg.png
  [4]: https://i.stack.imgur.com/ilolu.png
  [5]: https://i.stack.imgur.com/TDm7D.png


body:
What you call a “terminal” is actually a _terminal emulator_, i.e. a
computer program intended to emulate an old school [computer
terminal][]. CRT-based terminals were in turn designed to emulate still
older “hard-copy terminals”, like the venerable [ASR-33][]. A hard-copy
terminal (also called “teletypewriter”) is basically a typewriter fitted
with a serial port. Whatever you type is sent along the wire. Keystrokes
are sent _immediately_: these devices did not have memory (which was
hugely expensive at the time) and could not buffer your input. The
Teraterm program you are using inherits from this history: like a
teletypewriter, it sends your keystrokes immediately.

The Arduino serial monitor, in contrast, does not transmit as you type.
Instead, you type a line of text and, when you hit “Send”, the whole
line is sent at once, at the full speed of the serial port.

This makes a significant difference in terms of transmission timing.
With Teraterm, the Arduino program sees long pauses (which depend on
your typing speed) between successive characters. With the serial
monitor, successive characters are spaced by roughly 87 µs. If your
Arduino code [properly buffers its input][Majenko] until it receives an
end-of-line, then it will work equally well with Teraterm and with the
serial monitor. If, on the other hand, your code gets impatient and
times out while you are typing, then it will not get multi-character
commands you type on Teraterm.

Note that, if you want your Arduino program to be friendly to terminal
users, you may want to echo the characters you receive, as local echo on
the terminal is usually not on by default. More importantly, you may
want to handle the backspace key (which can send either ASCII BS or
ASCII DEL) to let the user fix their typos. See how this is done in this
very simple [command-line interpreter][interpreter].

[computer terminal]: https://en.wikipedia.org/wiki/Computer_terminal
[ASR-33]: https://en.wikipedia.org/wiki/Teletype_Model_33
[Majenko]: https://majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27
[interpreter]: https://gist.github.com/edgar-bonet/607b387260388be77e96


message:
Errors when trying to connect esp8266 to firebase

hello guys i was trying to connect my project to firebase but got this erorrs:
````
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\Firebase.cpp: In member function 'int FirebaseRequest::sendRequest(const string&, const string&, char*, const string&, const string&)':
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\Firebase.cpp:78:1: error: no return statement in function returning non-void [-Werror=return-type]
   78 | }
      | ^
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\Firebase.cpp: In member function 'void FirebaseStream::startStreaming(const string&, const string&, const string&)':
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\Firebase.cpp:91:16: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   91 |   analyzeError("STREAM", status, path_with_auth);
      |                ^~~~~~~~
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp: In member function 'virtual void FirebaseHttpClientEsp8266::begin(const string&)':
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp:47:50: error: no matching function for call to 'begin(const char*, const char [60])'
   47 |     http_.begin(url.c_str(), kFirebaseFingerprint);
      |                                                  ^
In file included from d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp:9:
C:\Users\NyK\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:166:10: note: candidate: 'bool HTTPClient::begin(String, uint16_t, String)' (near match)
  166 |     bool begin(String host, uint16_t port, String uri = "/")  __attribute__ ((error("obsolete API, use ::begin(WiFiClient, host, port, uri)")));
      |          ^~~~~
C:\Users\NyK\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:166:10: note:   conversion of argument 2 would be ill-formed:
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp:47:30: error: invalid conversion from 'const char*' to 'uint16_t' {aka 'short unsigned int'} [-fpermissive]
   47 |     http_.begin(url.c_str(), kFirebaseFingerprint);
      |                              ^~~~~~~~~~~~~~~~~~~~
      |                              |
      |                              const char*
In file included from d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp:9:
C:\Users\NyK\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:167:10: note: candidate: 'bool HTTPClient::begin(String, const uint8_t*)' (near match)
  167 |     bool begin(String url, const uint8_t httpsFingerprint[20])  __attribute__ ((error("obsolete API, use ::begin(WiFiClientSecure, ...)")));
      |          ^~~~~
C:\Users\NyK\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:167:10: note:   conversion of argument 2 would be ill-formed:
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp:47:30: error: invalid conversion from 'const char*' to 'const uint8_t*' {aka 'const unsigned char*'} [-fpermissive]
   47 |     http_.begin(url.c_str(), kFirebaseFingerprint);
      |                              ^~~~~~~~~~~~~~~~~~~~
      |                              |
      |                              const char*
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp: In member function 'virtual void FirebaseHttpClientEsp8266::begin(const string&, const string&)':
d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp:51:60: error: invalid conversion from 'const char*' to 'const uint8_t*' {aka 'const unsigned char*'} [-fpermissive]
   51 |     http_.begin(host.c_str(), kFirebasePort, path.c_str(), kFirebaseFingerprint);
      |                                                            ^~~~~~~~~~~~~~~~~~~~
      |                                                            |
      |                                                            const char*
In file included from d:\Kuliah\Mata Kuliah\Internet of Things\Arduino\libraries\FirebaseArduino\src\FirebaseHttpClient_Esp8266.cpp:9:
C:\Users\NyK\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:168:70: note:   initializing argument 4 of 'bool HTTPClient::begin(String, uint16_t, String, const uint8_t*)'
  168 |     bool begin(String host, uint16_t port, String uri, const uint8_t httpsFingerprint[20])  __attribute__ ((error("obsolete API, use ::begin(WiFiClientSecure, ...)")));
      |                                                        ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
cc1plus.exe: some warnings being treated as errors

exit status 1

Compilation error: exit status 1
````

i've installed the latest version of esp8266 and **"Firebase Arduino Client Library for ESP8266 By Mobitz"** but the error still occured. please help

here's my full code:
````

#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <FirebaseArduino.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include<DHT.h>

#define FIREBASE_HOST "*****firebaseio.com"
#define FIREBASE_AUTH "*****UKBpSMo07nUT8ZWYS9"

#define WIFI_SSID "******"
#define WIFI_PASSWORD "******"

#define DHTPIN D5
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

bool light;
bool fan;

unsigned long previousMillis = 0;
const long interval = 10000;

void setup() {
  pinMode(D1, OUTPUT);
  Serial.begin(115200);
  delay(500);
  WiFi.begin(WIFI_SSID,WIFI_PASSWORD);
  Serial.println("Connecting..");

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

  Firebase.begin(FIREBASE_HOST,FIREBASE_AUTH);
  dht.begin();

  delay(2000);
  // put your setup code here, to run once:
}

void readDatas(){
  float h=dht.readHumidity();
  float t=dht.readTemperature();

  Firebase.setFloat("Data/Temperature:",t);
  Firebase.setFloat("Data/Humidity:",h);
}

void loop() {
  light = Firebase.getBool("LightStates/switch");
  Serial.println(light);
  if(light==true){
    digitalWrite(D6, HIGH);
  }
  if(light==false){
    digitalWrite(D6, LOW);
  }

  fan = Firebase.getBool("FanStates/switch");
  Serial.println(fan);
  if(fan==true){
    digitalWrite(D7, HIGH);
  }
  if(fan==false){
    digitalWrite(D7, LOW);
  }

  unsigned long currentMillis = millis();
  if(currentMillis-previousMillis>=interval){
    readDatas();
    previousMillis=currentMillis;
  }

}

````

body: fixed by downgrading my esp8266 version to 2.7


message:
Problem compiling sketches for the arduino wavgat uno R33

I am configuring the arduino IDE to be able to compile and upload sketches for the arduino wavgat uno R3. I have installed the Arduino IDE, as well as the required drivers for the board. I also have downloaded the zip containing the "hardware" and "librairies" folder that i copied into the "Arduino" folder.

In the IDE, I can select the wavgat uno R3 as a board and the board is detected by the IDE.

However, when I try to compile any sketch, I get the following error message :

    avr-gcc: error: C:\Users\henry\AppData\Local\Temp\arduino\sketches\F2EF7F804783EB75A0A6457CF6D8C244/core\core.a: No such file or directory

    exit status 1

    Compilation error: exit status 1

I seems to be a problem related to the compilation. Is there something related to the compilation for the wavgat uno R3 that I forgot ?

Thank you in advance

body:
The problem was solved by using a specific version of the arduino IDE, the 1.8.15. You have to install the drivers and copy the correct driver files in the Arduino folder. The program then compile correctly and can be uploaded to the wavgat.

Also, when working on the wavgat nano, you have to select "WAVGAT UNO R3" as the board type, and not "WAVGAT NANO 3.0" as you might first think.


message:
How to get around passing a variable into an ISR

Okay so you aren't able to pass a variable into in ISR. This is causing problems for me. I'm using a rotary encoder, and I need it to be connected to an interrupt pin and running a ISR. When using this method, no pulses are ever skipped and the knob works great.

Currently I have the ISR setup like this:

    void vhISR()
    {
      // this checks the PINE register for a 1 or 0 on the 5th bit (or 6th)
      // I'm bit shifting the result so that variable is either true or false for comparison, not 16/0 or 32/0
      rotCurrentA = (PINE & B00010000) >> 4;
      rotB = (PINE & B00100000) >> 5;

      if (rotCurrentA != rotLastA)
        {
          if (rotCurrentA != rotB) // cw
            {
              voltageHigh += knobResolution;
              rotLastA = rotCurrentA;
            }
          else // ccw
            {
              voltageHigh -= knobResolution;
              rotLastA = rotCurrentA;
            }
        }
    }

The code simply varies voltageHigh by 0.1V increments. The problem is this: I need to do this same 0.1 variations on several other variables, depending on which one I select. I need to increase/decrease a voltageLow, a timer, and a resistance, all that need +/- 0.1 increments (but on different ranges. For instance, voltLow is somewhere between 0.1 & 5, and VH is somewhere between 6 & 10). Normally what I would do is just pass the variable I needed by reference into the function and have the function increment/decrement that variable....but an ISR is not a normal function and you cannot pass a variable into it.

How do I get around this? I'm not sure if that's enough information to go off of let me know.

body:
I would follow Delta\_G's advice, and write an ISR that counts the steps
and does nothing more. As a general rule, you want to do as little as
possible within an ISR. I would even avoid floating point and just count
the raw number of steps:

```c++
// Count of rotational steps updated in the ISR. Must be unsigned in
// order to avoid signed overflow, which is undefined behavior.
volatile uint16_t rotation_count;

void vhISR()
{
    static uint8_t rotLastA;
    uint8_t rotCurrentA = (PINE >> 4) & 1;
    uint8_t rotB = (PINE >> 5) & 1;

    if (rotCurrentA != rotLastA)
        return;
    if (rotCurrentA != rotB) // cw
        rotation_count++;
    else // ccw
        rotation_count--;
    rotLastA = rotCurrentA;
}

// Return the number of rotational steps since the last call. Should be
// called often enough to avoid overflowing an int16_t.
int16_t get_rotation()
{
    static uint16_t last_count;

    // Avoid a data race: rotation_count should not be modified while we
    // are reading it.
    noInterrupts();
    uint16_t count_copy = rotation_count;
    interrupts();
    int16_t delta = count_copy - last_count;  // this is signed!
    last_count = count_copy;
    return delta;
}
```

Note that the raw count is an unsigned number which can roll over modulo
216. The value returned by `get_rotation()`, however, is a
signed number which, owing to the rules of modular arithmetic, is
_immune_ to the rollover of the raw count. As long as you call
`get_rotation()` often enough (more often than every 32767 steps),
the returned value will always be correct.

Then, in your main program, you can use this to update whatever variable
you want:

```c++
const float knobResolution = 0.1;
float voltageHigh, voltageLow, resistance;

// The variable that the user has selected for changing.
enum {VOLTAGE_HIGH, VOLTAGE_LOW, RESISTANCE} selection;

void loop()
{
    // Set a pointer to the selected variable.
    float *selected_var;
    switch (selection) {
    case VOLTAGE_HIGH:
        selected_var = &voltageHigh;
        break;
    case VOLTAGE_LOW:
        selected_var = &voltageLow;
        break;
    case RESISTANCE:
        selected_var = &resistance;
        break;
    }

    // Update the selected variable.
    *selected_var += get_rotation() * knobResolution;
}
```

Note here that the `selection` enum is probably redundant with
`selected_var`. You could use the latter to keep track of the user
selection, then you would not need the `switch`/`case`.


body:
> Okay so you aren't able to pass a variable into in ISR ...

Not as such, because the ISR is triggered by hardware, and therefore you don't pass arguments to it.

However there is nothing stopping you having a global variable which the ISR can access (preferably declared `volatile`) so the ISR can change its behaviour depending on what the global variable holds.


message:
Does ESP32 can support WIFIDirect

I would like to establish a simple P2P connection between an ESP32 and an Android device without the use of an access point. I should be able to send and receive data from the ESP32 through the established connection. Is this possible, and if not, are there any alternative solutions?

body: I do know that you can host a web page on an esp8266, sending and receiving data on that. You can from there connect the Android to that web page. I am not sure what you mean by access point, and I hope that this method is not using an access point.


body: From my research i for to know that we can't use wifi direct for esp32 i found an alternative for my problem!!!!


message:
How to ignore garbage values in serial communication between arduino and python

I have `arduino uno`. I am trying to send and receive serial data from arduino to python. I have [usb to uart converter](https://i.ebayimg.com/images/g/49wAAOSw~XhZlUdj/s-l1200.jpg). I have connected its `tx` to `rx` of Arduino and `rx` to `tx` of Arduino and `gnd` is connected to `gnd`. I have connected this usb to my laptop where I have written below python script:

    import serial

    ser = serial.Serial(port='COM6')

    res = ser.read(10)
    print(bytes.hex(res))
    data = b"\x7E\x7E\xAA\x03\xAB\x77"
    ser.write(data)

    ser.close()

In above code, I am first reading the serial data, once the data is received, I sent out some hex packets. Below is the Arduino code:

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

 void loop()
 {
   const byte message[] = {0xAA, 0xBB, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03 };

   Serial.write(message, sizeof message);
   Serial.println("data sent");
   delay(1000);

   char buffer[6];
   if (Serial.available() > 0)
   {
  int size = Serial.readBytesUntil('\x77', buffer, 6);
  for (int i = 0 ; i < size ; i++)
  {
    Serial.println(buffer[i], HEX);
  }
   }
 }

In above code, I am first sending out the hex packets (which is received fine on python side) and then it waits for serial data. Once serial data is available to read, it reads it unitll `\x77` and prints out all data. This is received on serial console of Arduino:

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

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

You will notice that it has received the data but there are some extra `FF` being received. Why have we recived these `FF`. Also in the python code, we know we are sending data of length 6 so accordingly we have defined `char buffer[6]` in arduino but what if we have to receive data which we do not what length it will be. Please help. Thanks

body:
The effect that you see is [type promotion][1], in the C++ standard called "integral promotion", which happens implicitly. Values of type `char` are cast to `int`. Commonly, and in your case too, the `char` is by default signed.

The values `0xAA` and `0xAB` have a set most significant bit, which commonly designates a _negative_ value in [two's complement][2]. This holds true for your case. And so these negative values are cast to the same negative values, but in full width of an `int`. In your case, an `int` has 32 bits.

Hex `0xAA` as (by default signed) `char` is `-86` decimal. And `-86` decimal as (by definition signed) `int` is `0xFFFFFFAA` hex.

Printed as hex, all bits are shown. So you see all these `FF`.

The solution is to mask only the interesting lower 8 bits:

```c++
    {
      Serial.println(buffer[i] & 0xFF, HEX);
    }
```

  [1]: https://en.wikipedia.org/wiki/Type_conversion#Type_promotion
  [2]: https://en.wikipedia.org/wiki/Two's_complement


message:
arduino nano fried (TWICE!!)

Having the skill to be stupid has managed to fry not one but 2 Arduino nano boards in the same place (I think it is because this part that smoke came out from of has a lump on it that was not there before). I have heard that Arduino boards are open source, but I have not found anything explaining which part I have fried. Therefore, I don't know the function, so I cannot replace it. It would be greatly appreciated if anyone could point out the part name or a link to a shop with it in stock so I could purchase it or give me a copy of the PCB schematics to make my own Arduino.
I think the part is called the "usb diode"[![arduino nano][1]][1]
Thanks

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

body:
From the several Arduino Nano schematics I've found, the "fried" part you identify as the USB diode, might be a MBR0520 Schottky diode or a similar diode with a low forward voltage drop. These parts are polarized and should be replaced in the same orientation as the original part.

There is no guarantee that this is the only damaged component on your Nano.


message:
Speedometer for car

I want to build a speedometer for a car using Arduino UNO.
For the display, I'm using an LCD screen that will be located behind the steering wheel.
For context, I'm building the speedometer for a Tesla, which does not have a speedometer behind the steering wheel.
Because this speedometer is for a car, and for driving purposes, I need the speedometer to be very accurate.
I am planning to calculate the current speed of the car using a GPS module, but not sure **which GPS module would have the best accuracy but is not too expensive?**
I am also open to other methods that may be available to measure current speed.

body:
I built a GPS speedometer for an old Corvette using the TinyGPSPlus library with a GY-NEO6MV2 NEO-6M with an Arduino Uno.
http://www.carols62.com/speedo
Speed readings were very accurate.


message:
My Led blinks rapidly at the reset and stop blinking instantly

So ive been trying to make a program to test if the pins are working correctly but all it does is make my led blink rapidly on reset. the point of the program is that all my pins are connected to the same led, so blink each one of them once and send the number of the blinked pin to the serial.
but the led just doesnt blink and the program gets stuck at the start of pwmoutputtest.

```byte pwm[] = {3, 5, 6, 9, 10, 11};

boolean byteinarray(byte array[], byte pbit){
  for(int i=0; i<6; i++){
    if(array[i]==pbit){
      return true;
    }
  }
  return false;
}

void outputtest(){
  for(byte i=2;i<13;i++) {
    pinMode(i, OUTPUT);
  }

  for(byte i=2;i<14;i++){
    if (byteinarray(pwm, i)==false){
      Serial.println(i);
      digitalWrite(i, HIGH);
      delay(1000);
      digitalWrite(i, LOW);
      delay(1000);
    }
  }
}

void analogoutputtest(){
  for(byte i=0;i<5;i++) {
    pinMode("A"+i, OUTPUT);
  }

  for(int i=A0;i<A5;i++){
    Serial.println(i);
    digitalWrite(i, HIGH);
    delay(1000);
    digitalWrite(i, LOW);
    delay(1000);
  }
}

void pwmoutputtest (){
  for(int i=0; i<6; i++) {
    pinMode(pwm[i], OUTPUT);
  }

  for(int i=0; i<6; i++) {
    Serial.println(pwm[i]);
    for(int j=0; i<200; i++){
      analogWrite(pwm[i], j);
      delay(5);
    }
    analogWrite(pwm[i], 0);
  }
}

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

void loop() {
  outputtest();
  pwmoutputtest();
}```

body:
You have connected all the pins together. Then you are setting one pin HIGH (5V) at a time while all others are LOW (0V, aka ground).

So basically you are creating a short each time you set a pin HIGH. The current won't flow through the LED to ground (which would light up the LED), but the current flows through the pins, that are LOW, to ground. And since you didn't mention any current limiting resistors, you are straining the pin output hardware with this massively. If you do this too much, the pin output hardware will fail at some point, making the pin unusable for digital IO.

Instead of keeping the other pins LOW, you need to keep them at high impedance , which means configuring them as INPUT. That would be a function like this (not tested):

    void outputtest(){
      for(byte i=2;i<13;i++) {
        pinMode(i, INPUT);
      }

      for(byte i=2;i<14;i++){
        if (byteinarray(pwm, i)==false){
          Serial.println(i);
          pinMode(i, OUTPUT);
          digitalWrite(i, HIGH);
          delay(1000);
          digitalWrite(i, LOW);
          pinMode(i, INPUT);
          delay(1000);
        }
      }
    }


message:
How do I set the DHCP pool for an ESP-WIFI-MESH?

I'm building a mesh with ESP32 dev kits (ESP32-DevKitC V4) using the ESP-IDF VS Code extension and the ip_internal_network example project. The code for the [example][1], [common project components][2], and the [API][3] is linked. When the mesh nodes power on and build the network, they use the 10.0.0.0 network. How do I change the internal mesh network?

My operating assumptions:

 - The root node receives an external IP address from an external DHCP
   server.
 - The root node acts as an internal DHCP server to the mesh nodes.
 - The root node performs network address translation.
 - Its DHCPv4 server runs on the lwIP TCP/IP stack.
 - Internal IP addresses are leased from a pool governed by the root
   node (but it's possible that nodes request a particular address from
   this network and the server provides the next available; I'm unsure).
 - The network address is 10.0.0.0/8 (I inferred the subnet mask; it
   could be anything).

Obviously, the first thing I tried was searching for this network address in files. There was nothing in the project workspace and too many hits in the repo to be useful. I tried decimal and hex with no luck.

I also tried tracing the function that prints the IP address to the serial terminal to find the IP var, and working backwards to locate the statement that initializes this variable. I'm still reading event handler API documentation so I haven't made quick progress here either.

The programming interface is split among ESP-IDF component header files, build systems (CMake and Ninja?), KConfig options and host tools (idf.py?). C, FreeRTOS and build systems are all new to me so I would appreciate if someone with more experience could weigh in. Thank you.

  [1]: https://github.com/espressif/esp-idf/tree/master/examples/mesh/ip_internal_network
  [2]: https://github.com/espressif/esp-idf/tree/master/examples/common_components
  [3]: https://github.com/espressif/esp-idf/tree/master/components

body:
I figured it out; it's in mesh_netif.c:43. I'm not sure why I passed over this file initially but it caused a lot of unnecessary headache. The relevant struct is this:

    const esp_netif_ip_info_t g_mesh_netif_subnet_ip = {
        .ip = { .addr = ESP_IP4TOADDR( 192, 168, 0, 1) },
        .gw = { .addr = ESP_IP4TOADDR( 192, 168, 0, 1) },
        .netmask = { .addr = ESP_IP4TOADDR( 255, 255, 255, 0) },
    };

I changed the 10.0.0.0/16 network to 192.168.0.0/24. The root node assumes the address in `.ip`. I assume child nodes check the ARP table and increment until an address is available, then send the DHCPREQUEST for that address to root. I say "assume" because although root runs lwIP, I am not sure child nodes run lwIP (they may just communicate in layer 2 ESP-WIFI-MESH frames).

Make sure your DHCP server publishes an IPv4 DNS address or `ESP_ERROR_CHECK(esp_netif_set_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns))` (mesh_netif.c:70) will fail and cause the board to power cycle. A way around this is to enable `Use global DNS IP` in menuconfig. The global DNS field is in hex format, so 10.32.64.128 is written 0x0A204080.

Mesh-internal IP messages are published with MQTT so the name/address `.broker.address.uri` in mqtt_app.c:74 must be accessible from the router.


message:
does ATtiny85 handles the size of the libraries mentioned below `<MD_Parola.h>` and `<MD_MAX72xx.h>`

The ATtiny85 microcontroller has very limited resources, including program memory (flash) and RAM. It has 8KB of flash memory and only 512 bytes of RAM.

does ATtiny85 handles the size of the libraries  mentioned below
 `<MD_Parola.h>` and `<MD_MAX72xx.h>`

what microcontroller would you recommend?

https://www.arduinolibraries.info/libraries/md_max72-xx

https://reference.arduino.cc/reference/en/libraries/md_parola/

body:
It is very simple to test.

1) [Install the ATTinyCore][1] in IDE
2) Install the MD_Parola library in Library Manager. It will install the MD_MAX72xx library too
3) Go to IDE Examples menu, search for the MD_Parola library examples and select the Parola_HelloWorld example
4) select the ATTiny85 in the Tools menu
5) hit Verify

output:
```
avr/bin/ld: region `text' overflowed by 11820 bytes
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board ATtiny45/85 (Optiboot)
```
which means it will not fit.

If you select Arduino Uno in the Tools menu and Verify you get:
```
Sketch uses 20692 bytes (64%) of program storage space. Maximum is 32256 bytes.
Global variables use 288 bytes (14%) of dynamic memory, leaving 1760 bytes for local variables. Maximum is 2048 bytes.
```

  [1]: https://github.com/SpenceKonde/ATTinyCore/blob/v2.0.0-devThis-is-the-head-submit-PRs-against-this/Installation.md#boards-manager-installation


message:
connecting 4 scales to microcontroller for use as dog force plate

I want to build a system to measure the force distribution between the 4 legs of a dog. I plan to use this method:

http://www.rehabtools.org/scales.html

This setup seems to be for 1 scale. I want to use 1 scale for each leg, so that adds up to  4 scales. I assume I need 4 amplifiers, but can I connect those 4 to one microcontroller?

I currently have the Arduino Uno coming, will that work?

The connection from the 4 legs of the scale to the load amplifier I understand. But how do I go about having the 4 readings and then getting them in the software program?

Any advice would be greatly appreciated.

body:
If you follow the links in the tutorial you linked to, you will find

 * this [library for interfacing the HX711 load-cell amplifier][lib]

 * this [example sketch][skeych] for reading the scale

The library uses a bit-banging method (`pulseIn()`) for communicating
with the amplifier. This method can work with _any_ of the Arduino
digital pins. In the example sketch you have the instantiation:

```c++
HX711 scale(3, 2);
```

where the numbers (3, 2) tell the library the pins you want to use.

Given all this, you should be able to interface four identical scales
simply by using four separate pairs of pins. For example:

```c++
HX711 scale1(3, 2);
HX711 scale2(5, 4);
HX711 scale3(7, 6);
HX711 scale4(9, 8);
```

The adapt the example sketch to read all the scales.

[lib]: http://www.rehabtools.org/uploads/5/4/2/3/54237171/hx711-master.zip
[skeych]: http://www.rehabtools.org/uploads/5/4/2/3/54237171/load_cell_website_v2.ino


message:
USB Power works, VIN does not on Arduino Nano RP2040

I'm using the following simple code snippet to write to the D3-pin of my Arduino Nano RP2040 connect.

    for(int i = 0; i <= 0xff; i++) {
      analogWrite(3,i);
      delay(10);
    }

USB is connected and I have a voltmeter connected between the D3- and the 3V3-pin.
Result: The voltage increments over time, is then reset and starts incrementing again.
Everything as expected so far.
So I disconnect USB and connect the Arduino VIN-pin and the two GND-pins to a 9V power supply.
The builtin LED on the board turns on, but when I connect the voltmeter to D3 and 3V3 again, I get a constant voltage of 3.3 volts.
Why?

body:
Examining the [Arduino Nano RP2040 schematic here][1], we can see that VUSB and VIN are only separated by D2.  Further, if VUSB works as expected then it follows that VIN will likely work as well.

Assuming this, a reasonable explanation of why VUSB works as expected and VIN does not may be made by claiming the VIN power source is not capable of supplying the necessary current.

What is the necessary current is unknown.  [Examining the Arduino Nano RP2040 data sheet here][2] we see in section 2.2 that the power consumption of the Arduino Nano RP2040 board as TBC (To Be Confirmed).

Consider using a power source capable of providing several Amps of current.  The minimum current a USB port must be able to provide is 0.5 Amps.  But many USB sources can provide more. If it is necessary to know the exact current drawn when the Arduino Nano RP2040 is operating as expected, consider obtaining [commonly available USB current meters][3].

  [1]: https://content.arduino.cc/assets/ABX00053-schematics.pdf
  [2]: https://docs.arduino.cc/resources/datasheets/ABX00053-datasheet.pdf
  [3]: https://www.adafruit.com/product/4232


body:
I found it out!
I don't have an oscilloscope, but I had the idea that my transformer maybe puts out a "wavy" DC current.
I put an electrolytic capacitor parallel to the outputs of the transformer and now it works.
So it seems that Arduinos are pretty sensitive to DC currents that still have remaining AC portions.


message:
16 bit PWM on Nano Every

I need to drive a LED strip via MOSFET module. The module needs a high resolution PWM for very dim conditions. How can I set my pin to a 16 bit PWM resolution on an Arduino Nano Every?

body:
It's possible for D5 (TCA0-WO2) + D9 (TCA0-WO0) + D10 (TCA0-WO1) all three of them will be 16bit if you change TCA0 top value, but you can't use analogWrite.

    void setup() {
      // change period of TCA0 (already configured and started by arduino core)
      TCA0.SINGLE.PER = 0xFFFF; // change top value from 255 to 65535

      // set PWM value of D9 (channel 0)
      TCA0.SINGLE.CMP0 = 0; // initial value
      // enable PWM output (needed only once in setup)
      pinMode(9, OUTPUT); // setup pin as an output
      TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP0EN_bm; // enable pwm->pin

      // D5
      TCA0.SINGLE.CMP2 = 1; // initial value
      pinMode(5, OUTPUT);
      TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP2EN_bm;

      // D10
      TCA0.SINGLE.CMP1 = 65530; // initial value
      pinMode(10, OUTPUT);
      TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP1EN_bm;
    }

and in the code you'll use only `TCA0.SINGLE.CMPn = val;` where n is 0..2

(untested, but should be working)

EDIT: I forgot the period will be 3.8Hz, so you'll need to change also TCA0 prescaller or use smaller precision like 10b or so. Changing prescaller will mess up the all the TCB counters periods along with the one used for millis counter so you'd need also change that

EDIT2: for classic UNO/nano it'll look like this:

    TCCR1B = 0; // stop timer

    ICR1  = 0xFFFF; // f = 16MHz / (2*N*ICR1) = 16MHz / (2*65536) => ~122Hz
    OCR1A = 1;             // PB2 -> D9  (PWM value)
    TCCR1A = _BV(COM1A1);  // enable PWM output on PB2
    TCCR1B = _BV(WGM13) | _BV(CS10);  // mode=8 (phase and freq correct, ICR1 as top) and start timer with prescaller /1


body:
Thanks again for your help KIIV. I can confirm it works. This an example of a low light PWM for an LED on Pin 10. Maybe it helps others.

```
int brightness = 0;  // how bright the LED is
int fadeAmount = 1;  // how many points to fade the LED by

void setup() {
  TCA0.SINGLE.PER = 0x4000;
  TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV16_gc | 1 << TCA_SINGLE_ENABLE_bp
  TCA0.SINGLE.CMP1 = 65530; // initial value
  pinMode(10, OUTPUT);
  TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP1EN_bm;
}

void loop() {
  // set the brightness of LED pin:
  TCA0.SINGLE.CMP1 = brightness;

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 64) {
    fadeAmount = -fadeAmount;
  }
  // wait to see the dimming effect
  delay(50);
}
```


message:
Using interrupts as flags/latches without any ISR

I've got an Arduino Mega periodically running an (~400ms) operation that is sensitive to repeatable timing, so I don't ever want it to be interrupted.  But, I'd like to be able to use an interrupt flag from one of the built-in peripherals (PCINT, comparator, etc.) to check afterward if an external event (say, a pin going high momentarily) ever happened during the operation.

That is, it'd be nice if I could just treat one of the interrupt flags as a kind of async hardware latch that I can check (and reset) at my next earliest convenience instead of having my code interrupted.

It wouldn't be hard to add a discrete latch IC, but I was hoping I could get away with just using what was already built into the AVR without adding more hardware (and using an extra pin to reset the latch).

Looking at the documentation for each of the peripherals, it was unclear whether the flags will still be set when the interrupts themselves are disabled.  I saw a mention someplace of an "EMPTY_INTERRUPT" macro, but I'm guessing that still generates an interrupt vector with a single "return" instruction, so I'd still be losing cycles to the interrupt preamble, etc.

Can this be done without any ISR being called at all?  Or do I need to add more hardware?  I'm not sure wrapping the long-running task in noInterrupts()/interrupts() is a choice unless that also doesn't interfere with UART receiving.  Thanks!

body:
The answer to your question is: yes, you can use an interrupt flag even
if the interrupt itself is disabled. The flag is raised whenever the
peripheral detects the relevant event. You can check it at your
convenience.

As for resetting the flag, the way to do it varies from flag to flag.
Most are reset by writing a 1 bit to it (yes, it is kind of backwards,
but that's how it works). Others are reset by removing the condition
that raised them in the first place (e.g. the USART Data Register Empty interrupt). You will have to check the datasheet for the specific
interrupt flag you are interested in.

That being said, I would question your idea that you don't want your
code to be interrupted at all. As Nick Gammon writes in a comment, the
minimum time to execute an ISR is 2.625 µs. This is about 0.0007%
of the process period. If your operation is so time-sensitive that it
cannot tolerate this kind of variation, then it cannot run on a Mega _at
all_. The ceramic resonator that clocks a Mega has a typical accuracy of
about 0.1%, which is 150 time worse than the effect of a minimal
interrupt. Even if you calibrate this oscillator against an atomic
clock, in only a few hours its frequency will drift past 0.0007%.

In addition, if you want the code to work with no interrupts, you will
have to disable them explicitly with `noInterrupts()`. You will then
loose the Arduino timing function `millis()`, `delay()`, etc. And you
will not be able to receive data from the UART unless you write your own
code that polls the “receive complete” UART interrupt flag and then
grabs the data from the UART data register.


body:
> I'm not sure wrapping the long-running task in noInterrupts()/interrupts() is a choice ...

That's right. Turning off interrupts would stop the timing/delay working so you wouldn't be able to time your 200 µs (unless you use delayMicroseconds).

>  Each exposure is only a couple hundred microseconds, so even 2.625µs of periodic jitter would increase the exposure time by at least 1%.

I think you might be better off using a hardware timer to time the exposure, rather than a loop. I generated VGA signals [in a post here](https://gammon.com.au/forum/?id=11608) where I wanted the horizontal and vertical sync to have no jitter whatsoever. The timers can be set to turn on, or off, an output pin, so that could be used to control your shutter. Then it would be completely precise.

> I didn't know the UART interrupts the CPU ...

Incoming (or indeed outgoing) serial communications causes interrupts. The timers cause interrupts. In particular, if you haven't disabled it, Timer 0 generates interrupts which are counted so that millis() and micros() can function. You can disable interrupts but then timing exact intervals becomes problematic. My suggestion of using the timer hardware will give the most reliable and repeatable performance, in the same way that my VGA signal generation was completely without jitter.

Because of the timer interrupts, if you haven't disabled interrupts, some of your exposures may have the timer interrupt in the middle (making them longer) and some not, or at least, a different number of interrupts. This will make the exposure time non-precise.

---

Another approach would be to turn off interrupts for the exposure only (ie. your 200 µs, not the 400 ms you mention), and then use delayMicroseconds() to time the exposure. Then when interrupts are back on the closure of a switch (an external interrupt) could be processed by a normal ISR. This might add slight differences to the time *between* exposures, but the exposure time itself would be constant.

Even with interrupts off, an external interrupt is "remembered" and would be processed when interrupts are enabled again.

---

This is turning into [an XY problem](https://en.wikipedia.org/wiki/XY_problem) somewhat. It would have been better to mention your exact requirements (the photography part) rather than launching into questions about using interrupts as latches.

---

# Example code

To demonstrate how you can do this with timers, I have written some sample code:

<!-- language: c++ -->

    // Example of strobing a flash FRAMES_TO_TAKE times to take pictures
    // The time between each flash is in TIME_BETWEEN_SEQUENCES
    // The flash "on" time is in STROBE_ON_TIME
    //
    // For Atmega328P (Arduino Uno and similar)
    // and Atmega2560 (Arduino Mega)

    // Author: Nick Gammon
    // Date: 4 July 2023

    const byte FRAMES_TO_TAKE = 12;
    const byte CPU_CLOCK_SPEED = 16;  // MHz

    const unsigned long TIME_BETWEEN_SEQUENCES = 20000;  // µs
    const unsigned long STROBE_ON_TIME = 200;  // µs
    const byte PRESCALER = 64;

    // set correct output pin
    #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
      const byte FLASH_PIN = 10;  // OC1B (Output Compare Timer 1: B side) - Atmega328P
    #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      const byte FLASH_PIN = 12;  // OC1B (Output Compare Timer 1: B side) - Atmeg12560
    #else
      #error Processor not supported
    #endif

    volatile byte count;  // how many times it fired

    // Timer 1 Compare "B" ISR vector
    // count up to the required number of exposures, then stop
    ISR (TIMER1_COMPB_vect)
      {
      if (++count > FRAMES_TO_TAKE)
        {
        // stop timer 1
        TCCR1A = 0;
        TCCR1B = 0;
        } // end if number of frames reached

      }  // end of TIMER1_COMPB_vect

    // does one sequence of FRAMES_TO_TAKE shots and then stops
    void startSequence ()
    {
      // stop timer 1
      TCCR1A = 0;
      TCCR1B = 0;

      TCCR1A = bit (WGM10) | bit (WGM11);  // fast PWM - top at OCR1A
      TCCR1B = bit (WGM12) | bit (WGM13);  //  (mode 15)

      TCCR1A |= bit (COM1B1);   // Set OC1B during duty cycle

      OCR1A = ((TIME_BETWEEN_SEQUENCES * CPU_CLOCK_SPEED) / PRESCALER) - 1;  // total cycle time
      OCR1B = ((STROBE_ON_TIME * CPU_CLOCK_SPEED) / PRESCALER) - 1;          // duty cycle time
      count = 0;

      TCNT1 = 0;    // reset timer count

      TIFR1   = bit (OCF1B);    // clear "compare B" flag
      TIMSK1  = bit (OCIE1B);   // interrupt on compare B match
      TCCR1B |= bit (CS10) | bit (CS11);     // start timer with prescaler of 64
    } // end of startSequence

    void setup ()
      {
      // stop timer 1
      TCCR1A = 0;
      TCCR1B = 0;

      // set up pin so we can toggle it
      pinMode (FLASH_PIN, OUTPUT);
      digitalWrite (FLASH_PIN, LOW);

      // for debugging etc.
      Serial.begin (115200);
      }  // end of setup

    void loop ()
      {
      startSequence ();
      delay (20);
      Serial.print ("But does it get goat's blood out?\n");
      delay (1000);
       }  // end of loop;

---

# Code explanation

What this code does is use Timer 1 to time the intervals you require. Based on what you posted earlier, I have assumed:

* 12 exposures in a "session" (FRAMES_TO_TAKE) - you said "a dozen or so"
* Exposures are to be 20 ms apart (TIME_BETWEEN_SEQUENCES) - so a session is 240 ms
* Exposure time is to be 200 µs (STROBE_ON_TIME) - you said "a couple of hundred microseconds"
* You want to do other stuff like serial comms, checking switches etc.

The function `startSequence` initiates the timer which has a period of 20 ms and a duty cycle of 200 µs. At the completion of a duty cycle the ISR is called which counts duty cycles. At the end of the nominated number (12) the timer is turned off.

The output pin (pin 12 on the Mega, pin 10 on the Uno) is turned on during the duty cycle (ie. for 200 µs and off the rest of the time). Because this is done in hardware there is no jitter at all. In my demo I am doing serial comms to show that the intervals are exactly correct, despite the interrupts caused by the comms.

---

# Logic analyser output

The logic analyser screenshot shows that the intervals are exactly correct (to within a fraction of a percent). In any case the intervals are consistent with each other.

[![Logic analyser output][1]][1]

This second screenshot shows that there are 12 pulses in that interval.

[![Logic analyser showing count of pulses][2]][2]

I have used a prescaler of 64 to get a nice long interval that can be timed (without overflowing the 16-bit counter size). This gives a granularity of 64 clock cycles (4 µs).

---

# Timer 1 cheat sheet

---

[![Timer 1 cheat sheet][3]][3]

  [1]: https://i.stack.imgur.com/inRFb.png
  [2]: https://i.stack.imgur.com/Fh9DJ.png
  [3]: https://i.stack.imgur.com/yPLpA.png


message:
I2C cabling rules for 2+ devices

I'm attempting to wire two breakout boards with i2c devices to a Mega2560:

* a HD44280 LCD with PCF8574 i2c backpack
* a combo board with DS1307 + AT24C32

There are two obvious possibilities for cabling:

* two 10-inch ribbon cables that come together right before connecting to the Arduino's SDA and SCL pins. Technically, one could be 6 inches... but I know that with RS485, you're asking for trouble if you do a star with branches of unequal length. The cables can't really be any shorter without seriously impairing my ability to debug it while partially disassembled (the LCD is mounted to the lid, and the cables are long enough to allow me to lay the lid on the desk next to the enclosure and power everything up without putting stress on the cables).

* Same 10-inch segments of ribbon cable, but daisy-chained... Arduino to LCD, LCD to RTC. In this case, the second one really needs to be 10", because it's mounted to the only clear spot inside the case I have.

Is one likely to be better or worse than the other?

Are there any rules about WHERE the pullup resistors have to go? The DS1307 module has built-in pullup resistors. Do I have to somehow disable them & use resistors right at the point where the bus connects to the Arduino's SDA & SCL pins, or can the pullups go pretty much anywhere on the bus (including at one end of a star, or at the far end of a daisy chain)?

body: I2C is generally slow. You don't have to worry about how to route the device connection. Because propagation delay won't be a matter. The main goal should be to minimize the capacitance of the wiring, which means minimizing the total wire length. But as you mentioned one of the cable lengths is fixed, then keep the other one to a minimum. The star topology will work if you keep the wire lengths within 10 inches.