message:
Unlocking Digispark ATTiny85 after flashing it to HID

I made a simple test sketch to make my ATTiny85 emulate a Keyboard and send a sequence of keystrokes.

    #include "DigiKeyboard.h"
    void setup() {
      // don't need to set anything up to use DigiKeyboard
    }

    void loop() {
      DigiKeyboard.delay(1000);
      DigiKeyboard.sendKeyStroke(0);
      DigiKeyboard.sendKeyStroke(106); // F15
      DigiKeyboard.delay(59 * 1000);
    }

It worked fine, but now every time I plug it to the USB port on my computer, Windows detects it as a Keyboard and starts typing what I programmed it to type.

Arduino IDE can't reprogram it. When it says "Plug in device now", I do it, but it immediately acts like a Keyboard, not like a programmable ATTiny85.

[![Arduino IDE][1]][1]

*Note: Image shows the console output. Code is just a simple blinker.*

Is there any way to save this board? I just want to upload another sketch to it. Maybe some way to rewrite the bootloader or to erase the flash memory entirely.

Also, please give me some advice so I can avoid being locked out again in the future. I really want to use this board as a Keyboard emulator, but I want to be able to reprogram it if necessary.

[![ATTiny85][2]][2]

  [1]: https://i.stack.imgur.com/3VvD1.png
  [2]: https://i.stack.imgur.com/aSlE2.png

body: If you can't access the bootloader using USB your remaining option is ISP/ICSP (In-Circuit Serial Programming). I have that digispark board and I have never been able to program it using Arduino's IDE/USB. However, since then I always use both an USBasp programmer and the AVRDUDESS programming tool. With them you can eassily program the controller (they have never failed me). Connect the SPI, +5V, GND and RESET connectors from the ATTINY85 to the programmer, compile the code, program the binaries with AVRDUDESS and voila.


sender: user

message:
compress data with 8-4-2-1-BCD-Code

Hello I would like to optimise a few values for transmission via radio (LoRa) beforehand. I have a sensor number (1-255), temperature (00.00-99.99) and humidity. (00.00-99.99) I would like to transmit this data compressed as a byte array. I have already calculated that I need 5 bytes via BCD for this.

How do I get my numbers mapped into the respective byte?

```
float temperature = 24.12;
float humidity = 60.12;
byte message[5];

void setup() {
  Serial.begin(9600);
  message[0] = 12; //sensor id 12
}

void loop() {
  float temperature1 = floor(temperature);
  float temperature2 = (temperature - temperature1) * 100;
  Serial.println(temperature1, 0);
  Serial.println(temperature2, 0);
  message[1] //?? temperature1
  message[2] //?? temperature2

  float humidity1 = floor(humidity);
  float humidity2 = (humidity - humidity1) * 100;
  message[3] //?? humidity1
  message[4] //?? humidity2
}
```

sender: assistant

body:
Why don't you use the following mapping:

1 byte: sensor number (0-255)

2 bytes: temperature (0-65535) by mapping the temperature to

    (int) (65536.0 * (temperature / 100.0))

2 bytes: humidity (0-65535) by mapping the humidity to

    (int) (65536.0 * (humidity / 100.0))

You will lose a little bit of accuracy for the temperature and humidity. If you know ranges in which the temperature/humidity will be, you can get a better accuracy.

    message[0] = 12; // Sensor id 12
    message[1] = highByte(temperature);
    message[2] = lowByte(temperature);
    message[3] = highByte(humidity);
    message[4] = lowByte(humidity);

Note if you have multiple sensors and have to transmit them all, you don't need to send the sensor number, send in bytes 0..3 the temperature/humidity for sensor 0, in bytes 4..7 the temperature/humidity for sensor 1 etc.


body:
This is my final solution with BCD-Code

```
int temperature1 = int(floor(temperature));
int temperature2 = int(round((temperature - temperature1) * 100));
uint8_t bcdTemperature1 = uint8_t((temperature1/10) <<4) | (temperature1 );
uint8_t bcdTemperature2 = uint8_t((temperature2/10) <<4) | (temperature2 );

message[0] = moduleUniqueidentifier;
message[1] = bcdTemperature1;
message[2] = bcdTemperature2;
message[3] = uint8_t(ceil(humidity));
```


message:
Arduino cannot connect to port (arduino nano rp2040)

