body:
Essentially, I'm trying to figure out how I can use Bluetooth Classic using the on-board U-blox w102 Wifi/Bluetooth module. I'm assuming that SerialNina and SerialHCI are somehow connected to it and maybe the way to use Bluetooth Classic on the Nano RP2040.

The ArduinoBLE library uses SerialHCI in [HCIUartTransport.cpp](https://github.com/arduino-libraries/ArduinoBLE/blob/94ffe050629a8af65b6dfcee5ee3679ad5f2fab9/src/utility/HCIUartTransport.cpp). It also messes with NINA_RESETN and SPIWIFI_SS a bit in [ BLELocalDevice.cpp](https://github.com/arduino-libraries/ArduinoBLE/blob/94ffe050629a8af65b6dfcee5ee3679ad5f2fab9/src/local/BLELocalDevice.cpp), but I'm not too worried about those.

The WiFiNINA library uses SerialNina to update the wifi firmware in [SerialNINAPassthrough.ino](https://github.com/arduino-libraries/WiFiNINA/blob/e8f0701d46c874530837bddf3b50ced7da674444/examples/Tools/SerialNINAPassthrough/SerialNINAPassthrough.ino) and [ESP32BootROM.cpp](https://github.com/arduino-libraries/WiFiNINA/blob/5d245e34269afe99216f1aec0f65501f35083dbf/examples/Tools/FirmwareUpdater/ESP32BootROM.cpp).

From this, I'm assuming that SerialHCI can be used to control BLE and SerialNina updates the Wifi's firmware. Am I right about this? If so, what part of the Nina-w102 module is SerialHCI connected to?

title: What are SerialNina and SerialHCI supposed to be used for? (Arduino Nano RP2040 Connect)

Answers: 1

body:
> what part of the Nina-w102 module is SerialHCI connected to?

from ArduinoCore-mbed/variants/NANO_RP2040_CONNECT/pins_arduino.h
```
#define SerialNina  Serial3
#define SerialHCI  Serial2
```
```
#define SERIAL2_TX   (digitalPinToPinName(25))
#define SERIAL2_RX   (digitalPinToPinName(26))
#define SERIAL2_CTS   (digitalPinToPinName(27))
#define SERIAL2_RTS   (digitalPinToPinName(28))
#define SERIAL3_TX   (digitalPinToPinName(25))
#define SERIAL3_RX   (digitalPinToPinName(26))
```

Serial2 is configured with flow control pins, but both Serial2 and Serial3 use the same RX/TX pins wired to ESP32 NINA RX/TX.

----------
> the way to use Bluetooth Classic on the Nano RP2040:

To use classic Bluetooth on Arduino boards with esp32 NINA module you have to replace the Arduino nina-fw in the esp32 with the SerialToSerialBT.ino sketch for esp32 Arduino core.

You can flash NINA over the host MCU (rp2040) with SerialNINAPassthrough.ino sketch of WifiNINA library. More details about that are in this Arduino forum [thread][1]. (Ignore the part before my first comment there).

But with this modification there is no nina firmware, so no WiFi, no cloud. The esp32 is then like a HC-05.

  [1]: https://forum.arduino.cc/t/can-the-nano-iot-33-run-full-bluetooth-not-ble/626990/22


body:
I would like to identify the target where I'm downloading my Arduino code. Following this example:

[How to get board type](https://arduino.stackexchange.com/questions/21137/arduino-how-to-get-the-board-type-in-code)

I'm able to recognize for example Arduino Mini, etc.. but Arduino Every, quite new board is not in the list and I don't understand where to find the correct "define" name to add in the list.
Can someone help me?
Thanks Andrea.

title: Arduino Nano Every: get board name in the code

Answers: 1

body:
According to [documentation][1] the macro to identify the Arduino board is generated as as `ARDUINO_{build.board}` where `{build.board}` is from boards.txt file of the 'platform'.

Nano Every has in boards.txt `nona4809.build.board=AVR_NANO_EVERY`.

So the macro to identify Nano Every is `ARDUINO_AVR_NANO_EVERY`.

  [1]: https://arduino.github.io/arduino-cli/latest/platform-specification/#boardstxt


body:
I am using a Teensy 3.6 to communicate with an external instrument via a serial connection. However, I am not able to get the instrument to respond to my commands.
The idea is to send a command from the computer via the serial monitor to the Teensy, which then can send it to the instrument (I know that the Teensy is not needed with this configuration but this is just for testing of a more complex set-up).
The instrument uses an RS232 connector so I use this [RS232 shifter][1] to connect it to the Teensy. The serial communication settings of the instrument are: 38.4k baud rate, 8 data bits, 1 stop bit, no parity and a carriage return character should mark the end of the command string.

A simple example of my code to read the input from the serial monitor and send a command to the instrument:
```
#define FILTser Serial1
char Command;

void setup() {
  Serial.begin(9600);
  FILTser.begin(38400);
  Serial.println("<Teensy is ready>");
}

void loop() {
    Command = 'X';
    recvCmd();

    // Start sampling command
    if (Command == 'S') {
       FILTser.write("pumpctl=1\r");
       FILTser.write('\n');
       Serial.println("Sampling started");
    }
}

void recvCmd() {
    if (Serial.available() > 0) {
        Command = Serial.read();
    }
}
```
If I read the output from the Teensy on the Serial1 port with Putty I get the message correctly. If I send the same command directly to the instrument with Putty or Python I get the instrument to respond as I expect. This means that the instrument is working and the serial output from the Teensy is also fine so I really don't understand what could be wrong.

I know that the instrument is not responding because I would expect a pump to turn on when it receives the command. Additionally, I tried to read the answer of the instrument on the serial port and I was receiving a `-1` but I would expect `OK` for a good command and `ERR` if the command is not recognized.
To read the instrument answer on the serial port I tried using both a single character with `Response = FILTser.read();` and also a full string using the code from [here][2].

An example of the Python code that I use to send commands to the instrument is the following:
```
import datetime
import serial
import io
import time

# =============================================================================
# Configure serial port
# =============================================================================
ser = serial.Serial()
ser.baudrate = 38400
ser.port = 'COM5'
ser.timeout = 1

#%% Define FILT functions
def FILT_send(commnd):
    ser.write(commnd.encode('ascii'))
    time.sleep(0.5)
    value_read = ser.readline().decode('ascii')
    return(value_read)

def FILT_control():
    global q
    user_input = input('Type:\n \
    - S to start sampling\n \
    - E to end sampling\n \
    - Q to quit the program\n')

    if user_input == 'S':
        FILT_send('pumpctl=1\r')
        print('Sampling started')

    if user_input == 'E':
        FILT_send('pumpctl=0\r')
        print('Sampling ended')

    if user_input == 'Q':
        print('The end')
        q = False

#%% Main
ser.open()
q = True
while q:
    FILT_control()
ser.close()
```

  [1]: https://www.sparkfun.com/products/449
  [2]: https://forum.arduino.cc/t/serial-input-basics-updated/382007

title: No response from instrument via serial communication

Answers: 1

body:
The Sparkfun RS232 shifter is not a great device. It relies on whatever it's connected to (on the 9-pin port) providing the negative rail for the EIA-232 voltage levels.

That's fine when you connect to something that *has* those voltages available, such as a computer, but many "devices" don't - they will themselves have a similar shifter inside and will rely on whatever *they* are plugged in to for providing the needed negative voltage.

Put the two together and *no-one* will provide that negative voltage.

Instead you should use a MAX232 (or MAX3232 for 3.3V operation) based converter. This has a built-in voltage doubler and voltage inverter to convert the 5V into +/-10V to give a proper EIA-232 compliant signal which the device should then be happy with.


body:
Have I understood the ATmega328P datasheet correctly regarding the TWI clock frequency?

From §21.5.2 Bit Rate Generator Unit, the TWI clock frequency is calculated as follows:

[![f_{scl}=\frac{f_{cpu}}{16+2\timesTWBR\timesPrescaler}][1]][1]

Then solving for `TWBR`:

[![TWBR=\frac{\frac{f_{cpu}}{f_{scl}}-16}{2\timesPrescaler}][2]][2]

However, §8.12.2 CLKPR – Clock Prescale Register mentions that the CPU frequency is prescaled by `CLKPR`. So should the equation be:

[![f_{scl}=\frac{f_{cpu}}{2^{CLKPR}\times(16+2\timesTWBR\timesPrescaler)}][3]][3]

And solving for `TWBR`:

[![TWBR=\frac{\frac{f_{cpu}}{2^{CLKPR}\times f_{scl}}-16}{2\timesPrescaler}][4]][4]

Is the following code a correct implementation of the equations?

```cpp
void SetFrequency(uint32_t twi_freq)
{
    if (smbus)
    {
        // SMBus clock frequency is 10 kHz to 100 kHz.
        if (twi_freq > 100000u)
        {
            twi_freq = 100000u;
        }
        else if twi_freq < 10000u)
        {
            twi_freq = 10000u;
        }
    }
    else if (twi_freq > 400000u)
    {
        // Up to 400 kHz data transfer speed.
        // §21.1 Features
        twi_freq = 400000u;
    }

    // TWI prescaler of 1.
    // Table 21-8. TWI Bit Rate Prescaler
    // TWPS1 = 0, TWPS0 = 0
    TWSR &= B11111100;

    // Achievable maximum TWI frequency with current CPU frequency, CLK prescaler and minimum TWBR with TWI prescaler of 1.
    // Rounded down to nearest integer.
    const uint32_t TWI_FREQ_MAX = F_CPU / ( ( 1 << CLKPR ) * ( 16 + 2 * 0x00 * 1 ) );

    // Achievable minimum TWI frequency with current CPU frequency, CLK prescaler and maximum TWBR with TWI prescaler of 1.
    // Rounded up to nearest integer.
    const uint32_t DIVISOR = ( ( 1 << CLKPR  ) * ( 16 + 2 * 0xFF * 1 ) );
    const uint32_t TWI_FREQ_MIN = (F_CPU + (DIVISOR - 1)) / DIVISOR;

    if (twi_freq > TWI_FREQ_MAX)
    {
        twi_freq = TWI_FREQ_MAX;
    }
    else if (twi_freq < TWI_FREQ_MIN)
    {
        twi_freq = TWI_FREQ_MIN;
    }

    // TWI bit rate.
    // §21.5.2 Bit Rate Generator Unit
    // §8.12.2 CLKPR – Clock Prescale Register
    byte bit_rate = (F_CPU / (1 << CLKPR) / twi_freq - 16) / 2

    TWBR = bit_rate;

    // Check.
    const uint32_t twi_freq = F_CPU / ( ( 1 << CLKPR ) * ( 16 + 2 * TWBR * 1 ) );
}
```

Note that `smbus` is a flag set elsewhere (global or class member) to indicate SMBus mode.

  [1]: https://i.stack.imgur.com/8cgX4.png
  [2]: https://i.stack.imgur.com/jFEId.png
  [3]: https://i.stack.imgur.com/gaX5K.png
  [4]: https://i.stack.imgur.com/9vrzJ.png

title: Two-Wire Interface (TWI) Frequency and SMBus Compatibility

Answers: 1

body:
Just to confirm, in case anyone else is wondering, the second pair of equations in my question are the correct ones which take the CPU clock prescaler (`CLKPR`) into account.

TWI clock frequency:

[![f_{scl}=\frac{f_{cpu}}{2^{CLKPR}\times(16+2\timesTWBR\timesPrescaler)}][3]][3]

And solving for `TWBR`:

[![TWBR=\frac{\frac{f_{cpu}}{2^{CLKPR}\times f_{scl}}-16}{2\timesPrescaler}][4]][4]

  [3]: https://i.stack.imgur.com/gaX5K.png
  [4]: https://i.stack.imgur.com/9vrzJ.png


body:
I am working on communicating 4 switch states across multiple Arduinos using only one pin. It must be as fast as conceivably possible.

Currently I have a *master* Arduino reading all 4 switches ([multiplexing][1]) and encoding them as [4-bit values][2]: 0001 = 0, 0010 = 1, 0011 = 2 and so on up to 1111 = 15. I am thinking of assigning the low and high pulse duration/width, (+1) to produce a PWM square wave. So 1+0=1, 1+1=2, 1+2=3 ... 1+15=16. The high width (or low width) will hold the muxed value (+1.) Each *slave* would read this muxed value and demux it to get the state of all 4 switches.

Now to my concern: Is this approach safe and reliable? Or should I triple up the values: 1=3, 2=6, 3=9 ... to build in some tolerance and prevent some time misread due to some miss-interpolations? My switches control motors and a misread could have some unpleasant consequences.

I am using the Arduino's internal crystal, nothing external.

*As a side note: I am actuality using Seeeduinos XIAO and not an Arduino. I started working on the timer based [PWM writing and reading][3] aspect, but it turns out to be quite complicated as there is not a lot of exaples to be found.*

  [1]: https://en.wikipedia.org/wiki/Multiplexer
  [2]: https://en.wikipedia.org/wiki/4-bit_computing
  [3]: https://arduino.stackexchange.com/questions/85741/seeeduino-xiao-write-and-read-pwm-duration-period-using-timers

title: Is a PWM phase duration set with OCR1A a reliable way to communicate values to other Arduinos?

Answers: 0


body:
I'm trying to use softwareserial to exchange datas with a sensor.
After some tries without any answer from the sensor, I checked the arduino TX with my scope and what I've seen is not what I've sended.

My original byte array (before the setup function):

    static byte simple_write[] = {0xfe, 0x41, 0x00, 0x80, 0x01, 0x10, 0x28, 0x7e};

What I got on my scope:

0X77 , 0x61 , 0x69 , 0x74 , ...

Every single sent byte is wrong. I don't understand why.
The only thing on the way is a bridge divider to reduce 5V TTL from the arduino to 3,3V CMOS.

If someone have an idea, thanks in advance.

EDIT2: I use IS.MDuino.21+ (ATmega2560)

EDIT: Here are the parts of my code who involve the softwareserial

        #include "SoftwareSerial.h"

        SoftwareSerial LP8_Serial(1, 0);

        static byte simple_write[] = {0xfe, 0x41, 0x00, 0x80, 0x01, 0x10, 0x28, 0x7e}; //Write 0x010 to address 0x0080

    void setup(){
    LP8_Serial.begin(9600); //Opens the virtual serial port with baud of 9600
    }

    void loop(){

    LP8_val1 = GetDatas_uart();

    }

    int GetDatas_uart() {
      if (first_loop == 0) {
        //reset_device();  // includes a 500 msec delay
        sendRequest(simple_write, 8, 4); // send to address 0x0080 a 0x10
        first_loop = 1;
      }
      else
        sendRequest(write_to_0x20, 8, 4); // send to address 0x0080 a 0x10
      delay(2000);
      unsigned long valCO2 = getValue(response);
      delay(3000);
      Serial.println("Now reading 32 bytes");   //sendRequest(read_16_bytes,7,21);
      sendRequest(read_32_bytes, 7, 37);
      Serial.print("CO2 from 0x9a-0x9b = ");
      Serial.print(response[29], HEX);
      Serial.print(response[30], HEX);
      Serial.print(" = ");
      int decimal = 256 * response[29] + response[30];
      Serial.print(decimal);
      Serial.println("d");

      return decimal;
    }

    void sendRequest(byte packet[], int m, int n)
    {
      while (!LP8_Serial.available()) //keep sending request until we start to get a response
      {
        Serial.println("waiting for Software.serial port availability");
        LP8_Serial.write(packet, m);
        //LP8_Serial.write(simple_write, m);
        delay(1000); // Necessary to get consistent loading of response[i]
      }
      int timeout = 0; //set a timeout counter
      while (LP8_Serial.available() < n ) //Wait to get a n byte response
      {
        timeout++;
        if (timeout > 10) //if it takes too long there was probably an error
        {
          while (LP8_Serial.available()) //flush whatever we have
            LP8_Serial.read();
          break; //exit and try again
        }
        delay(50);
      }
      for (int i = 0; i < n; i++)
      {
        response[i] = LP8_Serial.read();
        //    Serial.print("response[i] = ");
        Serial.print("response[");
        Serial.print(i);
        Serial.print("] = ");
        Serial.println(response[i], HEX);
      }
      Serial.print("\n\n");
      Serial.flush();
    }

title: Softwareserial send wrong values

Answers: 1

body:
Sooo, I feel a little ashamed...

After re-reading the documentation of the Arduino from Industrial Shields I use (model 21+), I discovered that using Serial0 on this board is unadvised because these pins are shared with USB.

I connected my serial wires to the Serial1 connection and now, my scope show me exactly what I wanted to see on my TX line.

Sorry for that. Like often, the problem whas between the screen and the chair.

Thanks,


body:
Let me get this straight, I'm trying to see my ESP32 is connected to the **internet** or not, not Wi-Fi, as at times the board is able to connect to Wi-Fi, but not able to contact any servers, due to router issues.

I want to check, if the board is connected the internet or not, how do I do this?

What I have so far:-
```
char ssid[] = "Youreally";
char pass[] = "WannaKnow";

void setup(){
WiFi.begin(ssid, pass);
Serial.begin(115200);
}

void loop(){
  if (WiFi.status() != WL_CONNECTED) {
  Serial.println("Connected");
  }
}
```

title: How do I check if my board is connected to the internet?

Answers: 1

body:
As you would be having some sort of connectivity except WiFi you could check that on regular basis in your loop, for instance when using MQTT I would check:

    if (!mqttClient->connected())

and then based on the result I would test:

    if (WiFi.status() != WL_CONNECTED)

so I can handle the relevant layer.


body:
I have a SAMD21G18A-MUT custom board, which has 6 'grove' connectors, of which two are I2C In and out (sharing the same MCU Pins) and also has 2 'special' 8 pin connectors attaching to Particulate Matter sensors that connect to :

 1. PA 14, (9, 8)[Sercom 2 alt]; PB8,PA6 [PWM], PB23

 2. PA 15,(11,10)[Sercom 0]; PB9, PA7 [PWM], PB22

 which implement serial interfaces with additional control wires.

The Grove ports are :

 - ADC 0 (A0 & A1); Pins 9,10 [accessible only to SERCOM 0]
 - ADC 1 (A2 & A3); Pins 47,3 [not accessible by SERCOM]
 - GPIO D0/D1 [SERCOM4_ALT]; (used)  Pins 21,22
 - UART Tx/RX [Sercom 1]. Pins 27,28
- I2C Pins (SDA, SCL), (Pins 31,32)  [SERCOM 1 PAD 0 & 1]  (only one I2C port  Used)
- Debug Connector, ({ins 45,46) [SERCOM 1 PAD 2 & 3]
- USB Pins (D+, D-, (Pins (33,34) [SERCOM 3]  (Used when programming)

SERCOM 5 appears to be unused, but not accessible by either ADC Port.
Do not ask me how the overloading of SERCOM 1 works...IDK

So, all but 1 Sercom ports are used up and yet I need to connect up 2 additional serial devices; a Wind sensor and a Rain Gauge.
Obviously I can connect one of them to UART Tx/Rx Sercom1; but the other one can physically connect only to one of the ADC Ports. But the only available Sercom for those pins is already used.
 So, I think I need to implement SoftwareSerial on (say) A0 and A1 for the second device that I need to connect.

Any thoughts on if or how this can be done ?

My only current alternative is to add a whole new MCU Board, but that brings on space and mounting considerations.

title: Is SoftwareSerial possible for Samd21 boards?

Answers: 0


body:
I'm trying to follow lesson 6 of the Adafruit Arduino lessons on digital inputs found [here](https://learn.adafruit.com/adafruit-arduino-lesson-6-digital-inputs/overview).

I have the same code and the board setup the exact same and the code it **is working** exactly as it should. I just can't figure out ***WHY***.

Board:

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

Code:

        /*
    Adafruit Arduino - Lesson 6. Inputs
    */

    int ledPin = 5;
    int buttonApin = 9;
    int buttonBpin = 8;

    byte leds = 0;

    void setup()
    {
      pinMode(ledPin, OUTPUT);
      pinMode(buttonApin, INPUT_PULLUP);
      pinMode(buttonBpin, INPUT_PULLUP);
    }

    void loop()
    {
      if (digitalRead(buttonApin) == LOW)
      {
        digitalWrite(ledPin, HIGH);
      }
      if (digitalRead(buttonBpin) == LOW)
      {
        digitalWrite(ledPin, LOW);
      }
    }

Why does the light turn on when one of he buttons is pressed once and turn off when the other button is pressed once. I don't understand the mechanism of how the press is being remembered.

There doesn't seem to be anything in the code that can explain why the button stays on even when no longer pressed, so it should be some component? But what?

Can anyone help explain why this is working?

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

title: How or why is the Arduino keeping a LED on when the input putton is no longer pressed?

Answers: 4

body: If you read the lesson below the first picture and above parts it states: "Pressing the button nearer the top of the breadboard will turn the LED on, pressing the other button will turn the LED off." Try pressing and expect the LED to turn off.

body: The press is not being remembered. Instead, the output pin "remembers" its state: `digitalWrite(HIGH)` sets the pin to high and the pin will remain high until you call `digitalWrite(LOW)`.

body:
It might be interesting to look at the reasons why the pin remembers its state (as described in other answers).

Every digital pin has dedicated digital output hardware, which can drive the pin to HIGH (Vcc, supply voltage) or LOW (ground). This output hardware is internally tied to a SFR (Special Function Register). A register is a piece of specific memory hardware in the microcontroller of the Arduino. The digital output hardware is electrically hardwired to some of those special function registers. Thus its state depends on what is saved in those registers. Since the registers hold their state during the running time of the Arduino (they are memory after all), the digital output hardware will also not change, until you change the corresponding registers (through executing `digitalWrite()`).

You can even manipulate the SFRs directly. This can help with programming time sensitive code or setting/reading multiple pins at once. All the digital pins are sorted into so called ports, which can hold up to 8 pins. For each port there are the following SFRs (the `x` stands for the character of the corresponding port, like `PORTA`, `PORTB`, ...), where the bits in these (1 byte big) registers correspond to one pin each:

- `DDRx`: This register is the Data Direction Register. It controls if the corresponding pins are set as digital output or input.
- `PORTx`: This register sets the output state. `digitalWrite(pin, HIGH)` will write a 1 to the corresponding bit of this register, which then sets the pin to HIGH. If the corresponding pin is set as input, setting a 1 in the corresponding bit of the PORT register will enable the interal pullup resistor of that pin.
- `PINx`: This register holds the current state of the corresponding pins, so you can use it to read a digital pin.

You can also read [this reference article][1]. Also the datasheet of the used microcontroller also contains all information about what SFRs exist and how they are used to perform specific actions.

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

body:
I would like to add two more cents. It is a wonderful explanation already from @chrisl
Here is the simulation screenshot for your [example][1]:
[![enter image description here][2]][2]

if you consider mechanical switches, they really cut the connection so that the light will be OFF. When you want the light to be on, you will move the switch to the ON position(in this example, hold the button)
[![enter image description here][3]][3]

In the case of Microcontrollers, and in the given example, it is more like two people communicating.

 1. The 1st person is looking at the switches. The 2nd person is
    controlling the LED
 2. 1st person is instructed to notify the second person about anybody pressing the switches
 3. whenever the ON switch is pressed, the 1st person will immediately tell the second person to turn on the LED
 4. Whenever the OFF switch is pressed, the 1st person will tell the 2nd person to turn off the LED

The behaviour of the program much depends on the requirement.
_____________
if you would love to see the LED turn OFF when you want to, you can try this [example][4]
[![enter image description here][5]][5]

Code:

    /*
      Adafruit Arduino - Lesson 6. Inputs
    */

    int ledPin = 5;
    int buttonApin = 9;
    //int buttonBpin = 8;

    byte leds = 0;

    void setup()
    {
      Serial.begin(9600);
      pinMode(ledPin, OUTPUT);
      pinMode(buttonApin, INPUT_PULLUP);
      pinMode(buttonBpin, INPUT_PULLUP);
    }

    void loop()
    {
      digitalWrite(ledPin, !digitalRead(buttonApin));
    }

  [1]: https://wokwi.com/arduino/projects/307720303778202178
  [2]: https://i.stack.imgur.com/QvZ36.gif
  [3]: https://i.stack.imgur.com/U9Zkw.png
  [4]: https://wokwi.com/arduino/projects/307720931096134209
  [5]: https://i.stack.imgur.com/HHXDT.gif


body:
I'm trying to compile my code but i keep exceeding my global variable memory by 12%.
Is there anything i can do in my code to further reduce RAM usage?
Or do i have to do modifications to the libraries I'm using?
Here is my main program:

        #include <MIDI.h>
    #include <FastLED.h>
    #include <SoftwareSerial.h>

    #define LED_PIN 3
    #define NUM_LEDS 60
    #define LEDMAP 0xAB5AB5AB5AB5AB5
    #define OFFSET 36
    #define RANGECHECK if (pitch > 35 && pitch < 96)

    SoftwareSerial softSerial(2, 4);
    CRGB leds[NUM_LEDS];

    MIDI_CREATE_INSTANCE(SoftwareSerial, softSerial, midiB);

    void setup() {
      FastLED.addLeds<WS2811, LED_PIN, GRB>(leds, NUM_LEDS);
      FastLED.clear(true);
      midiB.begin(MIDI_CHANNEL_OMNI);
      midiB.setHandleNoteOn(HandleOn);
      midiB.setHandleNoteOff(HandleOff);
    }

    void loop() {
      midiB.read();
    }

    void HandleOn(byte channel, byte pitch, byte velocity)
    {
      RANGECHECK
      {
        leds[pitch - OFFSET] = bitRead(LEDMAP, (pitch - OFFSET)) ? CRGB::NavajoWhite : CRGB::Salmon;
        FastLED.show();
      }
    }

    void HandleOff(byte channel, byte pitch, byte velocity)
    {
      RANGECHECK
      {
        leds[pitch - OFFSET] = CRGB::Black;
        FastLED.show();
      }
    }
I've reached my limit in optimizing my RAM usage here. Any suggestions for optimizing my code would be appreciated.

title: How can i reduce my global variable use? Attiny85

Answers: 2

body:
FastLED needs to keep the colors of all the pixel in RAM, so that is using a lot of RAM.

To get around this, you could use a strategy that generates the pixel data on the fly as you send it out to the strings. Here is an example of a project that does that...

https://wp.josh.com/2021/04/21/build-a-live-scrolling-tickertape/

Also, SoftSerial keeps a buffer ([looks like 64 bytes][1]?) which also uses some RAM. You could use a different approach to serial communications that does not allocate such a large buffer. It would take work, but you could even process the midi bytes as they were received and not need any byte buffer.

  [1]: https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/SoftwareSerial/src/SoftwareSerial.h#L72

body:
Since i don't use sysex messages, i got my RAM usage down to 84% by setting the `SysExMaxSize`

in `midi_settings.h`
to 0.


body:
Well, I am trying make a library for HMI display. display and Arduino comminicate with Serial. So I will so many times Serial port. Generally I will use **Serial.write** commend. if I examine other libraries, there are lots way to declare serial. Why and which is the best I want to learn.

there I have seen declaring Serial methods.

**Method 1**

in library .h file

    nothing

in library .cpp file

    #include <SoftwareSerial.h>

    SoftwareSerial SIM(RX_PIN,TX_PIN);

    void KapadokyaGSM::basla(){
     SIM.begin(9600);
      _tampon.reserve(255);
    }

**Method 2**

in library .h file

    public:
    EasyNex(HardwareSerial& serial);
    ...
    private:
    HardwareSerial* _serial;
    ...

in library .cpp file

    EasyNex::EasyNex(HardwareSerial& serial){  // Constructor's parameter is the Serial we want to use
    _serial = &serial;
    }

    void EasyNex::begin(unsigned long baud){
    _serial->begin(baud);  // We pass the initialization data to the objects (baud rate) default: 9600
    delay(100);            // Wait for the Serial to initialize

Also I have seen declaring with Stream but now i didnt find example codes. So finally **Can anyone tell me what is the best for declearing Serial in library.** it can be for only hardware serial or both

title: which is the best way to declare Serial while creating Arduino library?

Answers: 2

body:
There is no best way, the first is using a global variable, being static. The second is dynamically (or at least to pass a serial instance).

It depends on your use
- If you want your code always to work with the same declared serial (hardware or serial) instance, you can use the first method, as it is the easiest.
- If you want your serial hardware port to be flexible (your code to work e.g. with a selectable hardware serial port on an Arduino Mega), you need the second.
- If you want to your serial port to be either software or hardware, you can use the second method, but you need another type (not the mentioned `HardwareSerial` class. I don't know by head the parent class of `SoftwareSerial` and `HardwareSerial` (The `Stream` class you mentioned could be a common parent class).

body:
As regards the use of `Stream`:

I usually use `Stream` instead of `HardwareSerial` because:

* It allows the use of other serial devices, like `SoftwareSerial` or `USBSerial` that aren't "Hardware" UARTs.
* It even allows the use of non-serial systems, like sending data over networks or wireless devices

However it means:

* The user has to manually initialize their serial object / device as `Stream` has no facility for setting things like baud rates.


body:
I have an esp32 development board that I am trying to use to get Bitcoin price data using the Coinbase api.

On the Coinbase developers website, they give this example Curl command to get Bitcoin price data:

    curl https://api.coinbase.com/v2/prices/spot?currency=USD
I put this into a command prompt on my computer and it works as expected. So I used this as a template for my HTTP get statement in my Arduino sketch.

    if (!client.connect("api.coinbase.com",80)) {
      Serial.println("Connection failed.");
    }
    delay(100);
    client.print("GET /v2/prices/spot?currency=USD HTTP/1.1\r\nHost: api.coinbase.com\r\n\n");

However, when sent from my esp32, I get a "301 Moved Permanently" error. But the new Location specified in the response is exactly where I was accessing in the first place!

    HTTP/1.1 301 Moved Permanently
    Date: Sun, 22 Aug 2021 22:15:50 GMT
    Transfer-Encoding: chunked
    Connection: keep-alive
    Cache-Control: max-age=3600
    Expires: Sun, 22 Aug 2021 23:15:50 GMT
    Location: https://api.coinbase.com/v2/prices/spot?currency=USD
    Set-Cookie: __cf_bm=ea2a2031c3fa42b910632c627d2ed4c48824323d-1629670550-1800-ARKBVsdI9BWVOOTWmKXp+cMv0hcxMU4YAOR1JyHtH2Q49TEBkGuGNXLxSMIanzC7W8Ga9uXBCtdo+Th7Fgir8Jc=; path=/; expires=Sun, 22-Aug-21 22:45:50 GMT; domain=.coinbase.com; HttpOnly
    X-Content-Type-Options: nosniff
    Server: cloudflare
    CF-RAY: 682f764a88f3a3eb-PIT

Why does this HTTP request work with Curl, but not when sent from the esp32?

title: WiFi.h library, Issues with client.print()

Answers: 1

body:
It's not an error, it's an HTTP redirect.

The HTTP request worked as expected on the ESP32. Curl automatically handles the redirect. Your homegrown HTTP implementation does not.

The Coinbase API requires you to use HTTPS and does not allow HTTP. This protects private information, like API keys and information the API may return. It also verifies that you're talking to the real Coinbase API server and not an impersonator.

You'll need to use port 443 and the [`WiFiClientSecure`](https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFiClientSecure) library instead of `WiFiClient` library. Or even better, you could use an HTTP client that already implements the HTTP protocol, like [`HTTPClient`](https://github.com/espressif/arduino-esp32/tree/master/libraries/HTTPClient).


body:
Below is the small RGB LED circuit I'm trying to build. My question is why are the 3 transistors necessary, and can I not link the LEDs directly?

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

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

title: Why are transistors necessary before LEDs?

Answers: 3

body:
The port pins of your Nano can deliver current in a quite limited range, and six LEDs need a lot more to shine brightly. The transistors are amplifying the available current.

However, 4k7 resistors in series with each LED will not allow enough current to let them shine well. Reduce the resistors by a factor of at least 10. Read the LEDs' data sheet and apply Ohm's law.

body:
Each LED consumes up to 20mA and You are using three LEDs at each I/O port in Arduino Nano. In other word, each part consumes 120mA.

The important thing is Arduino Nano I/O provides 20mA at maximum. So if you want to control 120mA by I/O ports, you must use transistor to support huge current.

Transistor can afford current up to 500mA.

body: The transistors are connected as an emitter follower, not as a switch. The transistors are acting as current amplifiers. The emitter voltage will rise to approximately the voltage on its base - about 0.7V. That places the voltage at about (5 - 0.7 = 4.3V) at the emitter. Since the collectors of transistors are powered by Vin I would guess you have at least 6 volts available assuming a 5V Nano so the extra voltage drop across the transistors will be dissipated as heat. The base resistors are not needed but should not affect performance much. The available current at the emitter would be the Hfe of the transistor times the base current. Each LED will consume about 2 milliamps making the load on each of the transistor around 12 milliamps. It should work fine. You can divide the 12 milliamps of the LEDs by the Hfe of the transistor to get the base load.


body:
I am trying to retrieve JSON mqtt message I received in ESP32.

```
void mqttMsgCallback(char* topic, byte* payload, unsigned int length) {
    payload[length] = '\0';
    String _message = String((char*)payload);
    String _topic = String(topic);
    if (_topic.equals("Sys.GetInfo/"+getMacAddr()) == 1)
    {
      Serial.println("Message arrived for sys.GetInfo");
      StaticJsonDocument <256> msg1;
      Serial.println(_message);
      deserializeJson(msg1,_message);
      String callbackTopic = msg1["callbackTopic"];
      Serial.println(callbackTopic);
    }
}
```
The issue is when I publish ```mosquitto_pub -t "Sys.GetInfo/2462ABFC2CD0" -m "{"callbackTopic" : "1234"}"``` it works well like callbackTopic as 1234.

but when I publish ```mosquitto_pub -t "Sys.GetInfo/2462ABFC2CD0" -m "{"callbackTopic" : "xyz"}" ``` it prints callbackTopic value as null.
Please point me if I an missing something.

Arduino version 1.8.15
ArduinoJson : 6.18.2
Borad : ESP32

Thanks

title: ArduinoJson library parsing error

Answers: 2

body:
Your shell is stripping the " from inside the string. If you run the command:

    $ echo "{"callbackTopic" : "xyz"}"

you get:

    {callbackTopic : xyz}

so you see all the quotes are stripped. `xyz` isn't something that ArduinoJSON can parse. But `1234` is, so with the quotes stripped it's still considered valid.

You need to ensure the quotes aren't removed. There's two ways of doing this: escaping them, or encapsulating the string in single quotes which gives a more "literal" interpretation of the contents than double quotes:

Escaping:

    "{\"callbackTopic\" : \"xyz\"}"

Single quotes:

    '{"callbackTopic" : "xyz"}'

Either of those when used as a parameter to a command work - like:

    $ echo '{"callbackTopic" : "xyz"}'
    {"callbackTopic" : "xyz"}

body:
To parse an ArduinoJSON one simply needs to

      String JSONpayload = "some JSON here";
      StaticJsonDocument <512> geoLocationInfoJson;
      DeserializationError error = deserializeJson(geoLocationInfoJson, JSONpayload);
      if (error) {
        this->mserial->printStrln("Error deserializing JSON");
      }

To use the values within the `StaticJsonDocument` one first needs to

    if ( geoLocationInfoJson.isNull() == true ){
      String dataStr="NULL geoLocation data.\n";
      Serial.print( dataStr);
      return true;
    }

next, is required to verify if a key exists. If TRUE, then is mandatory first to get the desired value into a corresponding data type, like below, and only afterward work on it, for instance, send it as a BLE message string:

    if(this->interface->geoLocationInfoJson.containsKey("lat")){
      float lat = this->interface->geoLocationInfoJson["lat"];
      dataStr += "Latitude: "+ String(lat,4) + "\n";
    }
    if(this->interface->geoLocationInfoJson.containsKey("lon")){
      float lon = this->interface->geoLocationInfoJson["lon"];
      dataStr += "Longitude: "+ String(lon,4) + "\n";
    }

    if(this->interface->geoLocationInfoJson.containsKey("regionName"))
      dataStr += String(this->interface->geoLocationInfoJson["regionName"].as<char*>()) + ", ";

 The full code above is available on this GitHub repository:

https://github.com/aeonSolutions/aeonlabs-ESP32-C-Base-Firmware-Libraries


body:
OK, I'm working on a project where I want to have multiple toggle switches create a "code" to determine further actions. This is essentially 5-bit communication process that will create output with a 32-bit range of outcomes from 00000 to 11111.

I'm testing the method with three switches, so if the first and third switch are HIGH/on it will read 101. Second and third, 011 etc. I'm not versed enough to know if there is a better method here, but is there a better way to do this?

        // Define the pins being used
    int pin_switch = 10;
    int pin_switch2 = 11;
    int pin_switch3 = 12;

    // create int for 3-digit code
    int code = 000;

    void setup()
    {
        Serial.begin(9600);
        pinMode(pin_switch, INPUT);
        pinMode(pin_switch2, INPUT);
        pinMode(pin_switch3, INPUT);
    }

    void loop()
    {

    if pin_switch == HIGH;
     {code += 100;}

    if pin_switch2 == HIGH;
     {code += 10;}

    if pin_switch3 == HIGH;
     {code += 1;}

    Serial.print(code);

    // operate based on code output
    if code == 101;
     {do 101 stuff}

    if code == 001
     {do 001 stuff}

    // reset code for next loop so numbers don't keep rising
    code = 000;
    }

title: 5-bit communication method?

Answers: 2

body:
It would be more convenient and less typing if you put all your switch pins in an array. That way you can loop over it to configure the ports and read them rather than copy/pasting the "same" code over and over.

The calculation of the resulting code is a classic "shift and add" loop. I put both the decimal version you seem to want and the more "usual" binary version in the snippet below.

The idea behind that sort of loop is:
1. start with an empty (zero) code
2. multiply the code by 10 (or left-shift once for binary)
3. read a switch, add 1 to the code if it is HIGH
4. go back to step 2 if there are more switches.

The value of the switches already read get "pushed" one slot to the left before reading the next switch, resulting in the code you want.

The order in which you list the ports in the array is important: the first port in the array will change the leftmost (most significant) digit/bit in the code.

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

    const uint8_t switch_pin[] = { 10, 11, 12 };
    const uint8_t num_switches = sizeof(switch_pin)/sizeof(switch_pin[0]);

    void setup() {
      // Set all switch pins to input mode
      for (uint8_t i = 0; i < num_switches; ++i) {
        pinMode(switch_pin[i], INPUT);
      }
      Serial.begin(9600);
    }

    void loop() {
      int code = 0;
      // Read each switch and compute the code
      for (uint8_t i = 0; i < num_switches; ++i) {
        // If the code is supposed to be in decimal
        code = code * 10;
        code += digitalRead(switch_pin[i]);
        /* For a binary version, code only needs to be 8 bits long:
        code <<= 1;
        code |= digitalRead(switch_pin[i]);
        */
      }

      // Do stuff with the code
      Serial.println(code);
      delay(200);
    }

body:
Unfortunately your code is all over the place. You have to use C/C++ syntax, which you don't. Also you don't actually read any input.

- if statements look like this:

        if(condition){
            my_code();
        }

- `if(pin_switch == HIGH)` (corrected syntax) will always be false, since `pin_switch` is of value `10`. Its just the pin number. To actually read the pin, you need to use `digitalRead()` like this:

        if(digitalRead(pin_switch) == HIGH)

    or even simpler

        if(digitalRead(pin_switch))

- It seems that you want to manipulate the bits with `code += 100;`, but the compiler takes numbers as decimal. So you are adding 100 to `code`. Please look into the bitwise operators. Also: You can actually write numbers in binary or hex by using `0b101` or `0xF3` respectively (the values here are just examples). This also means, that `int code = 000;` is the same as `int code = 0;`.

---

To build the 3 digit code from input you could put them together via bitwise operators:

    code = (digitalRead(pin_switch3) << 2) | (digitalRead(pin_switch2) << 1) | digitalRead(pin_switch);

Depending on your used Arduino and the used pins you can get this even easier. The pins are sorted into ports. Each port has a Special Function register, which holds the current state of the pins. You can mask away any unwanted pins and shift the number to be right justified. For example: On the Uno and Nano pins 2 to 7 belong to PORTD. So, if you use pins 2 to 4 for your 3 switches, you could get the code like:

    code = (PIND & 0b00011100) >> 2;

This is a bit more difficult to understand, but it will help you later on, when pursuing Arduino more.

---

For deciding what action to do based on the code, it is normally easier to use a switch case statement:

    switch(code){
        case 0b101:
            do_something();
            break;
        case 0b011:
            do_something_else();
            break;
    }


body:
I am trying to communicate between two Seeeduino XIAO (chip: ATSAMD21G18A-MU) by way of **TCC capture** using register timers.

Square wave pulse duration varies from 200ns to 4us.

I found these two code samples, and I am now trying to change them up to make them work the way I intend to read and write these short pulses.

---

**1) XIAO writing square wave (generate output)**

This code works, but it is changing the pulse width and not the pulse period. Output is on pin `D2` and `D3`. How can I make it change the polse period instead of the polse width?  [Source][6]

````
// Output 300kHz dual slope PWM on TCC0 with complementary outputs and dead time insertion
void setup()
{
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |        // Enable GCLK0
                      GCLK_CLKCTRL_GEN_GCLK0 |    // Select GCLK0 at 48MHz
                      GCLK_CLKCTRL_ID_TCC0_TCC1;  // Route GCLK0 to TCC0 and TCC1

  PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;   // Enable the port multiplexer for port pins PA10 and PA11
  PORT->Group[PORTA].PINCFG[11].bit.PMUXEN = 1;

  // Select the port pin multiplexer switch to option F for TCC0/WO[2] and TCC0/WO[3] on
  // port pins PA10 and PA11 respectively
  PORT->Group[PORTA].PMUX[10 >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;

  TCC0->WAVE.reg = TCC_WAVE_POL2 |                // Reverse the signal polarity on channel 2
                   TCC_WAVE_WAVEGEN_DSBOTTOM;     // Dual slope PWM on TCC0
  while (TCC0->SYNCBUSY.bit.WAVE);                // Wait for synchronization

  //  48,000,000 / 300,000 = 160
  TCC0->PER.reg = 79;                             // Set the frequency of the PWM on TCC0 to 300kHz
  while(TCC0->SYNCBUSY.bit.PER);                  // Wait for synchronization

  TCC0->CC[2].reg = 40;                           // Output a 50% duty-cycle
  while(TCC0->SYNCBUSY.bit.CC2);                  // Wait for synchronization

  TCC0->CC[3].reg = 35;                           // Output a 43% duty-cycle
  while(TCC0->SYNCBUSY.bit.CC3);                  // Wait for synchronization

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

void loop(){
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_LUPD;         // Set the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  TCC0->CCB[2].reg = 40;                          // Output a 50% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB2);                 // Wait for synchronization
  TCC0->CCB[3].reg = 35;                          // Output a 43% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB3);                 // Wait for synchronization
  TCC0->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD;         // Clear the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  delay(1000);                                    // Wait for 1 second

  TCC0->CTRLBSET.reg = TCC_CTRLBSET_LUPD;         // Set the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  TCC0->CCB[2].reg = 20;                          // Output a 25% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB2);                 // Wait for synchronization
  TCC0->CCB[3].reg = 15;                          // Output a 18% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB3);                 // Wait for synchronization
  TCC0->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD;         // Clear the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  delay(1000);
}
````
---

**2) XIAO reading square wave (input capture); Period and Pulse-Width (PPW) Capture**

This code works, but it reads the frequency over a period of 1 second, and not just the duration of a polse period. Input is on `D6`. How can I make these changes to the code for it to work?  [Source][7]

````
// Count the number of pulses on pin D6 (PB08) over a 1 second period
void setup()
{
  SerialUSB.begin(115200);                  // Initialise the native serial port
  while(!SerialUSB);                        // Wait for the console to open

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

  ////////////////////////////////////////////////////////////////////////////////////////
  // Generic Clock Initialisation

  GCLK->GENDIV.reg =  GCLK_GENDIV_DIV(1) |          // Select clock divisor to 1
                      GCLK_GENDIV_ID(4);            // Select GLCK4

  GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC |            // Set the duty cycle to 50/50 HIGH/LOW
                      GCLK_GENCTRL_GENEN |          // Enable GCLK
                      GCLK_GENCTRL_SRC_XOSC32K |    // Select GCLK source as
             //    external 32.768kHz crystal (XOSC32K)
                      GCLK_GENCTRL_ID(4);           // Select GCLK4
  while (GCLK->STATUS.bit.SYNCBUSY);                // Wait for synchronization

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |          // Enable generic clock
                      GCLK_CLKCTRL_GEN_GCLK0 |      // GCLK0 at 48MHz
                      GCLK_CLKCTRL_ID_TCC0_TCC1;    // As a clock source for TCC0 and TCC1

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |          // Enable generic clock
                      GCLK_CLKCTRL_GEN_GCLK4 |      // GCLK4 at 32.768kHz
                      GCLK_CLKCTRL_ID_TCC2_TC3;     // As a clock source for TCC2 and TC3

  //////////////////////////////////////////////////////////////////////////////////////////////
  // TCC2 Initialisation - reference timer: measures a 1s period

  TCC2->PER.reg = 32767;                             // Set the period (PER) register for a
                                                     // PWM period of 1s
  while (TCC2->SYNCBUSY.bit.PER);                    // Wait for synchronization

  TCC2->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;            // Set timer to Normal PWM mode (NPWM)
  while (TCC2->SYNCBUSY.bit.WAVE);                   // Wait for synchronization

  TCC2->CTRLBSET.reg = TCC_CTRLBSET_ONESHOT;         // Enable oneshot operation
  while(TCC2->SYNCBUSY.bit.CTRLB);                   // Wait for synchronization

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

  TCC2->INTENSET.reg = TCC_INTENSET_OVF;   // Enable overflow (OVF) interrupts on TCC2

  TCC2->CTRLA.bit.ENABLE = 1;              // Enable TCC2
  while (TCC2->SYNCBUSY.bit.ENABLE);       // Wait for synchronization

  ////////////////////////////////////////////////////////////////////////////////////////
  // TCC0 Initialisation - measurement counter: counts the number of incoming of pulses

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

  EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO8;       // Enable event output on external interrupt 8
  EIC->CONFIG[1].reg |= EIC_CONFIG_SENSE0_HIGH;  // Set interrupt to detect a HIGH level
  EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT8;      // Clear the interrupt flag on channel 8
  EIC->CTRL.bit.ENABLE = 1;                      // Enable EIC peripheral
  while (EIC->STATUS.bit.SYNCBUSY);              // Wait for synchronization

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

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

  TCC0->EVCTRL.reg = TCC_EVCTRL_TCEI0 |       // Enable TCC0 event 0 inputs
                     TCC_EVCTRL_EVACT0_INC;   // Increment the TCC0 counter on receiving an event 0

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

void loop()
{
  startConversion();     // Start a conversion over the 1 second integration window
  delay(3500);           // Wait for 1 second
}

void startConversion()
{
  TCC2->CTRLBSET.reg = TCC_CTRLBSET_CMD_RETRIGGER;   // Retrigger the timer TCC2 to
                                                     //   start the integration window
  while (TCC2->SYNCBUSY.bit.CTRLB);                  // Wait for synchronization
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_RETRIGGER;   // Retrigger the timer TCC0 to
                                                     //   start the count
  while (TCC0->SYNCBUSY.bit.CTRLB);                  // Wait for synchronization
}

void TCC2_Handler()
{
  TCC2->INTFLAG.bit.OVF = 1;                         // Clear the TCC2 overflow interrupt flag
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_READSYNC;    // Trigger a read synchronization
                                                     //   on the COUNT register
  while (TCC0->SYNCBUSY.bit.CTRLB);                  // Wait for the CTRLB register write synchronization
  while (TCC0->SYNCBUSY.bit.COUNT);                  // Wait for the COUNT register read sychronization
  SerialUSB.println(TCC0->COUNT.reg);                // Print the result
}
````

Some helpful page explaining these timers

   https://www.picotech.com/support/topic24051.html

   https://shawnhymel.com/1710/arduino-zero-samd21-raw-pwm-using-cmsis/

  [1]: https://blog.thea.codes/understanding-the-sam-d21-clocks/
  [2]: http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf
  [3]: https://i.stack.imgur.com/CQVRV.gif
  [4]: https://i.stack.imgur.com/Q1Koz.gif
  [5]: https://www.youtube.com/watch?v=2FoZ7kHOdT0
  [6]: https://forum.arduino.cc/t/martinl-please-help-samd21-pwm-dti-questions-help/675541/3
  [7]: https://forum.arduino.cc/t/frequency-measurement-on-seeeduino-xiao-at-200khz/688929

title: Seeeduino XIAO write and read PWM duration (period) using timers

Answers: 1

body:
**1) Writing short square wave pulses to pin `D3` using Seeeduino XIAO**

[Timer setup derived from this github post][1] and [includes update suggestion][4] by MartinL.

````
void setup()  //TCC1 Timer-Setup AT-SAMD21-G18 ARM Cortex M0
{
  setupTimers();
  changePer(125);
}
void loop() {
  // testing
  changePer(20);
  delay(3000);
  for (byte i = 0; i < 15; i++) {
    changePer(40 + (i+1)*4);
    delay(1000);
  }
  delay(2000);
}

// Change Pulse Period
void changePer(uint16_t myPer) {
  TCC1->CTRLBSET.reg = TCC_CTRLBSET_LUPD;     // Set the Lock Update bit
  while (TCC1->SYNCBUSY.bit.CTRLB);           // Wait for synchronization
  TCC1->PERB.reg = myPer;                     // Set period
  while(TCC1->SYNCBUSY.bit.PERB);             // Wait for synchronization
  TCC1->CCB[1].reg = myPer/2;                 // Set duty-cycle to 50%
  while(TCC1->SYNCBUSY.bit.CCB0);             // Wait for synchronization
  TCC1->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD;     // Clear the Lock Update bit
  while (TCC1->SYNCBUSY.bit.CTRLB);           // Wait for synchronization
}

// Output PWM on digital pin D3 using timer TCC1 (10-bit resolution)
void setupTimers() {
  REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) |        // Divide the 48MHz clock source by divisor N=1: 48MHz/1=48MHz
                    GCLK_GENDIV_ID(4);          // Select Generic Clock (GCLK) 4
  while (GCLK->STATUS.bit.SYNCBUSY) ;           // Wait for synchronization

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

  // Enable the port multiplexer for the digital pin D3 and D11  **** g_APinDescription() converts Arduino Pin to SAMD21 pin
  PORT->Group[g_APinDescription[3].ulPort].PINCFG[g_APinDescription[3].ulPin].bit.PMUXEN = 1;

  // Connect the TCC1 timer to digital output D3 - port pins are paired odd PMUO and even PMUXE
  // F & E specify the timers: TCC0, TCC1 and TCC2
  // D2 is on PA10 = even, use Device E for TCC1
  PORT->Group[g_APinDescription[2].ulPort].PMUX[g_APinDescription[2].ulPin >> 1].reg |= PORT_PMUX_PMUXO_E;

  // Feed GCLK4 to TCC0 and TCC1
  REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN |       // Enable GCLK4 to TCC0 and TCC1
                     GCLK_CLKCTRL_GEN_GCLK4 |   // Select GCLK4
                     GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
  while (GCLK->STATUS.bit.SYNCBUSY) ;           // Wait for synchronization

  // Dual slope PWM operation: timers countinuously count up to PER register value then down 0
  REG_TCC1_WAVE |= TCC_WAVE_POL(0xF) |          // Reverse the output polarity on all TCC0 outputs
                   TCC_WAVE_WAVEGEN_DSBOTH;     // Setup dual slope PWM on TCC0
  while (TCC1->SYNCBUSY.bit.WAVE) ;             // Wait for synchronization

  // Each timer counts up to a maximum or TOP value set by the PER register,
  // this determines the frequency of the PWM operation: Freq = 48Mhz/(2*N*PER)
  REG_TCC1_PER = 256;               // Set the FreqTcc of the PWM on TCC1 to 24Khz
  while (TCC1->SYNCBUSY.bit.PER) ;  // Wait for synchronization

  // Divide the GCLOCK signal by 1 giving  in this case 48MHz (20.83ns) TCC1 timer tick and enable the outputs
  REG_TCC1_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
                    TCC_CTRLA_ENABLE;          // Enable the TCC0 output
  while (TCC1->SYNCBUSY.bit.ENABLE) ; // Wait for synchronization
}
````

**2) Reading short square waves with Seeeduino XIAO pin `D2`**

It is thanks to MartinL that I got this to work. [Source][2]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  [1]: https://gist.github.com/nanase/b80dea702c8933dab5bd13c6e4f9ed31
  [2]: https://forum.arduino.cc/t/attachinterrupt-12-null-high-for-external-interrupt-on-samd21g-m0/899581/2
  [4]: https://forum.arduino.cc/t/attachinterrupt-12-null-high-for-external-interrupt-on-samd21g-m0/899581/4


body:
I have a code for finding the rpm of one system calling here as engine , the engine have a hall sensor output and I have tried the following Code

```

#define SERVO_MIN 2000
#define SERVO_MAX 4000

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

struct Engine {
  uint16_t servoMin = 2000, servoMax = 4000;
  uint16_t rpm_desired;
  volatile Pulse pulse;
  uint32_t get_rpm() {
    cli();
    uint32_t rpm_width = pulse.get_width();
    sei();
    return 12e7 / rpm_width;
  }
};

Engine engine1,engine2;

void pin_initialization() {
  // INT2
  pinMode(19, INPUT_PULLUP);

  // Input capture points
  pinMode(49, INPUT_PULLUP);
  pinMode(48, INPUT_PULLUP);

}

void timer4_initialization() {
  cli();
  TCCR4A = 0; TCCR4B = 0; TCCR4C = 0;
  TCCR4A = B10101011;
  TIMSK4 = B00100000;
  TIFR4 = _BV(ICF4);
  TCCR4B = B11011010;
  OCR4A = 39999;
  OCR4B = SERVO_MIN;//7
  OCR4C = SERVO_MIN;//8
  sei();
}

void timer5_initialization() {
  cli();
  TCCR5A = 0; TCCR5B = 0; TCCR5C = 0;
  TCCR5A = B10101011;
  TIMSK5 = B00100000;
  TIFR5 = _BV(ICF5);
  TCCR5B = B11011010;
  OCR5A = 39999;
  OCR5B = SERVO_MIN;//45
  OCR5C = SERVO_MIN;//44
  sei();
}

void timer3_initialization() {
  TCCR3A = 0x00; TCCR3C = 0x00;

  TCNT3 = 0x1FF; // from datasheet
  TIFR3 = _BV(TOV3);
  TIMSK3 = _BV(TOIE3); // overflow enable
  TCCR3B = B00000010; // 8 prescaling
}

volatile uint32_t ovfCount = 0;
ISR(TIMER3_OVF_vect) {
  ovfCount++;
}

void pulseWidthCalculator(Pulse *channel) {
  unsigned char sreg;
  sreg = SREG;
  cli();
  uint16_t tcnt3 = TCNT3;
  uint32_t ovf_count = ovfCount;
  SREG = sreg;

  if (bit_is_set(TIFR3, TOV3) && tcnt3 < 16384) {
    ovf_count++;
  }

  uint32_t time = ovf_count << 16 | tcnt3;

  if (!channel->stateHigh) {
    channel->stateHigh = true;
  } else if ( channel->stateHigh) {
    channel->width = time - channel->last_toggle;
    channel->stateHigh = false;
  }
  channel->last_toggle = time;
  sei();
}

void externalInterrputInitialization() {
  EIFR = _BV(INTF2) ;
  EICRA = 0; EICRB = 0;
  EICRA = B00100000;
  EIMSK = B00000100;
}

ISR(INT2_vect) {
      pulseWidthCalculator(&engine1.pulse);
}

ISR(TIMER4_CAPT_vect) {
  pulseWidthCalculator(&engine2.pulse);
}

ISR(TIMER5_CAPT_vect) {
//  pulseWidthCalculator(&engine2.pulse);
}

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

  pin_initialization();
  delayMicroseconds(10);

  externalInterrputInitialization();
  delayMicroseconds(10);

  timer3_initialization();
  delayMicroseconds(10);

  timer4_initialization();
  delayMicroseconds(10);

  timer5_initialization();
  delayMicroseconds(10);

}

void loop() {
  Serial.print(engine1.get_rpm());
  Serial.print("\t" );
  Serial.println(engine2.get_rpm());
}

```

The same hall sensor output is given to the INT2 (pin #19) pin and ICP4(pin #49) and the results obtained is given below

```
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
24590 1626
1658 1626
1658 1626
1658 1626
1658 1626
1658 1626
1658 1626
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
1658 1646
4577 1646
4577 1646
4577 1646
4577 1646
4577 1646
4577 1646
4577 1646
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
1667 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
2029 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
3054 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
2961 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
3792 1565
3792 1565
3792 1565
3792 1565
3792 1565
3792 1565
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
3792 1587
1542 1587
1542 1587
1542 1587
1542 1587
1542 1587
1542 1587
1542 1587
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1542 1521
1710 1521
1710 1521
1710 1521
1710 1521
1710 1521
1710 1521
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
1710 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3062 1619
3361 1619
3361 1619
3361 1619
3361 1619
3361 1619
3361 1619
3361 1619
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
3361 1581
1449 1581
1449 1581
1449 1581
1449 1581
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
1449 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1541
2166 1628
2166 1628
2166 1628
2166 1628
2166 1628
2166 1628
2166 1628
2166 1628
2166 1628
2166 1628
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
9880 1544
1588 1544
1588 1544
1588 1544
1588 1544
1588 1544
1588 1544
1588 1544
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1588 1586
1693 1586
1693 1586
1693 1586
1693 1586
1693 1586
1693 1586
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1693 1599
1584 1599
1584 1599
1584 1599
1584 1599
1584 1599
1584 1599
1584 1599
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1584 1567
1526 1567
1526 1567
1526 1567
1526 1567
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1526 1646
1693 1646
1693 1646
1693 1646
1693 1646
1693 1646
1693 1646
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
1693 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1682
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
2464 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
1699 1623
3947 1623
3947 1623
3947 1623
3947 1623
3947 1623
3947 1623
3947 1623
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
3947 1688
1537 1688
1537 1688
1537 1688
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1537 1655
1709 1655
1709 1655
1709 1655
1709 1655
1709 1655
1709 1655
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
1709 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
61696 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
83449 1699
```

I have a feeling that the Noise canceller in the input capture pin is helping here, I would like to get help on

 1. How to make the interrupt values also correct
 2. What logical mistake am I making.

how to add the logic of noise cancelling to Interrupt subroutine code.

If I have to add 4/6 such engines what is the best option.

** with a function generator both INT and ICP are giving the correct result.

title: External Interrupt and Input Capture pin | Arduino MEGA

Answers: 0


body:
In my project Pin 3 of Arduino UNO is as External interrupt (INT1) and at the same time, I have to run Timer2. INT1 dosen't work When Timer2 is run. Timer2 is run just as timer. Is it my mistake or it is logical?

I connect a key to pin 3 as external interrupt and also run timer. Every time INT1 on pin 3 senses rising edge Button_ISR() is called.
but because of running timer2, Button_ISR() is not called.

THis is my code:

    int buttonPin = 3;
    void setup()
    {
      pinMode(buttonPin, INPUT);
      attachInterrupt(digitalPinToInterrupt(3), button_ISR, RISING);
      Serial.begin(9600);
      TCCR2B = 0x07; // clock frequency / 1024
      //OCR2B = 0x00;  // Output compare
      TCNT2 = 0;     // Set counter 2 to zero
      TIMSK2 = 0x01; // Enable overflow interrupt

    }

    void loop()
    {

    }

    void button_ISR()
    {
      Serial.print("button_ISR()");
      Serial.print("\n");
    }

title: Timer2 and INT1 in Arduino UNO

Answers: 1

body:
Here are my 2 cents:

Your code is missing the ```handler``` for the timer. You have enabled the Timer overflow interrupt, but you have ISR prepared for it. So, the control is ending up reaching unhandled interrupt ISR which is a ```Restart```

Arduino is restarting all the time.

Adding one line should fix it temporarily.

```
ISR(TIMER2_OVF_vect) {}
```

Here is the updated code. I can see that the code is now running (not restarting at least)

https://wokwi.com/arduino/projects/307835582788141632

        int buttonPin = 3;
        void setup()
        {
          pinMode(buttonPin, INPUT_PULLUP);
          Serial.begin(9600);
          Serial.println("ready!");
          TCCR2B = 0x07; // clock frequency / 1024
          //OCR2B = 0x00;  // Output compare
          TCNT2 = 0;     // Set counter 2 to zero
          TIMSK2 = 0x01; // Enable overflow interrupt
          attachInterrupt(digitalPinToInterrupt(3), button_ISR, RISING);

        }

        void loop()
        {

        }

    void button_ISR()
    {
      Serial.print("button_ISR()");
      Serial.print("\n");
    }

    ISR(TIMER2_OVF_vect) {}

_________________
Here is the disassembly code found on the Wokwi Arduino simulator for your sketch

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

and if you see the location ``` 0xf6```:
[![enter image description here][2]][2]

you will see that the code is doing a soft reset ( ```JMP 0```). I hope this is helpful to you. Please feel free to ask if you have any questions.

  [1]: https://i.stack.imgur.com/D0b0G.png
  [2]: https://i.stack.imgur.com/0oenN.png


body: I am trying to build a system to control lights remotely, but I am a student and am operating on a tight budget. Is there any way I can have just one Arduino along with a receiver and transmitter (I am using the 433Mhz RF Wireless Transmitter Module and Receiver Kit 5V DC 433MHZ) to do a simple on/off command for lights? I don't want to unnecessarily spend money on another Arduino (especially since I am not going to be transmitting complicated data). If this were possible, what are the other things I would need and what would the code look like?

title: Can I just use one Arduino in a receiver/transmitter circuit?

Answers: 1

body:
It depends on your hardware. You are not transmitting complicated data, but you need to transmit some data. Just wiring a switch to a standard RF transmitter is not enough. Though there are RF modules, which support exactly this (by having corresponding electronic components on the board). If you haven't already bought the modules, you could buy these.

If you already have bought the RF modules, you can buy a standard 433MHz key fob. They are normally rather cheap. Then you can record the key fobs signal with your receiver and write code to check for this signal in the received data.

If you plan to keep on building with Arduino, you might wanna buy directly a bunch of Arduinos (also for future projects). You can get Arduino clones directly from china for very cheap (a Nano clone for example costs normally between 1 and 2$ each in packs of maybe 10).


body:
I'm working with this library [AES lib][1] so everything works I can encrypt/decrypt data. But now I'd like to know what is the best way to store my `aes private key` ? My boars is a personnal board build with an `samd21 cortex M0+` my board doesn't have the possibility to connect with the extern world, like ethernet or ble, wifi.

I've only one possibility is to store the key in my program but what is the best way? Obfuscate my key? I know there is no perfect and secure solution if my key is store in my program, but what is the best solution ? Maybe is it possible to put my key when I upload my sketch in compiler option and store it in emulate eeprom?

  [1]: http://utter.chaos.org.uk/~markt/AES-library.zip

title: Where to store AES key on Arduino board

Answers: 1

body:
All you can really do with your key is to just store it in your code. It makes no difference if that is as a `const` variable or stashed in emulated EEPROM.

The real question is not how to store it but how to stop someone reading it. Most microcontrollers (and the SAMD21 is no exception) have "code protection" facilities - settings you can enable in the chip's configuration (or "fuse") bits to prevent the flash being read by any external debugger or programmer.  By enabling these bits (check the datasheet for your chip) you will prevent people being able to read the flash containing your key no matter *how* you store it.


body:
I'm new to nrf24l01 . I have a two nrf24l01 they both works very well ,I tested them with a simple LED blinking program. Now I write a program for both transmitter and receiver to just send message and get a response for the message. Both the transmitter and receiver programs are given bellow (program works but not as I'm expected)

Transmitter
```
#include<RF24.h>
#include <nRF24L01.h>
#include<SPI.h>

const byte CEpin=9;
const byte CSNpin=10;
RF24 radio(CEpin,CSNpin);
const byte address[][6]={"000001","000002"};
char ack[30],buf[]="hi....How are you?";
bool x;

void setup() {

  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address[1]);
  radio.openReadingPipe(1,address[0]);
  radio.setPayloadSize(30);
  radio.setChannel(83);
  radio.setDataRate(RF24_1MBPS);
  radio.setPALevel(RF24_PA_HIGH);

}

void loop() {
  delay(4);

  radio.stopListening();

  if(radio.write(buf,sizeof(buf)))
      Serial.println("MSG sent successfully");

  delay(6);

 radio.startListening();

 if(radio.available())
 {
  radio.read(ack,sizeof(ack));
  Serial.println(ack);
 }

 }

```

Receiver
```
#include<SPI.h>
#include<RF24.h>
#include<nRF24L01.h>

const byte cepin=9;
const byte cspin=10;
RF24 mynrf(cepin,cspin);
const byte address[][6]={"000001","000002"};
char buf[50];
char response[]={"I'm fine"};

void setup() {

Serial.begin(9600);
mynrf.begin();
mynrf.openReadingPipe(1,address[0]);
mynrf.openWritingPipe(address[1]);
mynrf.setPayloadSize(30);
mynrf.setChannel(83);

}

void loop() {

  delay(4);

  mynrf.startListening();

  if(mynrf.available())
  {
      mynrf.read(buf,sizeof(buf));
      Serial.println(buf);
  }

  delay(6);

  mynrf.stopListening();

  if(mynrf.write(response,sizeof(response)))
      Serial.println("response sent successfully\n\n\n");

}
```
I faced a lot of troubles

1.Without delay() [delay(4);delay(6);] it doesn't work

2.With setPayloadSize() and setChannel() it doesn't work

3.I can't set data rate at 250Kbps and 2Mbps which means setDataRate(RF24_1MBPS) only works

4.setPALevel(RF24_PA_HIGH) and setPALevel(RF24_PA_LOW) only works

5.It also doesn't give output as I'm expected. I attached a screenshot of my output bellow ( COM5 is Transmitter and COM4 is Receiver)

Transmitter and Receiver serial monitor output

[![
][1]][1]

These are the issues what I'm faced. Can any one explain it .

Please any one can suggest me a best tutorials and examples for nrf24lo1 .

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

title: nRF24L01 programming issue

Answers: 1

body:
Two things:

1. nRF24L01 is only half duplex. You can't send and receive at the same time. You must send only briefly and then spend some time listening for the response. With no delays there is no time to listen. It's like it's sat there with its fingers in its ears going "la la la la la" all the time.

2. You're spamming out a "response" all the time. The same situation occurs. You have two transmitters that rarely listen for anything. You should only send your response if you have received an original request.


body:
I'm trying to make a standalone arduino board with an OLED display using an Atmega328p. I never tried to make such a board using SMD components. I've soldered everything together except the OLED display itself. I've uploaded the ArduinoISP sketch to an Arduino Leonardo, and hooked up the SPI pins on my board there. But I simply can't upload anything, I've got 0x000000 as the device signature. I've checked all the connections from the Atmega to the exposed pins themselves, and all seems to be correct with no short circuits.

I'm a bit confused if I put C1 and C3 close enough, could those be the problem? Or is the atmega itself dead? Or did I missed something important?

Wiring between the board and the Leonardo is the following:

```
Board(H1 header)         Leo
1(reset pin)<----------> Pin 10
2(MISO)     <----------> Pin 12
3(MOSI)     <----------> Pin 11
4(SCK)      <----------> Pin 13
-------------------------------
Board(H2 header)         Leo
1(VCC)<----------------> 5V pin
2(GND)<----------------> GND pin
```

I've put a 10uF cap between `GND` and `RESET` on the Leo.

In the stock ArduinoISP sketch, the `#define USE_OLD_STYLE_WIRING` line is uncommented. I've tried both `Arduino as ISP` as a programmer (which didn't work), and `Arduino as ISP (Atmega32U4)` which gave me the aforementioned signature.

As for the board, I've tried selecting both `Arduino Duemilanove or Diecimila/ATmega328P` and `Arduino Pro or Pro Mini/ATmega328P (5V, 16MHz)`

[![main board][1]][1]
[![PCB][2]][2]

  [1]: https://i.stack.imgur.com/SHSXs.png
  [2]: https://i.stack.imgur.com/TSiUD.png

title: Stand alone Atmega328p-au

Answers: 0


body:
I am still new at this.
Using Arduino IDE

My MCU was working as a web server with HTML code on SD card using the Webserver sketch. After trying to include other inputs it stopped working with "Timed out waiting for packet header"
Decided to abandon that for a while.

I loaded the standard Blink sketch, repowered MCU, pressed rst and Flash in prescribed sequence. Powered card and checked for compilation - All OK.

Uploaded Blink sketch and  got "esptool FatalError: Timed out waiting for packet error" again. Repeated power down etc. but same. Something seems to be lingering.

```
Arduino: 1.8.15 (Windows 7), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Serial, None, All Flash Contents, 115200"
```

```
C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\tools\python3\3.7.2-post1/python3 C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0/tools/upload.py --chip esp8266 --port COM10 --baud 115200 erase_flash --before default_reset --after hard_reset write_flash 0x0 C:\Users\IAN\AppData\Local\Temp\arduino_build_567362/Blink.ino.bin

esptool.py v3.0

Serial port COM10

Connecting....

Chip is ESP8266EX

Features: WiFi

Crystal is 26MHz

MAC: 3c:71:bf:3b:03:1f

Uploading stub...

Running stub...

Stub running...

Configuring flash size...

Traceback (most recent call last):

  File "C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0/tools/upload.py", line 66, in <module>

    esptool.main(cmdline)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 3599, in main

    detect_flash_size(esp, args)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 2848, in detect_flash_size

    flash_id = esp.flash_id()

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 688, in flash_id

    return self.run_spiflash_command(SPIFLASH_RDID, b"", 24)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 948, in run_spiflash_command

    old_spi_usr = self.read_reg(SPI_USR_REG)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 562, in read_reg

    val, data = self.command(self.ESP_READ_REG, struct.pack('<I', addr))

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 386, in command

    p = self.read()

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 331, in read

    return next(self._slip_reader)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 2636, in slip_reader

    raise FatalError("Timed out waiting for packet %s" % waiting_for)

esptool.FatalError: Timed out waiting for packet header

esptool.FatalError: Timed out waiting for packet header
```

title: ESP8266 MCU not clearing memory?

Answers: 0


body: So I'm trying to use a photo-resistor and I learned that you should have a "fixed" resistor in the circuit. So my question is, what resistor should I have be the fixed resistor? My photo-resistor has a resistance of 18-50 KΩ at 10lux and a darkness resistance of 2.0 MΩ at 0lux.

title: What resistor should I use when using a photo-resistor?

Answers: 1

body:
What part of the “light curve” are you interested in and what will you be connecting the LDR output / voltage divider to?

A photoresistor (LDR) that has a resistance of, say, 20k Ohms at 10 lux (which is a very low “candlelight” light level*) can have a resistance of only 100 Ohms in daylight (10.000 lux or more). Your voltage divider (input to an ADC i presume?) should be matched with the values you are interested in.

That said, if I make the assumption that you want to distinguish between daylight and darkness and you want to connect the LDR voltage divider to an ADC input on your Arduino that has the same range as your power supply (usually 5V or 3.3V), you could build the following voltage divider using your LDR and a 10k Ohm resistor (R1, your "fixed" resistor):

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/PDrlr.png)

<!-- End schematic -->

This will give you a fairly wide range of values (with higher values being brighter) and allows you (by experiment) to determine when it's time to turn the lights on, for example.

*Actually, the definition of 1 lux is the amount of light one candle generates at a meter distance, so 10 lux is the light of 10 candles.


body:
I need variable frequency output - 0-5000Hz with some duty cycle. I do not want to change timers, because I am using delays, serial and CAN, so I do not want them to be affected by changed timers. I need this for VDO speedometer, which is driven by variable frequency.

Is it possible to set variable time interrupts and change them accordingly to what frequency I want?

title: Variable frequency PWM, without changing timers

Answers: 0


body:
I need help in writing some code that will allow for the ATMega32u4 to be aware of when it's plugged into a USB port. I'm not really familiar with the ATMega32 or with it's function in Arduino, so I'm lost in the dark on this one.

Update:
So in my circuit, the uC will be powered by Lithium Ion Batteries. On my PCB, their is a battery charging circuit that is powered through a USB C cable. My goal is to implement some type of firmware that can differentiate when the board is plugged into a wall outlet and a USB port on a computer. The reason for this is because I don't want the batteries to charge when the USB C cable is plugged into a laptop.

Second Update: Added pictures of the ATMega32 along with the charging circuit mentioned. I'll be the 5V voltage from USBC to charge the batteries. I'll have the data lines on the USB C cable connected so I can program the microcontroller through a USB cable. My goal here is for the microcontroller to recognize when it's connected to a computer. When this happens, I'll talk to the battery charging IC and tell it to not charge.
[![enter image description here][1]][1]

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

  [1]: https://i.stack.imgur.com/jTYgR.png
  [2]: https://i.stack.imgur.com/cJs8j.png

title: Alerting the ATMega32u4 that it's plugged into a computer (via USB)

Answers: 1

body:
I imagine (haven't really tried it) [this](https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/USBCore.cpp#L793) would work, with some minor adaptation to match your code structure.

```c++
// VBUS or counting frames
// Any frame counting?
u8 USBConnected()
{
 u8 f = UDFNUML;
 delay(3);
 return f != UDFNUML;
}
```

The method reads the `UDFNUML` - usb data frame number lower (byte) [register](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf), waits 3 milliseconds, which would be sufficient time get at least 1 more USB frame if the device was really connected to a USB host, reads the register again and checks if it some USB activity had happened.

Personally, I am not a big fan of busy wait delays like that because the CPU could be better utilized doing something useful in that period (3 milliseconds on a 16Mhz CPU = 48000 clocks ~= 48000 instructions)
I'd probably use 1 millisecond timer to sample the register and keep track of the USB status

An alternative would be to use the `bool USBDevice_::configured()` [method](https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/USBAPI.h#L62)
which is [implemented](https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/USBCore.cpp#L828) like so

```c++
bool USBDevice_::configured()
{
 return _usbConfiguration;
}

// Endpoint 0 interrupt
ISR(USB_COM_vect)
{
  //    ... snip ...
  else if (SET_CONFIGURATION == r)
  {
   if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
   {
    InitEndpoints();
    _usbConfiguration = setup.wValueL;
   } else
    ok = false;
  // ... snip ....
}
```

Hopefully one of the two approaches work for you...


body: I was using Arduino IDE 1.8.13 but didn't open for a few week and now I can't launch the IDE and any of the sketch. I uninstall it and downloaded the latest version 1.8.15 but it still poses the same problem. Only the initializing window appear and after it disappear, the IDE won't go any further. I run the debug.exe and still the same problem. Anyone has same problem and has the solutions?

title: Arduino IDE 1.8.15 won't open

Answers: 0


body:
I’m trying to figure out how to make arduino UPS (when the power goes down it should not reset the arduino). Or preferably buy something that will do that for me. I found [this][1], but Im not sure of it will work. I will normally be using power from the outlet, but in case of power outage, I want it to run on the 3,7V li-pol battery (best would be if arduino could somehow know that its running on battery) What solution would you recommend to me?

  [1]: https://www.laskarduino.cz/wemos-d1-mini-lithium-battery-shield/?gclid=EAIaIQobChMI0JK047rR8gIVUeJ3Ch0GnASEEAQYAiABEgIIV_D_BwE

title: Arduino UPS without reset

Answers: 0