My arduino cannot connect to any port of my computer. So far i tried the following, without any luck:
 1. Using another arduino to check the usb, and it worked. So no problem with usb cable.
 2. Resetting the arduino (double tap the reset-button)
 3. Inserting deleting and updating the drivers from the device manager
 4. Deleting the drivers, and then inserting the arduino while pressing the reset button.
 5. Connecting the arduino to a different pc and it still doesn't work.
 6. I followed everything listed [here](https://support.arduino.cc/hc/en-us/articles/4404168794514-Nano-RP2040-Connect-not-being-detected-on-USB-port). (Resetting, uploading a uf2 blink file). I even compiled my blink uf2 file, with the newest version of mbed os for rp2040. And i even tried with older versions of the mbed os.
7. I tried uploading a flash_nuke.uf2 file

Is there something else i can do? Or is it permenantly damaged?

When i connect to to the computer, this comes up:
[![enter image description here][1]][1]

In my device manager, i see the following:

[![Another][2]][2]

Also, in the IDE, i cannot select any port.

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

**Extra info :** I was trying to use Serial2 from another arduino to this, so i was changing some jumper wires while they were powered. So it is possible it is damaged.  I also tried uploading some sketches to use a second serial with some modifications to the core of the OS. The changes were on the spirit of [this](https://arduino.stackexchange.com/questions/90583/adding-serial2-ends-up-blocking-nano-rp2040) post, but not necessairily the same.

  [1]: https://i.stack.imgur.com/xquoE.png
  [2]: https://i.stack.imgur.com/GWyoe.png
  [3]: https://i.stack.imgur.com/poW8Z.png

body:
The RP2040 doesn't have a USB serial port *unless you program it to have one*.

Unlike "traditional" Arduinos the RP2040 uses the UF2 bootloader system. This involes the RP2040 pretending to be a USB flash drive, and then uploading code is as simple as copying the .UF2 file to that drive.

If you are seeing that drive then the chip is ready and waiting for you to upload code. You don't need to select a port in the IDE to upload the code since the port is not used for uploading (only for resetting the board to enter the bootloader mode, which you don't need since you are already in bootloader mode).

If the IDE is struggling to find the virtual flash drive then just find the .UF2 file that the IDE created and manually drag and drop it to that drive and it will program the code onto the drive for you.


body:
I had the same issue, even after following all the possible RESET/HARD RESET/BOOTLOADER procedures. I have found a solution for this board to regularly work under Windows, and this involves reintalling it as a DIFFERENT board.

What I became aware of, is that my Win OS (8.1) was not properly installing the Arduino Nano RP2024 driver, for reasons unknown. So, I was first trying to manually reinstall the driver after searching for the proper .inf driver file, which is located in "C:\Users\<USERNAME>\AppData\Local\Arduino15\packages\arduino\hardware\mbed_nano\3.2.0\drivers". Unfortunately this come up with the same issue.

So I went for a "fake" manual install of the device, by selecting "Manually choose from a list of device drivers in your PC".  I then selected "Ports (COM and LPT)", because this is how you would like your board to behave under your OS. THIS STEP IS ESSENTIAL. As far I could see, if you simply chose the Nano RP2024 .inf file located in the above folder, the boards will continue in not showing up in the COM ports list.

After this step, I went through a list of vendors, finding several Arduino-like entries. Among these, I selected "Arduino SA", which ws containing "Arduino Nano 33 BLE" as a device, which I found to be a working option. The board is now regulary showing up into the IDE, even after several connect/disconnect cycles, and also the serial monitor works.

NOTE: in case you select a different working mode of the board (e.g. HID peripheral such as mouse, keyboard or similar) you may have to reinstall it following the procedure above.

Hope this helps!
Cheers
Attila


message:
Differences between two common RS485 to TTL modules

I want to "translate" existing code, that utilizes one of these modules, for the other module.

Specifically, i have code that utilizes an "RS485 to TTL converter". As you can see in this picture,
[![enter image description here][1]][1]

The side that connects to the Arduino has four pins, VCC, GND, TX, RX.
But out of those pins, only two are data pins.

However, if we look at the MAX485 module,
[![enter image description here][2]][2]

The Arduino side has four pins as well, DI, DE, RE, RO.
However, all four of these pins are data pins.

Since the protocol is the same, how come the pins are different?
In the "RS485 to TTL converter" code, `SoftWareSerial` is being used, and it gets the two pins that will eventually connect to the TX, RX on the module - as arguments.

How can i translate this code for the MAX485? How should the pinout be?

  [1]: https://i.stack.imgur.com/38prk.png
  [2]: https://i.stack.imgur.com/h9GvK.png

body:
So far as I'm able to tell, your first module must have a feature that automatically enabled RS485 driver when you are sending and disabled it as soon as you aren't. This is not an uncommon feature.

The latter doesn't support it apparently. It looks like a common MAX485 type design which doesn't. Instead it exposes driver enable and receiver enable pins. These are normally active at opposite levels, which allows you to tie them together and run them to a single pin on the Arduino for controlling both at the same time. Any code that you had using the prior module would need to be changed to manually enable the driver when sending and then disable it afterwards.

You would need an extra digital pin (`PIN_DE_RE`) connected from the Arduino to the module, to both of its RE and DE pins. It would need to be set to output in `setup()` with `pinMode(PIN_DE_RE, OUTPUT);` And set to low `digitalWrite(PIN_DE_RE, LOW);` for a chip following the MAX485 design such that the receiver is enabled and driver disabled initially.

Your write transactions would then need to look like this:
```c++
delayMicroseconds(10);
digitalWrite(PIN_DE_RE, HIGH);
delayMicroseconds(10);
your_serial.write(whatever); // or .print etc
your_serial.flush();
delayMicroseconds(10);
digitalWrite(PIN_DE_RE, LOW);
delayMicroseconds(10);
```

You *may* not need explicit delays around the `digitalWrite` since `digitalWrite` is often slow enough anyway, but the point of them is to give support the minimum time needed between changing the RE/DE pins and a transaction. I picked 10uS somewhat arbitrarily.  More than anything it's just there to raise the point that the timing between the signal change and sending/receiving is important.

For `SoftwareSerial` `.flush()` does nothing usually, at least it doesn't on the AVR. But I include it just to make the point that whatever you use to send serial you must make sure the transaction has left the actual device and not merely been queued for send before disabling the RS485 driver. If you were doing this with `Serial1` on a Leonardo/Micro/Mega etc it would be important. I'd leave `.flush()` as is for `SoftwareSerial` in part because it won't cost you anything to do so and it will make things work if you switch to a buffered-output type serial connection.


body:
RS485 is a standard for a communication bus with potentially multiple senders, of course not at the same time. As such, a device needs to disable its transmitting circuit to let others communicate. The application layer protocol is not defined by RS485.

For this reason, a good driver module provides two control inputs beside the data lines:

- DE is "driver enable". It needs to be active, if the device wants to drive the bus and send its message.
- RE is "receiver enable". It needs to be active, if the device wants to listen to the bus and receive some message.

The data lines are commonly denoted like this:

- DI is "driver input". If you use the ubiquitous serial communication, this is the same as TXD.
- RO is "receiver output". If you use the ubiquitous serial communication, this is the same as RXD.

---

How does this work in the module that only has TXD and RXD?

Well, the hardware assumes some specific baud rate, which should be documented.

As soon as the start bit is detected on TXD, the module internally activates the driver (DE). It might additionally disable the receiver (RE) to avoid reception of the message as an echo.

This activation is controlled by a timer that lasts at least as long as the transmission at the specific baud rate needs to be sent.

---

Now, what to do with the MAX485 module's control lines?

You can connect TXD to DI and RXD to RO, respectively.

If your module simply uses the driver chip manufactured by Maxim, the control input RE has actually inverted logic. This means, the receiver is active, if the line is low. In contrast, the driver is active, if the line DE is high.

Put appropriate calls of `digitalWrite()` at the places where you want to send something to the sensor. Please be aware that the transmission needs some time. You need to make sure that all bits are sent before you disable the driver.

If you only want to receive from the sensor, just disable the driver and enable the receiver all the time.


message:
Will I need the internal pullup resistor if no button is used?

Given I have two Arduinos that are supposed to primitively communicate with each other using digital pins. On Arduino Ar1, pin D13 is to be used as an input, connected to Ar2's D2 pin.

Will I need to use the internal pullup resistor of Ar1 on pin 13, or is an outputted signal of LOW/HIGH already dragged to 0V/5V?

body:
If you set a pin to output mode in Arduino, it is "push-pull". This means, that any value, 0 or 1, is actively driven.

Therefore, you do not need a pull-up or pull-down resistor on the receiving input.

---

You need such a resistor, only if the driver does not drive the voltage actively. For example, this is the case with buttons or switches, which simply open and close a contact.

Some output modes exist like "open-drain" that only drive to GND at a value of 0, but do not drive the output pin at a value of 1. Such modes are not used if you call `pinMode()`.


message:
memory leak w/ no Strings involved

I'm trying to read data being transferred via Infrared from my Smartmeter on my ESP8266 using the following sketch:
```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <Ticker.h>
#include <AsyncMqttClient.h>

#ifndef STASSID
#define STASSID "mySSID"
#define STAPSK  "myPassword"
#endif

#ifndef MQTT_HOST
#define MQTT_HOST IPAddress(192, 168, 0, 100)
#define MQTT_PORT 1883
#endif

#ifndef IR
#define SerialDebug Serial1
#define IR Serial
#endif

AsyncMqttClient mqttClient;
Ticker mqttReconnectTimer;

WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
Ticker wifiReconnectTimer;

const char* host = "esp8266-webupdate";

const byte firstByte = 0x7E;
const byte lastByte = 0x7E;

uint8_t i;

ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;

void connectToWifi() {
  SerialDebug.println("Connecting to WiFi ...");
  WiFi.begin(STASSID, STAPSK);
}

void connectToMqtt() {
  SerialDebug.println("Connecting to MQTT ...");
  mqttClient.connect();
}

void onWifiConnect(const WiFiEventStationModeGotIP& event) {
  SerialDebug.println("Connected to Wi-Fi.");
  connectToMqtt();
}

void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
  SerialDebug.println("Disconnected from Wi-Fi.");
  mqttReconnectTimer.detach();
  wifiReconnectTimer.once(2, connectToWifi);
}

void onMqttConnect(bool sessionPresent) {
  SerialDebug.println("Connected to MQTT.");
  SerialDebug.print("Session present: ");
  SerialDebug.println(sessionPresent);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  SerialDebug.println("Disconnected from MQTT.");

  if (WiFi.isConnected()) {
    mqttReconnectTimer.once(2, connectToMqtt);
  }
}

void array_to_string(byte array[], unsigned int len, char buffer[]) {
  for (unsigned int i = 0; i < len; i++) {
    byte nib1 = (array[i] >> 4) & 0x0F;
    byte nib2 = (array[i] >> 0) & 0x0F;
    buffer[i*2+0] = nib1  < 0xA ? '0' + nib1  : 'A' + nib1  - 0xA;
    buffer[i*2+1] = nib2  < 0xA ? '0' + nib2  : 'A' + nib2  - 0xA;
  }
  buffer[len*2] = '\0';
}

void setup() {

  SerialDebug.begin(115200);
  IR.begin(9600);
  SerialDebug.println();
  SerialDebug.println("Booting Sketch...");

  wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
  wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);

  connectToWifi();

  httpUpdater.setup(&httpServer);
  httpServer.begin();

  mqttClient.setWill("smartmeter/online", 0, true, "no");
}

void loop() {
  httpServer.handleClient();

  uint32_t timeout = 2000;

  int readCnt = 0;
  uint32_t start_time = millis();
  byte tempChar = 0;
  byte *readMessage;
  uint32_t messageLen = 0;

  while ((tempChar != 0x7E) && (millis() - start_time < timeout)) {
    if (IR.available()) {
      tempChar = IR.read();
    }
  }

  start_time = millis();
  timeout = 1000;
  bool done = false;

  if (tempChar == firstByte) { // if first byte == 0x7E
    while ((millis() - start_time) < timeout && !done) {
      if (IR.available()) {
        tempChar = IR.read(); // second byte must be 0xA0
        if(tempChar == 0xA0) {
          while ((millis() - start_time) < timeout && !done) {
            if (IR.available()) {
              tempChar = IR.read(); // 3rd byte tells the legth of the message

              readMessage = new byte[tempChar+2];
              memset(readMessage, 0, tempChar+2);
              readMessage[0] = firstByte;
              readMessage[1] = 0xA0;
              readMessage[2] = tempChar;
              messageLen = ((uint32_t)(tempChar))+2;
              readCnt = 3;

              while ( readCnt < messageLen && ((millis() - start_time) < timeout)) { // minimum len 120 chars for 0x7E format
                if (IR.available()) {
                  readMessage[readCnt] = IR.read();
                  readCnt++;

                  if(readCnt == tempChar+2 && readMessage[readCnt-1] != lastByte) { // correct len but last byte not 0x7E
                    done = true;
                    SerialDebug.printf("Wrong end byte found - %d\n", readMessage[readCnt-1]);
                  } else if(readCnt == tempChar+2) { // correct len and correct last byte
                    done = true;
                    char str[251] = "";
                    array_to_string(readMessage, readCnt, str);
                    mqttClient.publish("smartmeter/raw", 0, false, str);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  mqttClient.publish("smartmeter/online", 0, true, "yes");
  char heap[6] = "";
  itoa(ESP.getFreeHeap(), heap, 10);
  mqttClient.publish("smartmeter/freeHeap", 0, false, heap);
}
```
I'm getting the encoded HEX-data published on my MQTT Topic as desired, the outputs length is 250 characters long (= 125 Bytes) which is correct:

> 7ea07bcf000200231362b1e6e700db08534d536770075f626120000e32e62addedaede38e64c8c3173035a0a853851a28efc57f7fd76a9df59dbb152f796939328ff0f28df7f257d20b5cb2a458c4eb9188e2c1c251701c891244d859ed9c159714bb4451c090d9b1ed3bbb1fc89785ebafbf59ec4f9d540eb4c90d47e

As I found out, the ESP's heap is decreasing by 100-300 by each iteration of the loop (data is being transmitted every second via Infrared from the power-grid Smartmeter) until the ESP will eventually be rebooted by the watchdog after like 5-8 minutes.

I explicitly did not use String variables in the sketch but I legit cannot find the reason for the memory leak. Tried turning off wifi, webserver and mqtt one after each other which didn't actually made a difference.

The heap-size stays at a constant level though when there is no data being received via the Infrared serial port, so I imagine something is fishy when storing the data in the byte array "readMessage".

Anything obvious that immediately pops into someones eye that I missed?

body:
You do a `new` inside the loop

     readMessage = new byte[tempChar+2];

which causes the heap to be filled with `tempChar+2` bytes, but you never delete this.

Try reusing this memory (making it a local, or make it 'dirty' global).

Probably (not tested) the above line can be rewritten as:

    byte readMessage[tempChar+2];


message:
digitalWrite giving different output voltages between programs

I'm using an arduino uno R3 for lighting a few LEDs in response to coputer control. I've written two programs, the first to try an Object Oriented style, and the second to split up the code into more manageable chunks. They both implement the same function, turning one led on, then off and repeat for the other led. I'd also put 100uF capacitors between the anode and ground of each led for a fade effect. When running with the first sketch this works fine, but I noticed with the second sketch, the fade no longer works and the leds are much brighter. There was no change in hardware between sketches, and reverting to either doesn't change anything. On inspection with a multimeter there appears to be a large difference in output voltage (1.6v -> 5.2v) between programs. I've tried changing pins and this seems to have no effect. Is it the code or have I missed something obvious with the hardware?

Program 1
```
#include "Arduino.h"
// create signal class
class two_aspect_signal {
  //store pin numbers
  const int danger_aspect;
  const int clear_aspect;

  public:
    two_aspect_signal(int danger_pin, int clear_pin):
      danger_aspect(danger_pin),
      clear_aspect(clear_pin)
    {}
    void setup(){
      //set to output
      pinMode(danger_aspect,OUTPUT);
      pinMode(clear_aspect,OUTPUT);
    }

    void danger(){
      //turn red light on, green light off
      digitalWrite(danger_aspect,HIGH);
      digitalWrite(clear_aspect,LOW);
    }

    void cleaR(){
      //turn red light off, green light on
      digitalWrite(danger_aspect,LOW);
      digitalWrite(clear_aspect,HIGH);
    }
};
//create signal object
two_aspect_signal sig(7,8);
void setup() {
}
void loop() {
  //turn red light on, green off
  sig.danger();
  delay(2000);
  //turn green light on, red light off
  sig.cleaR();
  delay(2000);
}
```

Program 2
```
#include "sig2.h"
//create signal object
two_aspect sig(7,8);
void setup(){}
void loop() {
  // set red light on, green off
  sig.danger();
  delay(2000);
  // set green on, red off
  sig.cleaR();
  delay(2000);
}
```
Program 2 (sig2.cpp)
```
#include "Arduino.h"
#include "sig2.h"

two_aspect::two_aspect(int clear_pin, int danger_pin)
{
  //set pins to output and store
  pinMode(danger_pin,OUTPUT);
  pinMode(clear_pin,OUTPUT);
  _danger_pin = danger_pin;
  _clear_pin = clear_pin;
}

void two_aspect::danger()
{
  //set red light on, green off
  digitalWrite(_danger_pin,HIGH);
  digitalWrite(_clear_pin,LOW);
}
void two_aspect::cleaR()
{
  //set green led on, red led off
  digitalWrite(_danger_pin,LOW);
  digitalWrite(_clear_pin,HIGH);
}

```
Program 2 (sig2.h)
```
#ifndef sig2_h
#define sig2_h

#include "Arduino.h"

class two_aspect
{
  public:
    two_aspect(int clear_pin, int danger_pin);
    void danger();
    void cleaR();
  private:
    int _clear_pin;
    int _danger_pin;
};

#endif
```

Please let me know if this should've been in the electronics forum, thanks for reading.

body:
The difference is, that in your first sketch you never call `two_aspect_signal.setup()`, thus the pins are never set as output. By default pins are configured as inputs. Doing `digitalWrite()` while the pin is configured as input will enable or disable the internal pullup resistor of that pin.

So in your first sketch you are powering the LEDs through the internal pullup resistor (if I correctly remember about 10kOhm). Thus they are rather dim. Also it takes some time for the capacitor to be charged through the big pullup resistor.

In your second sketch you configure the pins as output. So the LEDs will now  be actively driven through the pins output driver. It can provide way more current than the pullup resistor, thus the LEDs light up brigther. And the bigger current can also charge the capacitor in way less time (a time so small, that you don't even see it). Thus you don't see any fading (the fading is there, but just too fast for your eyes).

**What to do know?** You can of course just use the pullup resistor (and not configuring the pins as output). Or you can configure the pins as outputs and add a current limiting resistor between the pin and the LED/capacitor bundle. With your second sketch and the current circuit you are risking to damage the output drivers of that pin (through the LED current and through the high inrush current until the capacitor is charged). The sizing of that resistor depends on your needs. Make sure, that the current never exceeds 20mA (sustainable pin max current) (for 5V this would be R=U/I=5V/20mA=250Ohm as minimum resistance). The higher the resistance, the dimmer the LED will be and the longer the capacitor needs to charge. After that you can also change the capacitance. The higher the capacitance, the longer it will take to charge it (so longer fade effect).


message:
Standalone ATMega328 - do I need to burn the bootloader?

I want to get an ATMega328 off of the Digi-Key, and use it like an Arduino (without requiring the whole Arduino board).

When it comes to programming, do I need to do anything special like burn the bootloader onto it or something like that?

I want to use the Arduino IDE to program it.

body:
No, you do NOT need to burn the bootloader. But depending on your equipment and programing habits you may want to.
The bootloader used by Arduino (which is known by the name 'optiboot') is used to allow to program the microcontroller via serial interface. If you want to program your microcontroler this way, then you need the bootloader. Otherwise you will need a programmer for In-System-Programing that uses the SPI interface like Atmel AVRISP MKII, any cheap clone like USBtinyISP or any regular Arduino with ArduinoISP flashed on it.


body:
At the risk of having my answer closed as "link only" I want to tell you that I have [a page describing how to make an Atmega328P into an Arduino-compatible board](http://www.gammon.com.au/forum/?id=11637).

There is far too much detail to post here, but once you have installed your processor with a resistor and a couple of decoupling capacitors you can use another Arduino to burn the bootloader.

[![Burning the bootloader][1]][1]

Once you have done that you can use an FTDI cable to program your new Arduino-compatible from the Arduino IDE. The cable would be hooked up like this:

[![Programming with FTDI cable][2]][2]

Now you can program the chip just using the IDE as if it was a "real" Arduino.

  [1]: https://i.stack.imgur.com/3zhtf.jpg
  [2]: https://i.stack.imgur.com/6GiDl.jpg


message:
ESP32 - error when using `LITTLEFS.h` after core updated to 2.0.4

After updating ESP32 to core version 2.0.4 (file in Arduino IDE preferences was replaced  to`https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json` to upgrade), I get the following error:

    /Users/guydvir/Dropbox/Arduino/libraries/LittleFS_esp32/src/LITTLEFS.cpp: In member function 'virtual bool LITTLEFSImpl::exists(const char*)':
    /Users/guydvir/Dropbox/Arduino/libraries/LittleFS_esp32/src/LITTLEFS.cpp:44:28: error: no matching function for call to 'LITTLEFSImpl::open(const char*&, const char [2])'
         File f = open(path, "r");
                                ^
    In file included from /Users/guydvir/Dropbox/Arduino/libraries/LittleFS_esp32/src/LITTLEFS.cpp:17:
    /Users/guydvir/Library/Arduino15/packages/esp32/hardware/esp32/2.0.4/libraries/FS/src/vfs_api.h:38:17: note: candidate: 'virtual fs::FileImplPtr VFSImpl::open(const char*, const char*, bool)'
         FileImplPtr open(const char* path, const char* mode, const bool create) override;
                     ^~~~

I minimized code to headers only ( and empty `setup` and `loop`:

#include "FS.h"
//#include "LITTLEFS.h" // <----- commenting out stops the error message
#include <time.h>
#include <WiFi.h>

What may be the error and how to fix it ?

body: As Juraj commented - no need for `LittleFS_esp32` library, after upgrade to esp32 Arduino 2.0.4


body:
As you experienced, the Lorol's LittleFS_esp32 library was merged into ESP32 core from v1.0.6 and creates compile error to some old codes.

The difference is you have to use `#include <LittleFS.h>` instead of `#include <LITTLEFS.h>` for new cores (v1.0.6, v2.0.0+)

Check and modify the following snippet (used widely in my [ESP_WiFiManager library](https://github.com/khoih-prog/ESP_WiFiManager) ) for your purpose

```
// Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h
//#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) )  //(ESP_ARDUINO_VERSION_MAJOR >= 2)
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
  #if (_WIFIMGR_LOGLEVEL_ > 3)
    #warning Using ESP32 Core 1.0.6 or 2.0.0+
  #endif

  // The library has been merged into esp32 core from release 1.0.6
  #include <LittleFS.h>       // https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS

  FS* filesystem =      &LittleFS;
  #define FileFS        LittleFS
  #define FS_Name       "LittleFS"
#else
  #if (_WIFIMGR_LOGLEVEL_ > 3)
    #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library
  #endif

  // The library has been merged into esp32 core from release 1.0.6
  #include <LITTLEFS.h>       // https://github.com/lorol/LITTLEFS

  FS* filesystem =      &LITTLEFS;
  #define FileFS        LITTLEFS
  #define FS_Name       "LittleFS"
#endif
```


message:
I'm using nRF2401 and in my transmitter and receiver the Rx is not blinking and Tx is blinking; why does Rx not blink?

I did a search on the meaning of RX and TX and it seems TX means sending data and RX means receiving data.
So when my transmitter is turned off, my receiver looks like this and it works with a battery:

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

and when I turn on the transmitter my receiver looks like this:

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

So Tx is blinking and I'm confused, because Rx is not blinking and I think I receive nothing.

receiver code:

    #include <RF24.h>
    #include <SPI.h>

    int speedpin1=5;
    int dir11=3;
    int dir12=7;

    int speedpin2=A4;
    int dir21=8;
    int dir22=A3;

    int speedpin3=A2;
    int dir31=A1;
    int dir32=A0;

    int speedpin4=2;
    int dir41=4;
    int dir42=6;

    int mspeed;

    const byte CE = 9;
    const byte CS = 10;

    int data[1];

    RF24 Radio(CE,CS);
    const byte address[6]="00001";

    void setup() {
      // put your setup code here, to run once:
    Serial.begin(9600);
    pinMode(speedpin1,OUTPUT);
    pinMode(dir11,OUTPUT);
    pinMode(dir12,OUTPUT);

    pinMode(speedpin2,OUTPUT);
    pinMode(dir21,OUTPUT);
    pinMode(dir22,OUTPUT);

    pinMode(speedpin3,OUTPUT);
    pinMode(dir31,OUTPUT);
    pinMode(dir32,OUTPUT);

    pinMode(speedpin4,OUTPUT);
    pinMode(dir41,OUTPUT);
    pinMode(dir42,OUTPUT);

    Radio.begin();
    Radio.openReadingPipe(1,address);
    Radio.startListening();
    }

    void loop() {
      // put your main code here, to run repeatedly:
    if(Radio.available()){
      Radio.read(data,sizeof(data));
      if (data[0]>131){

        digitalWrite(dir41,LOW);
        digitalWrite(dir42,HIGH);

        analogWrite(dir31,0);
        analogWrite(dir32,255);

        digitalWrite(dir21,HIGH);
        analogWrite(dir22,0);

        digitalWrite(dir11,HIGH);
        digitalWrite(dir12,LOW);

        mspeed=255;

        analogWrite(speedpin1,mspeed);
        analogWrite(speedpin2,mspeed);
        analogWrite(speedpin3,mspeed);
        analogWrite(speedpin4,mspeed);
        Serial.println(mspeed);

      }
      if (data[0]<131){

        digitalWrite(dir41,HIGH);
        digitalWrite(dir42,LOW);

        analogWrite(dir31,255);
        analogWrite(dir32,0);

        digitalWrite(dir21,LOW);
        analogWrite(dir22,255);

        digitalWrite(dir11,LOW);
        digitalWrite(dir12,HIGH);

        mspeed=255;

        analogWrite(speedpin1,mspeed);
        analogWrite(speedpin2,mspeed);
        analogWrite(speedpin3,mspeed);
        analogWrite(speedpin4,mspeed);
        Serial.println(mspeed);

      }
      if (data[0]==131){

        mspeed=0;
        analogWrite(speedpin1,mspeed);
        analogWrite(speedpin2,mspeed);
        analogWrite(speedpin3,mspeed);
        analogWrite(speedpin4,mspeed);
        Serial.println(mspeed);

      }

    }

transmitter code:

    #include <RF24.h>
    #include <SPI.h>
    const byte CE = 9;
    const byte CS = 10;
    int jpin=A0;
    int datax;
    int data[1];

    RF24 Radio(CE,CS);
    const byte address[6]="00001";
    void setup() {
      // put your setup code here, to run once:
    Serial.begin(9600);
    Radio.begin();
    Radio.setRetries(5,10);
    Radio.openWritingPipe(address);
    }

    void loop() {
      // put your main code here, to run repeatedly:
    datax=analogRead(jpin);
    datax=map(datax, 0, 1023, 0, 255);
    data[0]=datax;
    Serial.print("data x: ");
    Serial.println(data[0]);
    Radio.write(data,sizeof(data));

    }

I'm using nRF2401 and in my transmitter and my receiver the Rx is not blinking and Tx is blinking; why does Rx not blinking?

I also don't know that why does Tx in my receiver not blinking when I move the joystick in my transmitter.

I can control my motors only a few times with a Joystick and after that the Tx in my receiver does not blink and then my motors are keep working or they stop and I can't control them.

----------
## Edit ##

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

  [1]: https://i.stack.imgur.com/eeZTJ.jpg
  [2]: https://i.stack.imgur.com/2SMBM.jpg
  [3]: https://i.stack.imgur.com/S2deH.png

body:
We've got multiple questions here, so:

## Why is TX/RX blinking weirdly? ##

The RX and TX LEDs on the Arduino Nano are connected to the RX0 and TX1 pins: they show activity on the Serial-over-USB port that connects your Arduino to the PC.

So, every time you receive data, you do a `Serial.print()`, transmitting text to the PC (where you can see that text in the Serial monitor). And _that_ is what's showing up in the RX/TX LEDs: the text you send over the serial line to the PC. If you want to get RX blinking in this setup, just enter some text in the Serial monitor's input box and send it. The TX LED should blink shortly, then (maybe too short to be noticeable).

Reusing those LEDs to show activity on the wireless transceiver by writing to the RX0/TX1 pins would mean that you'll lose the Serial monitor, i.e. `Serial.print()` would no longer be possible. Not recommended.

Your best option would be to introduce your own LEDs as an activity monitor. Just add an LED in series with an 1K resistor to pins D11 and D12 each (which are [the MOSI and MISO lines of the SPI interface][1], i.e. the equivalent of RX and TX of a serial interface).

In other words, add these components:
```
  D11 --> -LED+ --> 1K resistor --> 5V
  D12 --> -LED+ --> 1K resistor --> 5V
```

## Why does my transmission stop? ##

That's harder to see, but: I think you're using the RF24 library interface wrong.

According to [the code example "Transmitter Lv2" on this page][2], `Radio.read()` and `Radio.write()` expect a _reference_ to the data array, so you'd need to use `Radio.read(&data, sizeof(data))` and `Radio.write(&data, sizeof(data))` (note the ampersands).

It also may be that your transmitter is transmitting faster than your receiver can accept data, so you could try and add a `delay(5)` in the `loop()` of your transmitter.

  [1]: https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#Interface
  [2]: https://create.arduino.cc/projecthub/Arnov_Sharma_makes/arduino-based-nrf24-transmitter-receiver-setup-d73279#code


message:
Arduino Uno usb 5v and external power supply 12v overheating

I have a issue with my Arduino Uno r3.

I am sorry for my English and explanation of my problem I am not great with explaining.

I'm not sure why is that happening but I have 5V 18A power supply to power my LEDs. I connected 5v from arduino to 5v from external power supply and I plugged this combined cabble to my LEDs. I did the same with GND. On data pin 6 I used 220 Ohm resistor. Also I am using 12V power supply to power my arduino.

In the same time the usb was plugged.

In and between usb and power some chip is getting HOT I got quickly scared and un plugged whole arduino I am not sure how I should plug this in.  It worked fine until I plugged in external power supply and I was using few LEDs at the time.

This is how it looked like in more understandable way.

[![this  is how it looked like in more understandable way][1]][1]

Just point to me what I did wrong. I will be gratefull for any kind of help.

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

body:
I suggest you do not use the 12V external power when you are already supplying it with an externally regulated 5V source.

The sole purpose of the 12V input is to provide a 5V regulated supply voltage for the microcontroller. The PCB outputs this on the 5V header. The problem is that you are feeding your external 5V into that pin.

You can either continue powering the Arduino from the 12V supply and disconnect the external 5V from the Arduino (keep the GND from the external 5V conected). Or you can just remove the 12V power source.

It could end up that you have damaged the chip that overheated. If the Arduino still works after doing one of the solutions above, then you may be lucky and not damaged anything.

As a precaution, please measure your external 5V source with a multimeter to make sure it is within specs that Arduino allows.


message:
IF statement inside of a function call? Code help

I was browsing a library for steppers motors when I ran across this line of foreign-looking code:

    digitalWrite(enable_pin, (enable_active_state == HIGH) ? LOW : HIGH);

Is this some kind of shortcut to tossing an if statement into a function call? I've never seen this before. What exactly does it do, and what is this particular arrangement of code called?

Thanks!

body:
You could look at this as an "if expression", the correct term is "conditional operator" (C++ standard chapter 8.16). Many know it as "ternary operator" because it has three operands. You might already know the "unary operator" with one operand like the negation sign `-x`, or the "binary operator" with two operands like the addition `a + b`.

This expression consists of:
- the first operand
- the operator `?`
- the second operand
- the operator `:`
- the third operand

The first operator is evaluated and converted (if necessary) into a boolean.

If the result is `true`, the second operand is evaluated and gives the value of the expression.

If the result is `false`, the third operand is evaluated and gives the value of the expression.

Only one of the second and third operands is evaluated. This is important, if you use operands with side effects, like function calls can have.

This operator is often frowned upon. If used excessively, the source becomes easily unreadable. Many professional code style guide prohibit its use for this reason.

In your case it could have been written more clearly as
```c++
if (enable_active_state == HIGH) {
    digitalWrite(enable_pin, LOW);
} else {
    digitalWrite(enable_pin, HIGH);
}
```

It outputs the inverted value of the variable `enable_active_state` at the pin `enable_pin`.

Experienced Arduino users know that `HIGH` and `LOW` are represented in a way that are compatible with boolean values. Boolean inversions can be simpler expressed with the logical negation operator:
```c++
digitalWrite(enable_pin, !enable_active_state);
```

Anyway, the current compilers are commonly smart enough to generate the same machine code for each of the variants. Therefore, please write your source in the best way to express your intention. Anything else is "premature optimization", which is a bad thing. But this is a completely other topic.


message:
How to use the M117 temperature sensor from mysentech?

Anyone can help me decode the temperature of [the M117 chip from mysentech.com][1]?

I tried things, but I get a constant raw value of 0xFFFF, which becomes 1 once 2's complemented is applied.

The chip shows up at the expected address (TEMP_SENSOR_ADDRESS is 0x45) during a scan operation of the I2C bus.

```cpp

 // Start I2C Transmission
 Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
 // Select data register
 Wire.write(0x00);
 // Stop I2C Transmission
 Wire.endTransmission();
 delay(300);

 // == Request for the raw temp 2 bytes
 Wire.requestFrom(TEMP_SENSOR_ADDRESS, 2);
 const size_t count = Wire.available();
 log("%d bytes available", count);

 if (count!=2) {
  *ready = false;
  warn("I2c temp is not available");
 }
 else {
  *ready = true;
     // Get the raw data as the 16-bit big endian (MSB-LSB)
  byte data0 = Wire.read();
  byte data1 = Wire.read();
  const uint16_t raw = data0<<8 | data1;
  const int sign = raw>>15 == 1 ? -1 : 1;

  // Get the raw temperature as a 2's complement of the 16-bit (MSB-LSB) value
  const int16_t c2Raw = ~raw + 1;

  // Apply scale and offset
  temperature = sign * float(c2Raw)/256.0 + 40;
  log("raw: x (%d) | Raw 2's complement  x (%d) | temperature: %f°C",
   raw, raw,
   c2Raw, c2Raw,
   temperature
  );
    }
```

**[UPDATE | SEPT. 2nd 2022]**
 Following the discussion I had with @jsoleta, my current code is as follows. But still getting FFFF AC. AC being the correct CRC for FFFF.
Coud it be the result of a wiring issue of the component on our custom PCB?

The logs:

```
b5725|—|  Thermometer: Command: Writing to register command 0xCC44
b5725|—|  Thermometer: Command byte 0: cc
b5725|—|  Thermometer: Command byte 1: 44
b5725|—|  Thermometer: Command: register transmitted 2 bytes
b5725|—|  Thermometer: 3 bytes available
b5725|—|  Thermometer: Actually read 3 bytes: ff ff ac
b5725|—|  Thermometer:  CRC matched: computed: ac == read: ac
b5725|—|  Thermometer: raw: ffff (65535) | Raw 2's complement  0001 (1) | temperature: 39.996094°C
b5725|—|  Thermometer: raw: ffff (65535) | temperature: 39.996094°C
b5725|—|  Thermometer: Transmitting board temperature 40.0°C over the RS-485 bus (raw is 799 - 0x031f)
```

The updated code:
```cpp
loat I2cThermometer :: readTemperature(bool *ready) {
 float temperature = 0;

 log("Command: Writing to register command 0xCC44");
    // Start I2C Transmission
 Wire.beginTransmission(TEMP_SENSOR_ADDRESS);

 // Select data register 0x00, config 0x01

 const uint16_t command =
  0xcc44 // Wait for temperature measurement
  //0xf32d  // Read status
  //0x611d // Measurement result set alarm
 ;
 byte * data = (byte*)&command;
 Wire.write(data[1]); log("Command byte 0: x", data[1]);
 Wire.write(data[0]); log("Command byte 1: x", data[0]);

 // Stop I2C Transmission
 const auto readCount = Wire.endTransmission();
 log("Command: register transmitted %d bytes", readCount);
 delay(15);
 // == Request for the raw temp 2 bytes + CRC
 Wire.requestFrom(TEMP_SENSOR_ADDRESS, 3); // 2-byte data + 1-byte CRC
 const size_t count = Wire.available();
 log("%d bytes available", count);

 if (count!=3) {
  *ready = false;
  warn("No temp data is not available");
 }
 else {
  *ready = true;

   // Get the raw data as the 16-bit big endian (MSB-LSB)
   byte data[3];
   const size_t r = Wire.readBytes(data, sizeof data);
   log("Actually read %d bytes: x x x", r, data[0], data[1], data[2]);
   const byte crc = MY_CRC8(data, 2);
   if (crc != data[2]) {
    warn("CRC mismatch: computed: x != read: x", crc, data[2]);
   }
   else {
    success("CRC matched: computed: x == read: x", crc, data[2]);
   }
   const uint16_t raw = *(uint16_t*)data;

   const int sign = raw>>15 == 1 ? -1 : 1;

   // Get the raw temperature as a 2's complement of the 16-bit big engdian (MSB-LSB)
   const int16_t c2Raw = ~raw + 1;

   // Apply scale and offset
   temperature = sign * float(c2Raw)/256.0 + 40;
   #if LOG_LEVEL >= LOG_LEVEL_DEBUG
   log("raw: x (%d) | Raw 2's complement  x (%d) | temperature: %f°C",
    raw, raw,
    c2Raw, c2Raw,
    temperature
   );
   #endif

  #if LOG_LEVEL >= LOG_LEVEL_DEBUG
  log("raw: x (%d) | temperature: %f°C",
   raw, raw,
   temperature
  );
  #endif

  writeBoardTemperatureMessage(temperature);
 }

 if (!(*ready)) {
  #if LOG_LEVEL >= LOG_LEVEL_INFO
  log("Temperature is not ready %d°C", temperature);
  #endif
  return temperature;
 }

 #if LOG_LEVEL >= LOG_LEVEL_INFO
 log("Temperature is %d°C", temperature);
 #endif

 return temperature;
}

```

  [1]: https://www-mysentech-com.translate.goog/productinfo/535226.html?_x_tr_sch=http&_x_tr_sl=zh-CN&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=sc

body:
> WARNING: I have no way to test/verify the parts of this that directly apply to your chip.

## Issue conversion command

This device does not appear to follow the common write-register-address followed by read-register-value scheme. **Instead, it seems in order for the device to  sample and convert temperature at all you must first issue  a command to perform the conversion. You're not doing that, so that seems to be the principal problem.** You're reading whatever the value is prior to every having asked for a conversion an the datasheet says indicates this is indeterminate. So 0xFFFF is plausible and unremarkable for a value you'd get not having already requested conversion.

Issuing the conversion command (again, I'm not able to test this):

```c++
void request_temperature_conversion() {
  Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
  Wire.write(0xCC);
  Wire.write(0x44);
  const auto check_me = Wire.endTransmission();
  delay(15); // Ensure a completed conversion.
}
```

## Read result

To read the result of value of the most recent conversion:

```c++
uint16_t read_u16_temperature() {
  const auto read_count = Wire.requestFrom(
    TEMP_SENSOR_ADDRESS,
    3 // the actual transaction includes an 8-bit as well as 16-bit sample
  );
  uint8_t temp_payload[2];  // 2 because i'm going to ignore the CRC.
  Wire.read(temp_payload, sizeof temp_payload);

  return uint16_t(temp_payload[0]) << 8 | temp_payload[1];
}

int16_t read_s16_temperature() {
  int16_t r;
  const uint16_t u = read_u16_temperature();
  memcpy(&r, &u, sizeof r);
  return r;
}
```

## Together

Again, I can't really test this.

```c++
request_temperature_conversion();
temperature =
  sign
  * float(read_s16_temperature()) / 256
  + 40;
```

You probably can and should avoid the use of the floating point type.  If you're logging this data and transmitting this data to somewhere else to be logged, you may be better off transmitting/storing the raw values which can be (re)interpreted later rather than having different versions of your sketch potentially affecting how a calculation is done on the values.

## Manufacturer's documentation

The website you have linked to has a datasheet in Chinese. You may get some use out of you machine translate it to English (or whatever). Google Drive is capable of this. Probably more useful are the archives of sample code intended for STM32.  That's where all the information came from, including crucially the use of `0xCC44` command to prompt conversion. The 15ms delay is also lifted from what I read in the STM32 sample code in the rar archive from the site; I didn't put much thought into its significance or how the part behaves if you don't wait long enough. You should read through it, because there's more about configuring the chip, the CRC, etc.

[![Chip Maker's download center showing filenames M117 M117B Digital Temperature Chip Product Manual-Minyuan 202206.pdf, M117B_IIC_Samplecode_stm32-MY202203.rar, M117_MTS01_IIC_Samplecode_stm32-MY202202.rar][1]][1]

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


message:
Is it possible to use multiple I2C sensors with Arduino without an I2C multiplexer?

I have an IMU sensor and a Bluerobotics temperature sensor, both have different I2C addresses.

I want to integrate both with an Arduino UNO, I know I can do this with an I2C multiplexer but I don't have access to one right now.

Is it possible to integrate them with arduino without a multiplexer, i.e., by just connecting them parallelly on the A4 and A5 pins of Arduino? (This didn't work though when I tried, the temperature sensor was giving values but the values of IMU sensor were only zeros on the Arduino Serial Monitor)

I've found some videos on it on YT, some have connected pull up resistors to the sensors, but this method doesn't seem to work.

So before delving deeper into it, I'd like to know if this is even possible to do without a multiplexer, because my time is precious since I have a project deadline.

body:
first of all , you said they have different I2C addresses , so you don't need **I2C
 multiplexer** , I2C multiplexer is only used when having more than one device having same I2C address , and refer to [Adafruit I2C multiplexer][1] as they say :

> Finally, a way to get up to 8 same-address I2C devices hooked up to one microcontroller

which means it can handle 8 devices having the same address , but in your case , the addresses already are different , so why you need I2C multiplexer.

your problem needs to dig deep into debugging , you can get your self a cheap logic analyzer like [this cheap 10$ saleae clone analyzer][2] to see what data is actually put into the bus , the analyzer will make your debugging way more easy than you think , like the below picture obtained from [saleae official website][3] and also this cheap saleae clone works perfect with *logic* software offered from saleae:
  [![enter image description here][4]][4]

but for your problem , I am guessing that it's due to pull resistors and the parasitic capacitance between the 2 buses , reading from [I2C specification file][5], at section 7.1 , there is equation from minimum and maximum allowed pull up resistors according to nodes connected to the bus :

> Rp(min) = (Vdd - Vol(max)) / Iol
>
>
> Rp(max) = tr / (0.8473 * Cb)
>

where `Vdd` is 5V when using arduino , `tr` is the rise time maximum and it depends on MCU, `Cb` is  estimated bus capacitance and you can get that from datasheet of every component in your bus line as for arduino its capacitance is specified in [datasheet][6] at page 264 saying

> Capacitance for each I/O pin Ci – 10 pF

other symbols , you can get from the I2C specifications mentioned above , but your problem is due to pull up resistors I guess and you can't really know without debugging. I recommend you using logic analyzers.

  [1]: https://www.adafruit.com/product/2717
  [2]: https://www.amazon.com/HiLetgo-Analyzer-Ferrite-Channel-Arduino/dp/B077LSG5P2/ref=sr_1_3?keywords=logic analyzer&qid=1661924579&sprefix=logic a,aps,413&sr=8-3
  [3]: https://www.saleae.com/
  [4]: https://i.stack.imgur.com/26n6R.jpg
  [5]: https://www.nxp.com/docs/en/user-guide/UM10204.pdf
  [6]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf


body:
Since you did not give links I went on line and checked them. Be sure the I2C modules do not have pull up resistors. If so note the value.  Adjust your external so the pull up to 3V3 is about 3.1K. You will need a level translator for both the IMU module and the Bluerobotics temperature sensor they are both 3V3 boars. Good news one set of level translators will work for both. Remember you will need pull ups on both sides of the translators, check as not all do.

Since you are just getting started you can pick one of the fine 3V3 micros in the Arduino or ESP series of boards. Simple starting point rule for pull up on I2C: 3.1K for 3V3 and 4.7K for 5V. Let us know how you do.

Bad News it is possible you damaged one or both of the I2C boards with 5V.


message:
Upload to ESP32-C3 Fails

I have built a custom circuit board using the **ESP32-C3-MINI-1-H4** module([datasheet][1]).

Here is a schematic:
[![enter image description here][2]][2]

I have the GND, Tx, and Rx lines hooked up to an arduino uno without the atmega. The 3V3 comes from an external power supply.

I have successfully put the chip into download mode(as shown from the serial output below).

>ESP-ROM:esp32c3-api1-20210207
>
>Build:Feb  7 2021
>
>rst:0x1 (POWERON),boot:0x5 (DOWNLOAD(USB/UART0/1))
>
>waiting for download

I attempted to upload an example sketch using the following settings(Arduino IDE).

[![Arduino Settings][3]][3]

I held down the reset button(S4) until the Rx light on the uno started flashing.

It works about 5% of the time, but 95% of the time it ends in this:

> A fatal error occurred: Failed to connect to ESP32-C3: No serial data received.

I'm not sure how that is possible, as the serial data appears on the oscilloscope, and it is clearly in download mode as shown by the serial output.

I have tried removing the voltage divider form the RX line, but that didn't help. Is there any way to make uploading more consistent?

  [1]: https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf
  [2]: https://i.stack.imgur.com/KELzh.png
  [3]: https://i.stack.imgur.com/l38V5.png

body:
You must be in flash mode DIO and watch the "USB CDC on boot" which must be on if you use native C3 usb and off if you use an external usb-serial converter.

You can upload OK in QIO mode but program wont start, that is EXACTLY what OP is asking.


message:
nRF52832 BLE "conn_handle" to disconnect the current connected devices

I'm working on [nRF52832 Bluefruit Adafruit Module][1]. I want the BLE connection to disconnect using a function and can call whenever required. But the issue is the disconnect function needs "conn_handle" to disconnect from the current connected Client.

Can anyone help me find where I can get the "conn_handle" of the connected client?

    /**
     * Callback invoked when a connection is dropped
     * @param conn_handle
     * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
     */
    void disconnect_callback(uint16_t conn_handle, uint8_t reason)
    {
      (void) conn_handle;
      (void) reason;

      connection_num--;

      // Mark the ID as invalid
      int id  = findConnHandle(conn_handle);

      // Non-existant connection, something went wrong, DBG !!!
      if ( id < 0 ) return;

      // Mark conn handle as invalid
      prphs[id].conn_handle = BLE_CONN_HANDLE_INVALID;

      Serial.print(prphs[id].name);
      Serial.println(" disconnected!");
    }

The below complete code is for "Central Bleuart Multi"-

    /*********************************************************************

     This is an example for our nRF52 based Bluefruit LE modules

     Pick one up today in the adafruit shop!

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

     MIT license, check LICENSE for more information
     All text above, and the splash screen below must be included in
     any redistribution
    *********************************************************************/

    /* This sketch demonstrates the central API() that allows you to connect
     * to multiple peripherals boards (Bluefruit nRF52 in peripheral mode, or
     * any Bluefruit nRF51 boards).
     *
     * One or more Bluefruit boards, configured as a peripheral with the
     * bleuart service running are required for this demo.
     *
     * This sketch will:
     *  - Read data from the HW serial port (normally USB serial, accessible
     *    via the Serial Monitor for example), and send any incoming data to
     *    all other peripherals connected to the central device.
     *  - Forward any incoming bleuart messages from a peripheral to all of
     *    the other connected devices.
     *
     * It is recommended to give each peripheral board a distinct name in order
     * to more easily distinguish the individual devices.
     *
     * Connection Handle Explanation
     * -----------------------------
     * The total number of connections is BLE_MAX_CONNECTION (20)
     *
     * The 'connection handle' is an integer number assigned by the SoftDevice
     * (Nordic's proprietary BLE stack). Each connection will receive it's own
     * numeric 'handle' starting from 0 to BLE_MAX_CONNECTION-1, depending on the order
     * of connection(s).
     *
     * - E.g If our Central board connects to a mobile phone first (running as a peripheral),
     * then afterwards connects to another Bluefruit board running in peripheral mode, then
     * the connection handle of mobile phone is 0, and the handle for the Bluefruit
     * board is 1, and so on.
     */

    /* LED PATTERNS
     * ------------
     * LED_RED   - Blinks pattern changes based on the number of connections.
     * LED_BLUE  - Blinks constantly when scanning
     */

    #include <bluefruit.h>

    // Struct containing peripheral info
    typedef struct
    {
      char name[16+1];

      uint16_t conn_handle;

      // Each prph need its own bleuart client service
      BLEClientUart bleuart;
    } prph_info_t;

    /* Peripheral info array (one per peripheral device)
     *
     * There are 'BLE_MAX_CONNECTION' central connections, but the
     * the connection handle can be numerically larger (for example if
     * the peripheral role is also used, such as connecting to a mobile
     * device). As such, we need to convert connection handles <-> the array
     * index where appropriate to prevent out of array accesses.
     *
     * Note: One can simply declares the array with BLE_MAX_CONNECTION and use connection
     * handle as index directly with the expense of SRAM.
     */
    prph_info_t prphs[BLE_MAX_CONNECTION];

    // Software Timer for blinking the RED LED
    SoftwareTimer blinkTimer;
    uint8_t connection_num = 0; // for blink pattern

    void setup()
    {
      Serial.begin(115200);
      while ( !Serial ) delay(10);   // for nrf52840 with native usb

      // Initialize blinkTimer for 100 ms and start it
      blinkTimer.begin(100, blink_timer_callback);
      blinkTimer.start();

      Serial.println("Bluefruit52 Central Multi BLEUART Example");
      Serial.println("-----------------------------------------\n");

      // Initialize Bluefruit with max concurrent connections as Peripheral = 0, Central = 4
      // SRAM usage required by SoftDevice will increase with number of connections
      Bluefruit.begin(0, 4);

      // Set Name
      Bluefruit.setName("Bluefruit52 Central");

      // Init peripheral pool
      for (uint8_t idx=0; idx<BLE_MAX_CONNECTION; idx++)
      {
        // Invalid all connection handle
        prphs[idx].conn_handle = BLE_CONN_HANDLE_INVALID;

        // All of BLE Central Uart Serivce
        prphs[idx].bleuart.begin();
        prphs[idx].bleuart.setRxCallback(bleuart_rx_callback);
      }

      // Callbacks for Central
      Bluefruit.Central.setConnectCallback(connect_callback);
      Bluefruit.Central.setDisconnectCallback(disconnect_callback);

      /* Start Central Scanning
       * - Enable auto scan if disconnected
       * - Interval = 100 ms, window = 80 ms
       * - Filter only accept bleuart service in advertising
       * - Don't use active scan (used to retrieve the optional scan response adv packet)
       * - Start(0) = will scan forever since no timeout is given
       */
      Bluefruit.Scanner.setRxCallback(scan_callback);
      Bluefruit.Scanner.restartOnDisconnect(true);
      Bluefruit.Scanner.setInterval(160, 80);       // in units of 0.625 ms
      Bluefruit.Scanner.filterUuid(BLEUART_UUID_SERVICE);
      Bluefruit.Scanner.useActiveScan(false);       // Don't request scan response data
      Bluefruit.Scanner.start(0);                   // 0 = Don't stop scanning after n seconds
    }

    /**
     * Callback invoked when scanner picks up an advertising packet
     * @param report Structural advertising data
     */
    void scan_callback(ble_gap_evt_adv_report_t* report)
    {
      // Since we configure the scanner with filterUuid()
      // Scan callback only invoked for device with bleuart service advertised
      // Connect to the device with bleuart service in advertising packet
      Bluefruit.Central.connect(report);
    }

    /**
     * Callback invoked when an connection is established
     * @param conn_handle
     */
    void connect_callback(uint16_t conn_handle)
    {
      // Find an available ID to use
      int id  = findConnHandle(BLE_CONN_HANDLE_INVALID);

      // Eeek: Exceeded the number of connections !!!
      if ( id < 0 ) return;

      prph_info_t* peer = &prphs[id];
      peer->conn_handle = conn_handle;

      Bluefruit.Connection(conn_handle)->getPeerName(peer->name, sizeof(peer->name)-1);

      Serial.print("Connected to ");
      Serial.println(peer->name);

      Serial.print("Discovering BLE UART service ... ");

      if ( peer->bleuart.discover(conn_handle) )
      {
        Serial.println("Found it");
        Serial.println("Enabling TXD characteristic's CCCD notify bit");
        peer->bleuart.enableTXD();

        Serial.println("Continue scanning for more peripherals");
        Bluefruit.Scanner.start(0);

        Serial.println("Enter some text in the Serial Monitor to send it to all connected peripherals:");
      } else
      {
        Serial.println("Found ... NOTHING!");

        // disconnect since we couldn't find bleuart service
        Bluefruit.disconnect(conn_handle);
      }

      connection_num++;
    }

    /**
     * Callback invoked when a connection is dropped
     * @param conn_handle
     * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
     */
    void disconnect_callback(uint16_t conn_handle, uint8_t reason)
    {
      (void) conn_handle;
      (void) reason;

      connection_num--;

      // Mark the ID as invalid
      int id  = findConnHandle(conn_handle);

      // Non-existant connection, something went wrong, DBG !!!
      if ( id < 0 ) return;

      // Mark conn handle as invalid
      prphs[id].conn_handle = BLE_CONN_HANDLE_INVALID;

      Serial.print(prphs[id].name);
      Serial.println(" disconnected!");
    }

    /**
     * Callback invoked when BLE UART data is received
     * @param uart_svc Reference object to the service where the data
     * arrived.
     */
    void bleuart_rx_callback(BLEClientUart& uart_svc)
    {
      // uart_svc is prphs[conn_handle].bleuart
      uint16_t conn_handle = uart_svc.connHandle();

      int id = findConnHandle(conn_handle);
      prph_info_t* peer = &prphs[id];

      // Print sender's name
      Serial.printf("[From %s]: ", peer->name);

      // Read then forward to all peripherals
      while ( uart_svc.available() )
      {
        // default MTU with an extra byte for string terminator
        char buf[20+1] = { 0 };

        if ( uart_svc.read(buf,sizeof(buf)-1) )
        {
          Serial.println(buf);
          sendAll(buf);
        }
      }
    }

    /**
     * Helper function to send a string to all connected peripherals
     */
    void sendAll(const char* str)
    {
      Serial.print("[Send to All]: ");
      Serial.println(str);

      for(uint8_t id=0; id < BLE_MAX_CONNECTION; id++)
      {
        prph_info_t* peer = &prphs[id];

        if ( peer->bleuart.discovered() )
        {
          peer->bleuart.print(str);
        }
      }
    }

    void loop()
    {
      // First check if we are connected to any peripherals
      if ( Bluefruit.Central.connected() )
      {
        // default MTU with an extra byte for string terminator
        char buf[20+1] = { 0 };

        // Read from HW Serial (normally USB Serial) and send to all peripherals
        if ( Serial.readBytes(buf, sizeof(buf)-1) )
        {
          sendAll(buf);
        }
      }
    }

    /**
     * Find the connection handle in the peripheral array
     * @param conn_handle Connection handle
     * @return array index if found, otherwise -1
     */
    int findConnHandle(uint16_t conn_handle)
    {
      for(int id=0; id<BLE_MAX_CONNECTION; id++)
      {
        if (conn_handle == prphs[id].conn_handle)
        {
          return id;
        }
      }

      return -1;
    }

    /**
     * Software Timer callback is invoked via a built-in FreeRTOS thread with
     * minimal stack size. Therefore it should be as simple as possible. If
     * a periodically heavy task is needed, please use Scheduler.startLoop() to
     * create a dedicated task for it.
     *
     * More information http://www.freertos.org/RTOS-software-timer.html
     */
    void blink_timer_callback(TimerHandle_t xTimerID)
    {
      (void) xTimerID;

      // Period of sequence is 10 times (1 second).
      // RED LED will toggle first 2*n times (on/off) and remain off for the rest of period
      // Where n = number of connection
      static uint8_t count = 0;

      if ( count < 2*connection_num ) digitalToggle(LED_RED);
      if ( count % 2 && digitalRead(LED_RED)) digitalWrite(LED_RED, LOW); // issue #98

      count++;
      if (count >= 10) count = 0;
    }

[GitHub Source code][2]

I want to invoke this disconnect function, but I don't know where to get conn_handle. If anyone has any idea please help me.

I have already tried going into libraries; the best it shows is just the definition of the callback function:

    1: Bluefruit.Central.setDisconnectCallback(disconnect_callback);

    2: void BLECentral::setDisconnectCallback( ble_disconnect_callback_t fp )
       {
         _disconnect_cb = fp;
       }

    3: class BLECentral
       {
         ...
         private:
           ble_disconnect_callback_t _disconnect_cb;
       }

    4: typedef void (*ble_disconnect_callback_t ) (uint16_t conn_hdl, uint8_t reason);

This is all I got regarding this disconnect function in different libraries following the definition but nothing related to conn_handle.

  [1]: https://www.adafruit.com/product/3406
  [2]: https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/libraries/Bluefruit52Lib/examples/Central/central_bleuart/central_bleuart.ino

body:
Idk if its a right or not but it works.

When there's is a new connection established, "connect" gets revoked, with "conn_handle" as its argument. If someone knows please tell how is this function revoke itself.

But what I did is make a global variable `uint16_t conn_handle`

    uint16_t g_conn_handle;
    void connect_callback(uint16_t conn_handle)
        {
          g_conn_handle=conn_handle;
          // Find an available ID to use
          int id  = findConnHandle(BLE_CONN_HANDLE_INVALID);

          // Eeek: Exc
          ...

Now I can call the Disconnect function with this `g_conn_handle` global variable.


message:
Tasks in ESP32: guidelines rather than blink example

I'm using an ESP8266 for IOT devices.

I wish to work with an ESP32 and harvest its benefits - for my uses managing WiFi and MQTT connectivity.

Most tasks examples are *very* basic and quite the same (blinking LEDs). But for a real time application, more data is needed for which I can't find a guide.

For example:
1) when to use `core0` or `core1`?
2) How to evaluate stack size needed for a task?
3) Are there any limitation for a task? Is a `mqtt.loop()`  for example, ligit, memory wise?

I'd be happy to read about real life-implementations for tasks (especially "dos" and "don'ts")

Example usage from [ESP32 DOCS][1]

     // Dimensions the buffer that the task being created will use as its stack.
     // NOTE:  This is the number of bytes the stack will hold, not the number of
     // words as found in vanilla FreeRTOS.
    #define STACK_SIZE 200

     // Structure that will hold the TCB of the task being created.
     StaticTask_t xTaskBuffer;

     // Buffer that the task being created will use as its stack.  Note this is
     // an array of StackType_t variables.  The size of StackType_t is dependent on
     // the RTOS port.
     StackType_t xStack[ STACK_SIZE ];

     // Function that implements the task being created.
     void vTaskCode( void * pvParameters )
     {
         // The parameter value is expected to be 1 as 1 is passed in the
         // pvParameters value in the call to xTaskCreateStatic().
         configASSERT( ( uint32_t ) pvParameters == 1UL );

         for( ;; )
         {
             // Task code goes here.
         }
     }

     // Function that creates a task.
     void vOtherFunction( void )
     {
         TaskHandle_t xHandle = NULL;

         // Create the task without using any dynamic memory allocation.
         xHandle = xTaskCreateStatic(
                       vTaskCode,       // Function that implements the task.
                       "NAME",          // Text name for the task.
                       STACK_SIZE,      // Stack size in bytes, not words.
                       ( void * ) 1,    // Parameter passed into the task.
                       tskIDLE_PRIORITY,// Priority at which the task is created.
                       xStack,          // Array to use as the task's stack.
                       &xTaskBuffer );  // Variable to hold the task's data structure.

         // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
         // been created, and xHandle will be the task's handle.  Use the handle
         // to suspend the task.
         vTaskSuspend( xHandle );
     }

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html

body:
> in a real time application, more data is needed which I can't find a guide for it

That is because there isn't one. The amount of memory needed is completely defined by the application and the task you want to run, so no "guide" can tell you what that will be.

You will have to analyze the actual software you want to run to see what it does and how it works to estimate the likely size of stack needed (note: stack is used for local (non-static) variables as well as storage for registers when calling functions). It's entirely up to you to work it out. The basic assumption (since the SDK is aimed at professional users not hobbyists like typical Arduino users) is that you know what your software is doing since it's you writing that software.

> when to use core0 or core1?

When you need to balance your processing load. Again that's entirely down to your software and how you need it to work. Maybe you have one task that has to have almost exclusive use of a core - in which case you bind everything except that task to the same core, and place that task on its own core. Or maybe you just want to spread the tasks out evenly. It's your choice.

> Are there any limitation for task?

Yes. The chip only has finite memory. You can't give a task more memory than there is. Also be aware that there may be a watchdog monitoring your tasks so you have to be sure to "kick" it regularly and not block too long.


message:
Does avr-libc have any reason to word-align C++ class member variables?

This sounds straightforward enough, but I'm struggling to find a good answer.

Suppose I declare a C++ class with private members that collectively occupy an odd number of bytes. Say...

~~~
class Foo {
private:
    uint8_t bitflags;
    uint32_t millis;
}
~~~

or

~~~
class Foo {
private:
    uint8_t rawData[3];
}
~~~

If I compile it using GCC or Clang (possibly, wrapped inside the Arduino IDE, or multiply-wrapped inside PlatformIO, CMake, and an IDE like CLion), is there any likely scenario where the compiler (when targeting 8-bit AVR... specifically, the ATmega2560 on an Arduino Mega2560) would be inclined to add padding bytes to the portion of the class stored in SRAM? Say... between `bitflags` and `millis`, or between an instance of `Foo` and a `uint64_t` right after it?

If yes, what do I need to use to tell the compiler, "absolutely, positively ***DO NOT*** pad variables in SRAM (and, if you find yourself in a situation where it's seemingly unavoidable, at least output a prominent compile-time warning, if not an outright compilation-stopping error)?

Then... if I do that... are there any negative *consequences* to doing that with code that's targeting (and ultimately running upon) an 8-bit AVR?

As far as I know, 8-bit AVR has *never* had specific opcodes for copying a *pair* of consecutive bytes between registers and SRAM (I think, because Atmel literally ran out of opcode mapping space, and had nowhere to *put* hypothetical new opcodes like, "ldw rz, $f00d"), and `movw` only applied to pairs of *registers*... so, in theory, there's no reason *for* the compiler to "optimize" SRAM access to be word-aligned.

That said... I suppose it's not inconceivable that a compiler might *default* to word-alignment (even on platforms where it doesn't *matter*), just for the sake of ABI consistency between different platforms.

Before someone suggests, "try it and see!"... I've gotten far enough into learning C++ to know that with C++, you ***can't trust*** "compiles without errors and passes unit tests on *my computer*, with *{this} IDE*" as a general-purpose proof-of-correctness for C++ involving "implementation-defined" or "undefined" behavior. AFAIK, padding behavior is "implementation-defined".

body:
GCC has an extension to add attributes to types, which you can use to tell it your alignment requirements.

Additionally it has a `#pragma` to define the alignment, which could be used alternatively.

But as you already suspect, for this 8-bit target there should be no reason to insert padding bytes.

---

So your question boils down to find a method to detect unwanted padding. You can do this in a standard compliant way, which I show below. Yes, it does introduce additional types, one per structure. But it does not generate any unnecessary objects that eat your precious resources.

The "trick" is to use the `sizeof` operator to calculate a valid array size only, if the size of the checked type meets the expectation. If not, a compiler error safely breaks the generation of code. Granted, the error message is misleading an unsuspecting user, so it is really necessary to name the macro and the type accordingly.

This example compiles successfully with a PC as target, but not with an AVR as target. This is intentionally to demonstrate the working, because with an AVR target the type `UP` should have no padding bytes.

```c
#define ASSERT_TYPE_SIZE(Type, size) \
    typedef char Assert##Type##Size[2 * (sizeof(Type) == (size)) - 1]

typedef struct {
    char c;
    long l;
} UP;
ASSERT_TYPE_SIZE(UP, sizeof (long) + sizeof(long));

typedef struct __attribute__((packed)) {
    char c;
    long l;
} P1;
ASSERT_TYPE_SIZE(P1, sizeof (char) + sizeof(long));

#pragma pack(1)
typedef struct {
    char c;
    long l;
} P2;
ASSERT_TYPE_SIZE(P2, sizeof (char) + sizeof(long));
#pragma pack()
```


message:
Use same pin for two purposes

I have only one pin available and I'd need to use it both for a digitalRead and for sending serial messages (assigning it the Tx role within a SoftwareSerial). I can alternate these two operations, but I don't seem to succeed. I could be interested in other pairs as well (digitalRead+Rx, digitalWrite+Tx and digitalWrite+Rx) and I hope that understanding one will solve them all, but for now I'd be happy to get the first one working. My first naive attempt would be something like:

```
 #include <SoftwareSerial.h>

SoftwareSerial swSerial(7,6);
int val;

void setup() {

  pinMode(6, INPUT_PULLUP);

}

void loop() {

  val = digitalRead(6);

  delay(2000);

  swSerial.begin(19200);
  swSerial.print("myData");
  swSerial.end();

  delay(2000);

}
```

But I've made other experiments, for example with a digitalWrite, hoping that combining two forms of output would be feasible, but again no way. I know I can alternate a pin role between output and input as long as common digital read/write operations are involved, but SoftwareSerial appears to be less flexible. It seems to me it refuses to work as soon as the pin is declared/used for common digital purposes. Is there a way to accomplish my goal?

I guess that similar requirements and fixes (make a pin role more flexible) led to the [Software Serial with Half Duplex][1] library, but I'd refrain from adopting it because I feel it is overcomplicated and seems like overkill for my purpose, moreover it doesn't seem actively supported.

To avoid a XY problem, my very initial need (I may have further ones, requiring the different pairs mentioned at the beginning) would be to check whether this pin is floating or connected to something (I can chose between Vcc or Gnd, setting up the pull-up or an external pull-down accordingly) and to send back some information (obviously this is useful if the pin is actually connected, but I have no reason not to send data anyway) alternating the tasks a few times per second at least.

  [1]: https://forum.arduino.cc/t/software-serial-with-half-duplex-for-a-shared-serial-bus/112131

body:
First of all, for using the Software Serial you need to set your tx and rx pins to OUTPUT, that what the library does under the hood.

What you may try to do is to set a millis timer (forget about delay(), never ever use it) and change pin mode to INPUT once every 200ms let's say. And after your measurements put it back to output as soon as you can.

200ms delay is normally ok for some readings like button click. If you can read the value more rare do it (for example you may read some sensor value only once per hour). Here is an example:

        #include <SoftwareSerial.h>

    SoftwareSerial swSerial(7,6);
    int val;

    byte timer = 200; // Read value every 200ms
    uint32_t prevTime = 0;

    void setup() {

     // Don't change pin mode here
     swSerial.begin(19200);

    }

    void loop() {

     if (millis() - prevTime > timer) {
      // you could try swSerial.flush(); here...
      prevTime = millis(); // reset timer
      pinMode(6, INPUT_PULLUP); // changing pin mode and reading value
      val = digitalRead(6);
      pinMode(6, OUTPUT); // changing pin mode back
     }

     swSerial.print("myData");
     // swSerial.end(); // I don't think you need this line;

    }

It may be a solution from a programming point of view. But another task is to organize an electric multiplexing for 2 different devices on the same pin as was mentioned by @the busybee


message:
Methods of programming the Arduino

I took a look at a barebones Arduino schematic.
It had three different ways of programming the chip.
[![enter image description here][1]][1]

The first interface is for programming through SPI (For example with "Pocket AVR Programmer", or "USBTinyISP").

The second interface is for programming through an FTDI to USB module.

What is the third programming interface? It only has `MOSI, MISO and SCK`.

EDIT: This is a picture of the full schematic. Unfortunately, I could not find the link from which I downloaded it. I am sure it was from Github though.

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

  [1]: https://i.stack.imgur.com/0SyYs.png
  [2]: https://i.stack.imgur.com/vhAVD.png

body:
The 2x2 pin JP2 is connected to the Atmel 16U2 or 32U2 processor (whichever the manufacturer used) which provides the USB I/O interface to/from the Atmel 328p, the one we usually consider to be the Uno's processor. When pins are actually installed on that pad, jumpers may be placed across either or both pairs to connect the xxU2's pin-4 to pin-6, and/or pin-5 to pin-7, which connect to that processor's interrupts (numbered the same as those pins).

My searches have not yielded any answer to the question of why it was provided, other than to suggest that they may have been intended for a feature that was never implemented. You can see JP2 and its connections to the xxU2 processor in the center of [this schematic][1].

Update:

I was looking at the 3-pin connector(?) marked '???' in your question, and JP4 on the schematic in your update. Since your schematic does not show the xxU2 chip, and the connections of '???' are marked D11, D12, and D13, I'm going to guess instead that these are either auxilliary pins to access the 328's SPI interface, or is showing half of the ICSP hardware programming interface (the 3x2 pin block just above the '328 on the schematic I linked).

  [1]: https://electrosome.com/wp-content/uploads/2014/07/Arduino-Uno-R3-Schematic-Diagram.jpg


body:
JP2 and JP8 are both serial pin headers suitable for programming -- they connect to the same pins of the chip: RXD, TXD and RST. This is programming via UART: A bootloader software (which has to be "pre-burnt" in the chip's flash memory) is the first thing that is run after a reset (RST) signal. It waits a little moment for data to arrive on RXD. If data arrives, the bootloader goes into programming mode: the data is written to flash memory, making it the firmware to be executed after the next RST. (If no data arrives: well, then the firmware that already is there is executed.)

Programming the chip via JP4 would use "hardware-supported" programming interface via SPI, recognizeable by the pins MISO, MOSI and SCK. That is the only way to get the first bootloader into the flash memory. It also provides you with a way to flash and re-flash a firmware without a pre-burnt bootloader (making the bootloader space available to your firmware). That method is described in [the ATmega328P datasheet, chapter 27.8][1] and is the primary method employed by "ISP programmer boards". You could use those from the Arduino IDE using the menu option "Upload using programmer".

If this "barebone Arduino" circuit is meant to use an ATmega328P with the Arduino bootloader, however, I would assume that JP4 is meant to provide a pin header for some SPI sensor module (even though you could program and even un-brick the chip using this interface).

NB: "FTDI" is a red herring here. One of the most-used ISP programmer boards employs an chip made by FTDI, so you could call this method "programming via FTDI" ... but a specific USB-to-Serial cable using an chip made by FTDI and an 1x5 pin header is also called an "FTDI cable". (For a while, FTDI made the best USB-to-Serial chips. Clones just did not work that reliable. Today, CH340G and CP2104 are reliable enough for hobby projects, but somehow, "FTDI" stuck as a name.)

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf


message:
Provide custom AVR dude commands through the Arduino IDE

Besides the standard upload button that burns the code using FTDI, I want to then be able to provide custom AVRDude commands for burning fuses, when the external programmer is used.

Is this possible to do from the IDE? Maybe if I can edit some configuration files?

The idea is to have the IDE supply the upload command when the standard upload option is selected, but when `external programmer` is selected, i want to have custom behavior.

The custom behavior that I want is to preserve the EEPROM and set the lock bit.

These two actions can be performed with the following AVRDude commands:

    avrdude -c usbtiny -p m328p -U hfuse:w:0xd2:m
    avrdude -c usbtiny -p m328p -U lock:w:0x00:m

The external programmer i use is Sparkfun's "Pocket AVR Programmer" which is an SPI programmer.

So can I have custom behavior (supported by AVRDude) when I select program using external programmer?

EDIT:
I opened file `boards.txt` and i found these specifications of interest:

    pro.name=Arduino Pro or Pro Mini

    pro.upload.tool=avrdude
    pro.upload.protocol=arduino

    pro.bootloader.tool=avrdude
    pro.bootloader.unlock_bits=0x3F
    pro.bootloader.lock_bits=0x0F

    pro.build.board=AVR_PRO
    pro.build.core=arduino
    pro.build.variant=eightanaloginputs

and

    ## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328P
    ## ---------------------------------------------------
    pro.menu.cpu.8MHzatmega328=ATmega328P (3.3V, 8 MHz)

    pro.menu.cpu.8MHzatmega328.upload.maximum_size=30720
    pro.menu.cpu.8MHzatmega328.upload.maximum_data_size=2048
    pro.menu.cpu.8MHzatmega328.upload.speed=57600

    pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
    pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA
    pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0xFD
    pro.menu.cpu.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex

    pro.menu.cpu.8MHzatmega328.build.mcu=atmega328p
    pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L

I am using Arduino Pro Mini.
In the second specification, there is the option for setting the fuse bits I want. However, there is no option for the lock bits.
The option for the lock bits are in the first specification - but there is no option for the fuses.

My new questions are these:
 1. Should I specify the lock bits in the first specs and the fuses in the second? Will this work? I have to ask before trying anything stupid. Will the second specs "inherit" from the first specs?
 2. Will the parameters I insert here only work for the `Upload Using Programmer` option? I want the regular upload (via bootloader) to work normally.
 3. What happens if I ditch the Arduino platform and use a standalone AVR? If I use the same AVR that the Pro Mini platform had. Will the same settings work?

body:
You can add the fuse parameters to the "Upload using programmer" command pattern `tools.avrdude.program.pattern` in platform.txt. Copy them from the `tools.avrdude.erase.pattern`. (The fuse values are from boards.txt)

the modified upload command pattern:
> tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" -Ulock:w:{bootloader.lock_bits}:m


message:
Motor with ultrasonic sensor

I am new to programming so bear with me.
I am writing a simple code to control a motor such that the motor will turn at full speed as long as the sensor does not detect an object within 5" of the sensor. If it does see something at 5 inches or less, then I want  to motor to stop.
My question is this: When using an IF statement, do you have to have the ELSE, or can you simply do two IF statements with no ELSE?

Here is my example:
______________________________________________________________

    int motorpin1 = 10 , motorpin2 = 11;
    int trig = 12;
    int echo = 9;
    float distance;
    float time;

    void setup()
    {
      pinMode (motorpin1, OUTPUT);
      //yellow wire
      pinMode (motorpin2, OUTPUT);
      //blue wire

      pinMode (trig, OUTPUT);
      pinMode (echo, INPUT);
      Serial.begin (9600);

    }

    void loop()
    {
     // setup ultrasonic sensor to control
     //motor
      digitalWrite(trig, LOW);
      delayMicroseconds(2);
      digitalWrite(trig, HIGH);
      delayMicroseconds(10);
      digitalWrite(trig, LOW);
      time = pulseIn(echo, HIGH);
      distance = time/148.1;

      Serial.println(distance);

     if distance <5,digitalWrite (motorpin1, LOW);
     digitalWrite (motorpin2, LOW);

     if distance >=5, digitalWrite (motorpin1, HIGH);
     digitalWrite (motorpin2, LOW);
     delay (1000); //wait for 1 second

_______________________________________________________________

Is there a better way to do this with an ELSE statement? I want to capture the parameter where the code controls the specific parameters of >5  and then <or=5. Also, my next thing is to pause, and reverse the motor if after 1 second, the sensor still sees an object <=5.

Definitely a learning curve for this old brain of mine!

body:
You can do something along the line of

    if (distance < 5) {
        digitalWrite (motorpin1, LOW);
    }
    else {
        digitalWrite (motorpin1, HIGH);
    }

It seems like you only set `motorpin2` to `LOW` and never to `HIGH`. If you don't want to set it `HIGH`, move that line to the `setup()` section. There is no need to keep setting it `LOW`.


message:
ArduinoJSON :: How to determine Array's size in a DOC conatinaing not only Arrays

Parameter file containing MQTT topics as shown below, is read into `StaticJsonDocument<1250> DOC` variable.

Size of some groups may differ between MCU's, for example `sub_topics_win` may contain more topics, if MCU is 8 relay unit. For that I need the flexibility to read a specific topic that can differ in size.

What is the rifht way to do it?

    {
        "pub_gen_topics": [
            "myHome/Messages",
            "myHome/log",
            "myHome/debug"
        ],
        "pub_topics": [
            "myHome/Cont_A/Avail",
            "myHome/Cont_A/State"
        ],
        "sub_topics": [
            "myHome/Cont_A",
            "myHome/All",
            "myHome/lockdown"
        ],
        "sub_topics_win": [
            "myHome/Windows/gFloor/TwinWindow",
            "myHome/Windows/gFloor/Pergola"
        ],
        "sub_topics_SW": [
            "myHome/Light/int/gFloor/SalAmbient1",
            "myHome/Light/int/gFloor/SalAmbient2",
            "myHome/Light/int/gFloor/Lobby",
            "myHome/Light/int/gFloor/Corridor"
        ],
        "sub_topics_win_g": [
            "myHome/Windows",
            "myHome/Windows/gFloor"
        ],
        "sub_topics_SW_g": [
            "myHome/Light",
            "myHome/Light/int",
            "myHome/Light/int/gFloor/"
        ],
        "ver": 0.1
    }

body:
As I understand, your question is *How can I determine the best capacity for a `JsonDocument` when my input varies?*

If that's the case, I recommend that you read [How to determine the capacity of the JsonDocument?](https://arduinojson.org/v6/how-to/determine-the-capacity-of-the-jsondocument). Here is an extract from the section "What if my input varies?":

> If your program must deserialize a JSON document that changes, you must allocate a `JsonDocument` that is large enough for the largest valid input. I insist on the term *valid* because your program doesn't need to support any JSON document, but only the ones relevant to your use case.

Applying this to your problem, you need to put eight topics in each list and pass this document to the [ArduinoJson Assistant](https://arduinojson.org/v6/assistant/), which results in a recommended capacity of 3027 bytes on ESP8266. Now, this is a bit large for a `StaticJsonDocument`, so consider switching to a `DynamicJsonDocument.`


body:
If your question is *How can I read each element of an array when I don't know its size?*, then simply use a for-loop, like so:

```c++
JsonArray sub_topics_win = doc["sub_topics_win"];

for (const char* topic : pub_gen_topics) {
  Serial.println(topic);
}
```

See also: [JsonArray::begin() / end()](https://arduinojson.org/v6/api/jsonarray/begin_end/), [JsonArray::size()](https://arduinojson.org/v6/api/jsonarray/size/).


message:
ATTiny84 I2C with NeoPixels not working

I fetch RGB values via I2C - which works (with a splitting function).

Now I have a problem:
- When I write values directly into strip.color() like strip.Color(255,0,0,0) the NeoPixels turn red when receiving the values.
- When I use the values from the I2C connection it won't work anymore. But the values are correct if I have a look in the Serial Monitor.

Maybe the data type is wrong or something?

```
#include <Wire.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN   4
#define LED_COUNT 4

static const int SLAVE_ADDRESS = 0x08;

uint32_t currentColor;
int currentBrightness = 50;
int flashState = 0;
String ledRed, ledGreen, ledBlue, ledWhite;

String temp;
String payload;

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

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

  strip.begin();
  strip.show(); // Turn off all pixels asap
  strip.setBrightness(50); // Set brightness

  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);

  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(change);
}

// Set all pixels to color
void setPixelColors(uint32_t color) {
  for(int p = 0; p < LED_COUNT; p++) {
    strip.setPixelColor(p, color);
  }
  strip.show();

  delay(1000);
  digitalWrite(3, HIGH);
}

// Split the I2C message
String split(String s, char parser, int index) {
  String rs="";
  int parserIndex = index;
  int parserCnt=0;
  int rFromIndex=0, rToIndex=-1;
  while (index >= parserCnt) {
    rFromIndex = rToIndex+1;
    rToIndex = s.indexOf(parser,rFromIndex);
    if (index == parserCnt) {
      if (rToIndex == 0 || rToIndex == -1) return "";
      return s.substring(rFromIndex,rToIndex);
    } else parserCnt++;
  }
  return rs;
}

void loop() {
  // ...
}

void change(int howMany) {
  digitalWrite(3, LOW);
  temp = "";
  if (Wire.available()) {
    // Fetch the string
    while(Wire.available()) {
      char c = Wire.read();
      temp.concat(c);
    }

    payload = String(temp);
    flashState = split(payload, ',', 0).toInt();
    ledRed = split(payload, ',', 1);
    ledGreen = split(payload, ',', 2);
    ledBlue = split(payload, ',', 3);
    ledWhite = split(payload, ',', 4);

    byte bufRed[3];
    ledRed.toCharArray(bufRed, 3);

    byte bufGreen[3];
    ledGreen.toCharArray(bufGreen, 3);

    byte bufBlue[3];
    ledBlue.toCharArray(bufBlue, 3);

    byte bufWhite[3];
    ledWhite.toCharArray(bufWhite, 3);

    //setPixelColors(strip.Color(255, 0, 255, 0)); // WORKING

    currentColor = strip.Color(bufRed, bufGreen, bufBlue, bufWhite);
    setPixelColors(currentColor); // NOT WORKING
  }

  // Proof the I2C reading is finished
  delay(10);
}
```

I tried different data types, attached a status LED so I know it the I2C connection is working. When I test it with my UNO I get for R=255 G=0 B=255 W=0; like intended.

"Fun fact": On my UNO it works like a charm. It's just the ATTiny85 that won't accept that values(?)

---

New Code:

```
#include <Wire.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN   4
#define LED_COUNT 20

static const int SLAVE_ADDRESS = 0x08;

int currentBrightness = 50;
int flashState = 0;
int ledRed, ledGreen, ledBlue, ledWhite;

volatile bool recvFlag = false;
volatile uint32_t currentColor = 0;
String temp;

String payload;

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

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

  strip.begin();
  strip.show(); // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(change);
}

void setPixelColors(uint32_t color) {
  for (int p = 0; p < LED_COUNT; p++) {
    strip.setPixelColor(p, color);
    strip.show();
  }
}

String split(String s, char parser, int index) {
  String rs = "";
  int parserIndex = index;
  int parserCnt = 0;
  int rFromIndex = 0, rToIndex = -1;
  while (index >= parserCnt) {
    rFromIndex = rToIndex + 1;
    rToIndex = s.indexOf(parser, rFromIndex);
    if (index == parserCnt) {
      if (rToIndex == 0 || rToIndex == -1) return "";
      return s.substring(rFromIndex, rToIndex);
    } else parserCnt++;
  }
  return rs;
}

void loop() {
  if (recvFlag) {
    payload = String(temp);
    flashState = split(payload, ',', 0).toInt();
    ledRed = split(payload, ',', 1).toInt();
    ledGreen = split(payload, ',', 2).toInt();
    ledBlue = split(payload, ',', 3).toInt();
    ledWhite = split(payload, ',', 4).toInt();

    currentColor = strip.Color(ledRed, ledGreen, ledBlue, ledWhite);
    setPixelColors(currentColor);

    recvFlag = false;
  }
}

void change(int howMany) {
  temp = "";
  if (Wire.available()) {
    // Fetch the string
    while (Wire.available()) {
      char c = Wire.read();
      temp.concat(c);
    }

    // Proof the I2C reading is finished
    recvFlag = true;
  }
}
```

body:
Honestly I don't know, why exactly this works on your Uno. You need to know, that the `onReceive` callback function is called from an ISR (Interrupt Service Routine). And inside an ISR you cannot do things, that rely on interrupts to work (like `delay()`), since only one interrupt can run at a time. I'm not sure, how the Neopixel library works in its core, but its probably not a good idea to run the `show()` method inside an ISR. Also generally you don't want to do long things inside an ISR, since it will block all the other interrupt powered functions of your microcontroller (for example I2C, Serial, time keeping via `delay()` or `millis()`...).

Instead the best practice is to only set a flag and then do these things in the main code (aka in `loop()`). So something like this:

    volatile bool recv_flag = false;
    volatile uint32_t current_color = 0;

    void setup(){
        // Initiating everything like you already did in your code
        ...
    }

    void loop(){
        if(recv_flag){
            setPixelColors(currentColor);
            recv_flag = false;
        }
    }
    void change(int howMany) {
      digitalWrite(3, LOW);
      temp = "";
      if (Wire.available()) {
        // Doing all the data parsing like you already did
        ...
        // save current color in global variable
        currentColor = strip.Color(bufRed, bufGreen, bufBlue, bufWhite);
        // set flag
        recv_flag = true;
      }
    }

Note that every variable, that will be written to inside an ISR should be declared as `volatile`. This prevents the compiler from optimizing it out, since it cannot know when the interrupts will happen. So it might think that this variable will never change and just replace it with a literal. The `volatile` keyword prevents that.

---

As mentioned above I'm even wondering, why your code works on the Uno. Though the main difference between the Uno and the Attiny84 is, that the Uno as a full fledged I2C hardware interface, while the Attiny84 only has an USI (Universal Serial interface). So the Uno has most of the I2C communication implemented in hardware, while the Attiny84 needs to run (probably interrupt based) code to do the communication.


message:
Rename cu.usbserial-1410 on macOS

Is it possible to rename, e.g., [cu.usbserial-1410][1] to something else?

I have to connect multiple Arduino's and right now the order is rather important.
Being able to set a fixed name would help a lot.

  [1]: https://stackoverflow.com/questions/8632586/macos-whats-the-difference-between-dev-tty-and-dev-cu

body:
### Proposal:

Instead of trying to convince the PC's OS (be it macOS, Windows, or Linux) to use a fixed name for interfaces that connect specific Arduinos, add a identifying feature to your Arduino application. Then from the PC application ask each connected Arduino for its name to identify it.