text:
Why doesn't my mcp23s17 interrupts work anymore?
I'm using a teensy 4.0 with two mcp23s17 gpio expanders where #1 has 16 buttons wired to it, and #2 has 4 buttons and six rotary encoders. To run everything I'm using majenkos mcp23s17 library. Recently, I refactored my code, and suddenly I'm unable to setup the mcp's to have interrupts working properly.
I've tried to narrow the problem down by commenting out code, and it appears that as soon as I call         gpioExpander.enableInterrupt(pin, CHANGE); in gpioSetup() the problem occurs. In detail, loop() runs fine, but as soon as I press a button, the teensy hangs. Also, to restore the teensy I have to upload the code with the call to gpioExpander.enableInterrupt(pin, CHANGE); commented out in order to have the teensy up and running again.
I've been staring myself blind on the code, and I suspect I'm missing something obvious. Your help is appreciated.
//main.cpp
#include <Arduino.h>

#include "GPIO.h"
#include "MCP23S17.h"

extern MCP23S17 gpioExpander1;
extern MCP23S17 gpioExpander2;

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

void loop() {
    GPIOtest(gpioExpander1, gpioExpander2);
}

//GPIO.h
#ifndef GPIO_H
#define GPIO_H

#include <Arduino.h>

#include "MCP23S17.h"

constexpr uint8_t address = 0;
constexpr uint8_t interruptPin1 = 8;
constexpr uint8_t interruptPin2 = 22;
constexpr uint8_t chipSelectPin1 = 7;
constexpr uint8_t chipSelectPin2 = 21;

void setGPIO1Pins(MCP23S17 &gpioExpander);
void setGPIO2Pins(MCP23S17 &gpioExpander);
void gpioSetup();
void GPIO1interrupt();
void GPIO2interrupt();
void GPIOtest(MCP23S17 &gpioExpander1, MCP23S17 &gpioExpander2);

#endif

//GPIO.cpp
#include "GPIO.h"

#include <Arduino.h>
#include <MCP23S17.h>

volatile bool interruptFlag1 = false;
volatile bool interruptFlag2 = false;

MCP23S17 gpioExpander1(&SPI, chipSelectPin1, address);
MCP23S17 gpioExpander2(&SPI, chipSelectPin2, address);

//  Set all Port Expander pins to desired mode INPUT_PULLUP
//  Set all Port Expander input pins interrupts
void setGPIOPins(MCP23S17& gpioExpander) {
    for (uint8_t pin = 0; pin <= 15; ++pin) {
        gpioExpander.pinMode(pin, INPUT_PULLUP);
        gpioExpander.enableInterrupt(pin, CHANGE);
    }

    // set Port Expander Interrupt configuratons
    gpioExpander.setMirror(true);
    gpioExpander.setInterruptOD(false);
    gpioExpander.setInterruptLevel(LOW);
}

void gpioSetup() {
    gpioExpander1.begin();
    gpioExpander2.begin();
    digitalWrite(chipSelectPin1, HIGH);
    digitalWrite(chipSelectPin2, HIGH);

    pinMode(interruptPin1, INPUT_PULLUP);
    pinMode(interruptPin2, INPUT_PULLUP);

    attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, LOW);
    attachInterrupt(digitalPinToInterrupt(interruptPin2), GPIO2interrupt, LOW);

    setGPIOPins(gpioExpander1);
    setGPIOPins(gpioExpander2);

    // GPIO registers are read to be cleared
    gpioExpander1.getInterruptValue();
    gpioExpander2.getInterruptValue();
}

void GPIO1interrupt() {
    interruptFlag1 = true;
}

void GPIO2interrupt() {
    interruptFlag2 = true;
}

void GPIOtest(MCP23S17& gpioExpander1, MCP23S17& gpioExpander2) {
    if (interruptFlag1 == true) {
        Serial.println("interrupt 1 = true");
        interruptFlag1 = false;
    }

    if (interruptFlag2 == true) {
        Serial.println("interrupt 2 = true");
        interruptFlag2 = false;
    }
}

Short version, try:
attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin2), GPIO2interrupt, FALLING);

FALLING (instead of LOW) being the active ingredient. I'm assuming FALLING is supported. If not you can try synthesizing this with CHANGE and reading the port to see whether or not it is currently LOW.
And then call .getInterruptValue(); to clear the MCP23S17's interrupt condition where you clear the global volatile flags:
void GPIOtest(MCP23S17& gpioExpander1, MCP23S17& gpioExpander2) {
    if (interruptFlag1 == true) {
        Serial.println("interrupt 1 = true");
        interruptFlag1 = false;
        gpioExpander1.getInterruptValue(); // <------
    }

    if (interruptFlag2 == true) {
        Serial.println("interrupt 2 = true");
        interruptFlag2 = false;
        gpioExpander2.getInterruptValue(); // <------
    }
}

Long version:
This a guess, since I'm unable to test. But this is maybe not a bad guess:
You have configured the MCP23S17 device to drive active low on/during an MCP23S17 interrupt condition:
    gpioExpander.setMirror(true);
    gpioExpander.setInterruptOD(false);
    gpioExpander.setInterruptLevel(LOW);

So, were an MCP23S17 interrupt to occur (gpioExpander.enableInterrupt(pin, CHANGE);), the interrupt flag within the MCP23S17 would be set, and INTA/INTB of the MCP23S17 would become active low.
The MCP23S17 datasheet says:

The interrupt condition is cleared after the LSb of the data is
clocked out during a read command of GPIO or INTCAP

You have configured your interrupt pins for interrupting on a LOW level interrupt:
attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, LOW);

So, if I understand this correctly, your Teensy continually re-enter the GPIO#interrupt() functions until something read causes the interrupt condition to be cleared. You are not clearing the interrupt condition inside the ISR, you're setting a flag to do that later in the main line of execution, which is reasonable by itself. One thing I can guess is that had you'd previous had something to clear the interrupt condition inside the interrupt and it is now outside the interrupt, namely your call to .getInterruptValue(), which reads the INTCAP register mentioned above. Or perhaps you'd be using one of the functions that reads a pin/port that would have cleared the interrupt condition. Clearing the global variable alone will not clear the interrupt condition, and so you're going to go right back into ISR which will reassign the global variable.
An AVR will execute a single instruction outside of the ISR before reentering the ISR. So the effect of remaining in the interrupt condition is to make your code slow, potentially very slow. I don't know off the top of my head what the Teensy 4.x core will do in this case. Either way, it would lock up or possibly look locked up.
If you were reading/getting-interrupt-value inside the ISR it would have cleared it and so it would not re-entered the ISR repeatedly. Or rather, it wouldn't do that in definitely (or just for long). It possible that the Teensy is so much faster that it might re-enter a few times until the MCP23S17 got around to acknowledging that the interrupt condition had be cleared. I'm not advocating for this so, so I'll leave it at that.
I believe ultimately what you want is to set a FALLING edge interrupt:
attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, FALLING);

Anyway, with FALLING the initial falling edge of the INTA/INTB line sets the interrupt condition in the Teensy (not MCP23S17) but it is cleared when your ISR executes.  So you will not keep re-entering the ISR. So your ISR will enter once to set the global volatile flag. Later when you pick up on the set value of your global volatile flag(s), you need to call .getInterruptValue() (or otherwise read a pin) to clear the interrupt condition in your MCP23S17 (not Teensy) which will de-assert/raise INTA/INTB, at which point the ISR in the Teensy is ready for to get trigger by another falling edge of INTA/INTB.
It's also probably possible to do this with a LOW-level interrupt, but you'd have keep un-configuring them in the ISR and re-configuring them after you clear the MCP23S17's condition. Not sure that would be recommended. But, I think it's possible.

You've really pinpointed where I went wrong. Your keen eye has helped me in the right direction. Appreciate it a lot!


text:
How to count steps of a stepper motor with AccelStepper?
I want to turn on my motor and count how many total rounds it has until my limit switch is switched on. After that, I want to count rounds counterclockwise until another limit switch is pushed. For this, I'm using AccelStepper and ezButton lib.
Here is my code:
      if ((limitSwitch_XV.getState() == LOW) && (limitSwitch_XE.getState() == LOW) && rightDirectionX) {
        while (1) {
          stepper1.step(-1);
          stageSizeX++;
        }
      }

But here I've got an error which says that I can't use int in step(): 'virtual void AccelStepper::step(long int)' is protected within this context stepper1.step(1);
So how can I count the steps and go step by step to the given direction until I reach the limit switch with AccelStepper?

Why do you need to control every step yourself? You could also set it to a specific speed, and then in a loop call stepper1.run() and also check for the limit switch. As soon as the limit switch is activated you can stop the motor and read out the position. The difference in position between before and after is the number of steps traveled.

can you give me an example for it?

and also how can I change the direction then?

You get that error, because the step() method is protected in the AccelStepper class. It is not meant for calling by the user. AccelStepper instead wants you to state, what kind of movement you want (moving a specific distance/to a specific point/with a specific speed) and then frequently call the AccelStepper.run() method (or AccelStepper.runSpeed()), which will then execute the steps, when it is time to do so based on your planned movement.

If you want to solve your problem you have basically two ways to do this:

With AccelStepper: Set the stepper to run at a specific speed in the correct direction, then in a loop calling stepper1.runSpped() and testing your limitswitch with digitalRead(). So something along the lines of:
  stepper1.setCurrentPosition(0);
  stepper1.setSpeed(20); // Change speed according to your needs, negative values let the motor rotate in the other direction
  while(limitSwitch_XV.getState() == HIGH){ // Assuming, that limit switch is not pressed when HIGH
      stepper1.runSpeed();
  }
  int revolutions = stepper1.currentPosition() / steps_per_revolution;

or without AccelStepper: Depending on your stepper driver you can use a less sophisticated stepper library (like Arduinos Stepper library) or just control the stepper directly with digitalWrite() calls (to the Dir pin and to the Pulse pin). In that case you can do each step yourself, after each checking for the limit switch with digitalRead(). Something along the lines (I assume a stepper driver with dir pin and pulse pin, not one with multiple phase pins):
  digitalWrite(dir_pin, direction); // provide HIGH or LOW here depending on wanted direction
  int pos = 0;
  while(limitSwitch_XV.getState() == HIGH){
      digitalWrite(pulse_pin, HIGH);
      delayMicroseconds(10);
      digitalWrite(pulse_pin, LOW);
      pos++;
      delayMicroseconds(50); // Change this value according to the wanted speed
  }
  int revolutions = pos / steps_per_revolution;

Note, that both code snippets are totally untested and you need to build the surrounding code yourself. They only highlight the principle.

What is here steps_per_revolution?

You wanted to know the number of revolutions until you hit the limit switch. For converting traveled steps to number of revolutions you need the number of steps per revolution. That's a value, that is specific to your motor and driver configuration.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Can i use SCL, SDA pin for I2C
I read this article. In the article, it uses A4 and A5 for I2C. But can I just use SCL and SDA pin directly in the Arduino UNO R3? And do I need a put-up resistor for SCL and SDA pin?

Pins A4/A5 and the SCL/SDA pins are the exact same pins on the Arduino UNO R3. Not just "they perform the same function", but they are physically the same pins. It is one solid piece of metal from one pin to the other.
You don't need pullup resistors on the I2C pins because the Wire library turns on the internal pullups by default. However those internal pullups are about a tenth of the strength that I2C pullups should be, so I would recommend that you do add pullups, certainly for anything more than a couple of inches of wire.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
On Linux Min21, unable to access tools/port (grayed out)
I have dual boot laptop, Windows 11 & Linux Mint 21 (default boot).  when running Arduino IDE 1.8.19 using Linux the port not accessible [from tools/port], but if I boot as windows, I can access the port from the Arduino IDE.
Other applications running in Linux can access the USB drive without issue (eg FreeCAD, PrusaSlicer). Arduino IDE is the only app so far with this USB issue.
"dialout" is in my list of groups
Arduino IDE was installed using apt
If I run lsusb when the nano is connected, i see the following extra entry
Bus 003 Device 009: ID 1a86:7523 QinHeng Electronics CH340 serial converter

On another post it suggested running ls -l /dev/ttyUSB* and ls -l /dev/ttyACM*. For both I get the response "No such file or directory". The following files starting with tty* are in the /dev directory
tty    tty11  tty15  tty19  tty22  tty26  tty3   tty33  tty37  tty40  tty44  tty48  tty51  tty55  tty59  tty62  tty9       ttyS10  ttyS14  ttyS18  ttyS21  ttyS25  ttyS29  ttyS4  ttyS8
tty0   tty12  tty16  tty2   tty23  tty27  tty30  tty34  tty38  tty41  tty45  tty49  tty52  tty56  tty6   tty63  ttyprintk  ttyS11  ttyS15  ttyS19  ttyS22  ttyS26  ttyS3   ttyS5  ttyS9
tty1   tty13  tty17  tty20  tty24  tty28  tty31  tty35  tty39  tty42  tty46  tty5   tty53  tty57  tty60  tty7   ttyS0      ttyS12  ttyS16  ttyS2   ttyS23  ttyS27  ttyS30  ttyS6
tty10  tty14  tty18  tty21  tty25  tty29  tty32  tty36  tty4   tty43  tty47  tty50  tty54  tty58  tty61  tty8   ttyS1      ttyS13  ttyS17  ttyS20  ttyS24  ttyS28  ttyS31  ttyS7

If I tail the system log and plug the nano into the usb drive I get the following (the answer my be here but I cant see it).
Oct  7 17:17:14 HP-Envyl kernel: [ 8949.381626] usb 3-4: new full-speed USB device number 14 using xhci_hcd
Oct  7 17:17:14 HP-Envyl kernel: [ 8949.599105] usb 3-4: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64
Oct  7 17:17:14 HP-Envyl kernel: [ 8949.599107] usb 3-4: New USB device strings: Mfr=0, Product=2, SerialNumber=0
Oct  7 17:17:14 HP-Envyl kernel: [ 8949.599108] usb 3-4: Product: USB Serial
Oct  7 17:17:14 HP-Envyl kernel: [ 8949.601365] ch341 3-4:1.0: ch341-uart converter detected
Oct  7 17:17:14 HP-Envyl mtp-probe: checking bus 3, device 14: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-4"
Oct  7 17:17:14 HP-Envyl mtp-probe: bus: 3, device: 14 was not an MTP device
Oct  7 17:17:14 HP-Envyl kernel: [ 8949.601888] usb 3-4: ch341-uart converter now attached to ttyUSB0
Oct  7 17:17:14 HP-Envyl systemd[1]: Starting Braille Device Support...
Oct  7 17:17:14 HP-Envyl brltty[12613]: BRLTTY 6.4 rev BRLTTY-6.4 [https://brltty.app/]
Oct  7 17:17:14 HP-Envyl brltty[12613]: BRLTTY 6.4 rev BRLTTY-6.4 [https://brltty.app/]
Oct  7 17:17:14 HP-Envyl brltty[12613]: executing as the invoking user: root
Oct  7 17:17:14 HP-Envyl brltty[12613]: brltty: executing as the invoking user: root
Oct  7 17:17:14 HP-Envyl mtp-probe: checking bus 3, device 14: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-4"
Oct  7 17:17:14 HP-Envyl mtp-probe: bus: 3, device: 14 was not an MTP device
Oct  7 17:17:14 HP-Envyl brltty[12613]: CLDR open error: No such file or directory: /usr/share/unicode/cldr/common/annotations/en.xml
Oct  7 17:17:14 HP-Envyl brltty[12613]: brltty: CLDR open error: No such file or directory: /usr/share/unicode/cldr/common/annotations/en.xml
Oct  7 17:17:14 HP-Envyl brltty[12613]: brltty: possible cause: the package that defines the CLDR annotations directory is not installed
Oct  7 17:17:14 HP-Envyl brltty[12613]: brltty: emoji substitutiion won't be performed
Oct  7 17:17:14 HP-Envyl brltty[12613]: brltty: BrlAPI Server: release 0.8.3
Oct  7 17:17:14 HP-Envyl brltty[12613]: possible cause: the package that defines the CLDR annotations directory is not installed
Oct  7 17:17:14 HP-Envyl systemd[1]: Started Braille Device Support.
Oct  7 17:17:14 HP-Envyl brltty[12613]: emoji substitutiion won't be performed
Oct  7 17:17:14 HP-Envyl brltty[12613]: BrlAPI Server: release 0.8.3
Oct  7 17:17:14 HP-Envyl brltty[12613]: Linux Screen Driver:
Oct  7 17:17:14 HP-Envyl brltty[12613]: brltty: Linux Screen Driver:
Oct  7 17:17:14 HP-Envyl kernel: [ 8950.123164] input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input49
Oct  7 17:17:15 HP-Envyl brltty[12613]: USB configuration set error 16: Device or resource busy
Oct  7 17:17:15 HP-Envyl brltty[12613]: brltty: USB configuration set error 16: Device or resource busy
Oct  7 17:17:15 HP-Envyl brltty[12613]: USB interface in use: 0 (ch341)
Oct  7 17:17:15 HP-Envyl brltty[12613]: brltty: USB interface in use: 0 (ch341)
Oct  7 17:17:15 HP-Envyl ModemManager[1013]: <info>  [base-manager] port ttyUSB0 released by device '/sys/devices/pci0000:00/0000:00:14.0/usb3/3-4'
Oct  7 17:17:15 HP-Envyl ModemManager[1013]: <info>  [base-manager] couldn't check support for device '/sys/devices/pci0000:00/0000:00:14.0/usb3/3-4': Operation was cancelled
Oct  7 17:17:15 HP-Envyl kernel: [ 8950.239032] usb 3-4: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
Oct  7 17:17:15 HP-Envyl kernel: [ 8950.239683] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
Oct  7 17:17:15 HP-Envyl kernel: [ 8950.239693] ch341 3-4:1.0: device disconnected
Oct  7 17:17:15 HP-Envyl brltty[12613]: NoSpeech Speech Driver:
Oct  7 17:17:15 HP-Envyl brltty[12613]: brltty: NoSpeech Speech Driver:
Oct  7 17:17:18 HP-Envyl rtkit-daemon[3252]: Supervising 10 threads of 3 processes of 1 users.

Does anyone have any idea what can cause this issue?

Do you use brltty?

Uninstall brlttyfor a start.

OK, i can close this. brtty was the problem. I disabled it (found instructions below on another post)
systemctl stop brltty-udev.service
sudo systemctl mask brltty-udev.service
systemctl stop brltty.service
systemctl disable brltty.service

After logout and login, it works now.
Thanks for the help. I did not have this issue on Mint 20, so i am guessing that brtty was automatic in Mint 21

In a couple of days you'll be able to "accept" your own post. Unless a different one shows up that you like better, you probably should.


text:
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.

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.

Please don't post images of code.  Just copy and post your code into the editor, and then format it as a code sample.

@sempaiscuba the code is not the important part of the image... The console output is.

add the console output as text, not a picture

use a switch or a jumper to enable the keyboard code

You have nothing connected to the board at all except the computer?

This board is a tricky one, because the bootloader cannot be protected. -- As you describe it, you do everything correctly. After starting the upload, the board needs to be connected, so that its software starts. Commonly you disconnect the board before starting the upload. If the bootloader is present, it waits for 5 seconds for the uploader of the PC, before it launches the user application. -- Anyway, if the uploader does not connect to your board, the bootloader might be overwritten. -- Did you try to remove the device in the Hardware Manager? Windows might get into the way.

@timemage, yes, that's correct. Nothing is connected to the board, except the computer on the USB connection.

@thebusybee, Yes, I tried to remove the device in the Hardware Manager, but when I reconnect it, it shows up again. I also tried to replace the driver using Zadig (to libusb-win32) and now Windows doesn't detect it as a keyboard as before... but I still can't write a new sketch to it.

Well, then I'll assume that you lost the bootloader. There are multiple resources in the web that describe how to flash the bootloader. You should prefer the instructions of the manufacturer or similar serious site. Or buy a new device.

Yeah, I could just buy a new one, upload a new sketch and being locked outside again, the same way I am now... That's not sustainable, It should not be impossible to upload a new program multiple times. That's what this question is about: How to fix this specific board and how to prevent from being locked out again.

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.

Hello. Could you please add more details to this answer? What is USBasp? AVRDUDESS? Which "programmer" are you talking about? Is it a separated device?

I added some details to my response. Yes, USBasp is a separate device, a programmer typically implemented with an Atmel AVR controller. You can easily buy them from Ebay or someplace else. AVRDUDESS is a GUI tool to help you flash the compiled binary into the target controller, i.e., the attiny85 in this case.

You can learn a lot from Have I bricked my Arduino Uno? Problems with uploading to board


text:
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
}

how many sensors do you have?

Why do you want to use BCD? Binary values are much simpler to handle for any processor (and have a wider range).

@thebusybee the benefit lies in the smaller package that has to be transmitted via Lora. There are strict limits here

I don't grasp what you mean by "smaller package". Binary values are as small as BCD, and have a wider range at the same time. Some might say that binary values are even smaller than BCD, but this is only true if you can use arbitrary bit numbers. For example, a value range of 0000 to 9999 needs 16 bits in BCD, but only 14 bits as binary value. -- However, you accepted an answer that uses binary values.

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.

like this?
int payload = int(65536.0 * (humidity / 100.0));
message[1] = highByte(payload);
message[2] = lowByte(payload);

@TomBaires Something like that, I updated my answer

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 %10);
uint8_t bcdTemperature2 = uint8_t((temperature2/10) <<4) | (temperature2 %10);

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


text:
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:

Using another arduino to check the usb, and it worked. So no problem with usb cable.
Resetting the arduino (double tap the reset-button)
Inserting deleting and updating the drivers from the device manager
Deleting the drivers, and then inserting the arduino while pressing the reset button.
Connecting the arduino to a different pc and it still doesn't work.
I followed everything listed here. (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.
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:

In my device manager, i see the following:

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

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 post, but not necessairily the same.

the upload copies the bin to that drive. did you try the Upload? and double reset should activate the bootloader which should create a port.

I tried both double pressing the reset botton (a red light is not blinking, if it should) and uploading blink.ino. Nothing worked

please post the message text, not a picture of message text

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.

I upload the Blink.ino.elf.uf2 from arduino help (https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-01-technical-reference?_gl=1iu9w36_gaODM4NTQ0ODcuMTY1Nzc4MTAyNA.._ga_NEXN8H46L5*MTY2MTQxODM1NC41OS4xLjE2NjE0MTg0ODIuNjAuMC4w#board-not-detected), and still nothing happens. The arduino does not blink as it should, nor is there a COM port in the ide and device manager. Also, how can i manually create .UF2 files from the ide? (I got just a bin file from the option " Export compiled binary")

You create .UF2 files when you hit the compile ("verify") button in the IDE. You just have to find them - it's not always obvious. Check the verbose output for hints. Do you have a link between REC and GND to always force the bootloader? If so, remove it.

It seems the IDE has a problem creating uf2 files. Actually, i have 2 arduino rp2040. One that works and one that doesn't. If I connect the problematic one, or i compile the programm without any rp connected,  the IDE doesn't create a UF2 file. If i have the working one connected, it still doesn't create uf2 files until i press upload from the IDE. I tried using that uf2 file, but still the problem wasn't fixed.

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


text:
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:

The side that connects to the Arduino has four pins, VCC, GND, TX, and RX, but out of those pins, only two are data pins.
However, if we look at the MAX485 module:

The Arduino side has four pins as well, DI, DE, RE, and 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 and RX on the module as arguments.
How can I translate this code for the MAX485? How should the pinout be?
EDIT: I find it funny that I won the "notable question badge (question with 2500 views)"... And then I look and it has a -1 rating. lol

Your edit has extended the question to the point where the answer I gave no longer applies.

@timemage I am very sorry. I didn't know that it would come down to this... Sorry for your wasted time... And thank you for taking the time to answer as well.

@user1584421, I did a 'rollback'. please ask a new question for the ModbusServer library problem

It's not a waste exactly, but it creates complications when the question is updated to that degree when it has an answer. I wasn't about to roll back your question myself to bring them back to consistent and I wasn't prepared to update it to address the new question and to stop addressing all of the old stuff you'd integrated into the new question.

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:
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.

Thank you very much! With your help, i understood how the module works. However, I get a 226 error, which means timeout. I have the question updated with the code. If you happen to know what is going on.... You can omit the relatively large if statement, since it is not being executed. The code is quite small.

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.

this was all in a now deleted answer by timemage. OP needs a solution with the ModbusMaster library

Thank you but as Juraj said, i know this information at the time you wrote the answer. This has already been implemented, i am now getting a timeout error.

@Juraj I never saw timemage's answer. And from the comment I cannot conclude what was its contents. -- The question does not mention an issue with the library, but with the connections.

@user1584421 PLEASE edit your question if the issue you describe in the prose is cleared. Or better delete the question, and post a new one with the actual question.

In the bottom of the question, it has all the connections listed... Perhaps i should change the title of the question?

I did a 'rollback' of the question and undeleted timemage's answer

@user1584421 This is not a forum. If your question is answered in one way or the other, mark the best answer, or comment asking for clarification, for example. If you have a new issue, post a new question. You might want to take the [tour].

@Juraj Thank you very much! Now it is much better.

just a small note. user1584421 is a member for 8 years and has more than 1300 rep points from more than 50 questions and 6 answers


text:
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?

It's better to not think of the pullup resistor as part of the input (even though physically it is inside the chip) but instead think of it as part of the button circuitry. Thus if you're not using a button then the button circuitry doesn't exist, and that includes the pullup resistor.

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().


text:
Adding Serial2 ends up blocking nano rp2040
Background Info
I want to have two serials in my arduino nano rp2040 connect, in order to be able to communicate using the following scheme. (μC is a microcontroller).
μC1 <--> μC2 <--> μC3<-->....<-->μCn
So i tried changing the core and upload a sketch to test if it is possible. However, i ended up blocking the arduino, and

it disappears from the COM port,
the arduino red light is constantly blinking,
the serial port of my computer freezes,
the whole arduino application is not responding.
The arduino disappears from the device manager and it ends up as a USB device.

I want to understand what causes it, in order to avoid doing it in the future.
I usually reset the board, and then i upload a Blink.ino.elf.uf2 i have previously compiled. The application gets unstuck, the arduino runs the blink programm, and it appears at COM4.
Changes i made to the core:
1st change
In
C:\Users\<user>\AppData\Local\Arduino15\packages\arduino\hardware\mbed_nano\3.2.0\variants\NANO_RP2040_CONNECT

i changed the defines.txt and i changed the line:
-DDEVICE_SERIAL=1

to
-DDEVICE_SERIAL=2

2nd change
In the same folder, i changed pins_arduino.h in the following way:
// Serial
#define PIN_SERIAL_RX (0ul)
#define PIN_SERIAL_TX (1ul)

#define PIN_SERIAL2_RX (3ul)
#define PIN_SERIAL2_TX (4ul)

and
#define SERIAL_HOWMANY      2
#define SERIAL1_TX          (digitalPinToPinName(PIN_SERIAL_TX))
#define SERIAL1_RX          (digitalPinToPinName(PIN_SERIAL_RX))
#define SERIAL2_TX          (digitalPinToPinName(PIN_SERIAL2_TX))
#define SERIAL2_RX          (digitalPinToPinName(PIN_SERIAL2_RX))

My programm:
#define led LED_BUILTIN
char c;

void setup() {
  pinMode(led, OUTPUT);
  // put your setup code here, to run once:
  Serial.begin(9600);
  while(!Serial);
  digitalWrite(led,HIGH);
  delay(1000);
  digitalWrite(led,LOW);

  Serial2.begin(9600);
  while(!Serial2);
  digitalWrite(led,HIGH);
  delay(1000);
  digitalWrite(led,LOW);

}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() ){
    c = Serial.read();
    if (c != '\n'){
      Serial.print("Master wrote : ");
      Serial.println(c);
      Serial2.print(c);
    }
  }

  if (Serial2.available() ){
    c = Serial2.read();
    if (c != '\n'){
      Serial.print("Slave wrote : ");
      Serial.println(c);
    }
  }
delay(1000);
}

Edit I uploaded the same sketch with earlephilhower's core (you can find it here ) and the IDE showed this message:
Resetting COM4
Converting to uf2, output size: 136192, start address: 0x2000
Flashing D: (RPI-RP2)
Wrote 136192 bytes to D:/NEW.UF2
Board at COM4 is not available
Board at COM4 is not available

The last 2 messages were from me trying to open serial monitor. So i think the sketch has the problem, and not the modiffications i made to the mbed os core.

RP2040 has 2 UART peripherals. the datasheet has which pin can be used with which UART and in what direction. note that the datasheet has RP2040 pin numbering not the Nano pin numbering

I even used the phillower core without modifying anything, and i still faced the same problem. Also, the pinout or arduino rp2040 connect has one uart, so i do not know how to access the second uart that the rp2040 CPU has. From a link you sent me to another question, i understood that the second uart may not be accesible.


text:
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?

the 'problem with Strings' is a problem with new hidden in String class. your use of new is not hidden

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];

By now I was already convinced it's something so obvious sigh
A simple delete[] readMessage; after the MQTT publish of the "str" variable did the trick!
Even if I went a different path so actually solve the problem, you gave the actual hint that guided me there, so I'll mark your answer as accepted.
Thank you very much!

You are welcome ... however, take in mind that a new and delete is not needed in this case, as the data only lives within one function. Typically new / delete is used when the life span of data is higher than one function, or when the amount of data is not known beforehand/varies.

True that - I will definitely take it into account when I will be implementing parts of this sketch to the final code!


text:
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.

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).

Thank you! I'd put a 1k resistor before ground and thought that would be enough, I've now put 10k resistors on the outputs and it works great.


text:
Arduino lagging or buggy with delays and serial print?
I got a strange issue with my Arduino Leonardo (clone). It seems to be laggy or buggy, I don't know what the issue is.
I get issues when I use "long" delays.
Below sketch is working fine.
void setup() {
 Serial.begin(9600);
}

void loop() {
  delay(1000);
  Serial.println("Hello World 1000"); // added delay to line for debugging
}

When I use delay(2000) it still is fine. But when I try delay(3000) the serial monitor doesn't output anything (or just 1 line). When I lower the delay to like 2500, it gets better. But not without issues. Sometime it will just skip one iteration, see log below.
11:33:06.328 -> Hello World 2500
11:33:11.331 -> Hello World 2500
11:33:13.909 -> Hello World 2500
11:33:18.815 -> Hello World 2500
11:33:21.395 -> Hello World 2500
11:33:23.815 -> Hello World 2500
11:33:26.392 -> Hello World 2500

What might the issue be?
EDIT:

when I do 3x delay(1000) I get same (weird) results. With 2 times, it does work ok.

The logs are from the serial monitor from the Arduino IDE

I added below line in the setup, it does print the line just once.
while (!Serial) {}
Serial.println("setup()");

Important note: I think it might have to do more with the serial communication than with the Arduino itself. I tested the same things on another computer (Windows 10), and then I just get the expected results. I am using Manajaro Linux as the main machine.
When the output to the serial port is "lagging" so the printing of the line is missed/skipped, I see the RX and TX led on the Arduino light up for a while. Then when they go out, the serial monitor sometimes outputs 2 lines at once.

What happens if you do multiple delay(1000); in sequence between println()?

Is the log directly from the Serial Monitor? Or do you use any other communication channel?

Include a Serial.println("setup()"); or something similar in setup() so that the sample output makes clear whether or not setup() is being executed more than once.

Thanks for the help. I edited my post and added answers and more information.

Given the problem occurs with Manajaro Linux and not Windows 10, wouldn’t that indicate that the problem might be OS or IDE related,  not Arduino? What happens if you connect a terminal emulator to the USB port rather than the Arduino IDE (i.e., the USB port that has the Leonardo with the sketch running connected)?

@RowanP how would I do that?

Re “how would I do that?”: stty -F /dev/ttyACM0 raw 9600 && cat /dev/ttyACM0

Or use any dedicated terminal emulator like "PuTTY", available for Windows and Linux.

@EdgarBonet just tried your commands. I see output, but with the same "laggy" result as in the Arduino IDE. The RX is also blinking heavily, TX is blinking far less.

I tried your code, with 3 s delay, an Arduino Micro, an Ubuntu host, and the commands I showed. I see no laggy behavior. Maybe another process is accessing the serial port? You can check with sudo fuser -v /dev/ttyACM0

"I am using Manajaro Linux as the main machine" Had your problem with Manjaro here to my surprise. Tested different AVR cores, different terminals, same problem. Observed that RX was blinking for no reason. Problem disappeared while trying to inspect USB traffic with wireshark. Have not been able to replicate problem since. Noticed an external 3.0 hub wasn't working. System out of date. Updated, rebooted, still can't recreate the problem. Also observed that sending traffic would prompt inbound data (even with no code to read on Arduino). Add counter to code. Counts were skipped.

@timemage Good point. I don't expect RX to blink without reason. So something is/was using the same port, perhaps some misguided getty?

@thebusybee: ModemManager seems to be a common offender.

@EdgarBonet what is ModemManager? I seem to have it installed it too... Does it interfere with the serial monitor? How did you come across it?

ModemManager gets mentioned a lot in discussions about serial port problems on Linux. The Arduino IDE comes with a script called arduino-linux-setup.sh which, among other things, uninstalls ModemManager.

Another culprit for this sort of problem is Cura, however neither of this were in play during my own my prior comment. ModemManager is one of the first things to go on a Linux machine of anyone regularly using Arduino. I specially looked to see verify that Cura was not running. Modem manager attempts to identify the "modem" when the device enumerates. It does not continually attempt to send to the board. Its direct effects on the connection are limited to moments following bus enumeration.

I will test it all out and report back here. Good suggestions!

I tried uninstalled ModemManager, it messed up my system. I couldn't connect to internet anymore. WiFi and Bluetooth tray icons and applications were gone. Took me a while to fix it, since WiFi is the only way to connect with this machine. After uninstalling it though, I checked if the issue was fixed, unfortunately it was not. I also checked with fuser command. When the serial monitor of the Arduino IDE is closed, it returns nothing. When it is open it returns the following: sudo fuser -v /dev/ttyACM0 /dev/ttyACM0:        root       9775 F.... java


text:
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.

The processor for a home made Arduino is an ATMEGA328P. Note the P at the end or you may encounter invalid signature errors when programming it. There is an unfortunate terminology problem with "burn bootloader" in the Arduino IDE. You need to use "burn bootloader" to set the processor fuses even if you don't want a bootloader. Finally, check the stock level of the ATmega328P at Digikey in advance to avoid disappointment.

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.
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.

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:

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

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.


text:
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  tohttps://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 ?

maybe uninstall the library. https://github.com/lorol/LITTLEFS#readme

@Juraj now after downgade back to 1.0.4 (still in new repository) it cant find $PATH for python.....

@Juraj see pic below

you have 2.0.4, not 1.0.4

@Juraj I'm trying to understand what have change between 1.0.4 to 2.0.4

@Juraj Thank you, problem solved

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 ) 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

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


text:
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:

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

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

don't pay attention to lights ... examine the transmitted data and examine the received data ... if the data is the same, then your devices are operational

why did you delete your previous question and added this one? ... the two are almost the same ... if you want to make changes then edit your question instead

you are making things difficult for yourself ... add debugging code, so that you know what is being transmitted, what is being received, and how the received data is being decoded

How do you connect your nRF2401 and Arduino Nano? A circuit diagram would help to confirm whether the connection is correct or not as the first step of debugging.

@hcheung
I added the information you asked for to my question.

The wiring looks good. So your question is related to why RX not light-up or you can't receive the data? The RX is not light-up because the TX/RX pins are related to Serial port, has nothing to do with the communication between Arduino and nRF24L21 is via SPI, not via Serial port. TX light-up because you had Serial.print(). If you question is not receiving data (not receive correctly), add Serial.println(data) before if (data[0]>131){` to find out what have been received.

@hcheung
Yes, I can't receive data; I mean I receive the position of the joystick and then I can't receive it after I move the joystick multiple times; I mean the serial monitor does not show me the current position of the joystick.
SO I can't loop what I achieved. To solve this I should reopen the serial monitor and again after a while I receive nothing (because I moved the joystick multiple times) and then again I should close the serial monitor and open it again to receive data.

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, 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, 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.

I used this video for coding.
https://youtu.be/fbR_j3y_TC4?t=245

@dagh You also could try and use some of the code here: https://www.deviceplus.com/arduino/nrf24l01-rf-module-tutorial/ -- especially the RF24 configuration (l.50..72) and failure detection and reinitialization (l.91..105). That might give you additional insight.


text:
String of raw data to Char Hex Array for Bitmap
I'm trying to transfer a monochrome ~4kb image file over WebBT to an ESP32 via BLE.
The EPD display looks for an unsigned char array to represent a bitmap. So..it should be in the format of something like
`const unsigned char epd_bitmap_123_1 [] PROGMEM = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};`

I've been successfully able to chunk, serialize, and reassemble an ArrayBuffer of the image from JS to the mcu in C++ (as a String).
I can verify that printing the Hex String on the board is the same as what's given from JS.
However, the image does not display properly on my EPD.
    class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
     //String value of raw data from JS ArrayBuffer..I can only get data as String with BLECharacteristic...
     std::string value = pCharacteristic->getValue();

     //Converting of String above into a Hex String
     string s2;
     stringstream ss;
     for (const auto &item : total) {
       ss << hex << int(item);
     }
     s2 = ss.str();

     //Converting Hex String into Char Array for EPD
     char * const cstr2 = new char [s2.length()+1];
     std::strcpy (cstr2, s2.c_str());

     //Displaying final Char array on EPD
     display.clearBuffer();
     display.drawBitmap(0,0,(unsigned char *)cstr2,296,128,EPD_BLACK);
     display.display();
};

Any idea what's going wrong here? I'm thinking it's something with encoding.

The display doesn't want a hex string. It wants pure binary data. the 0xff and similar are only the human representation in the code. It corresponds to the binary representation 0b11111111.

So the display works when passing something like const unsigned char epd_bitmap_123_1 [] PROGMEM = {     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
I was hoping //Converting Hex String into Char Array for EPD      char * const cstr2 = new char [s2.length()+1];      std::strcpy (cstr2, s2.c_str()); would result in something of that format, but it does not appear to be working correctly.

EPD expects monochrome bitmap. So I get this is just array of bits representing either black or white.
Official doc says its expects a byte[] http://adafruit.github.io/Adafruit-GFX-Library/html/class_adafruit___g_f_x.html#a805a15f1b3ea9eff5d1666b8e6db1c56
So I guess my confusion is how a const unsigned char [] can be a byte[].
Regardless..how can I then convert anything I have (original string version of raw data, or subsequent converted Hex string) into said Byte array?
Thanks!

There are a couple of misunderstanding of the fundamental C++/Arduino programming concepts, 1)epd_bitmap_123_1 [] is not a string (a string is an array of unsigned char terminated by a \0 in C++), it is an array of unsigned char (a.k.a. uint8_t in C++, or byte in Arduino). 2) When passing in an array to a function as an argument, C++ automatically pass in the pointer of the array, so there is no need to cast it with (unsigned char *).

If the Adafruit_GFX::drawBitmap() is expecting a const uint8_t bitmap[], it would be easier that you just declare your epd_bitmap_123_1 [] as const uint8_t epd_bitmap_123_1 [] PROGMEM so that no casting is required.

Great, thanks for the clarification, I understand it wants a Byte array now. The problem is that I'm sending over an ArrayBuffer of bytes, but my BLE callback can only obtain a string representation of this. Printing out this string representation yields bunch of weird chars (mostly backwards '?')...
So..converting that string to a Hex string does in fact get the same bytes that were present from the JS array buffer. How to then convert this hex string into a byte array?

Note: The converted hex string I get would just be in format of "FFFF", as opposed to, "0xFF, 0xFF".


text:
Arduino Uno USB 5 V and external power supply 12 V overheating
I have a issue with my Arduino Uno r3.
I'm not sure why is that happening but I have a 5 V, 18 A power supply to power my LEDs. I connected 5 V from the Arduino to 5 V from the external power supply and I plugged this combined cable to my LEDs. I did the same with GND. On data pin 6 I used a 220 Ω resistor. Also I am using a 12 V power supply to power my Arduino.
At the same time the USB was plugged in.
In and between USB and power some chip is getting hot. I got scared and unplugged the whole Arduino. I am not sure how I should plug this in. It worked fine until I plugged in the external power supply and I was using few LEDs at the time.
This is what it looked like in more understandable way.

Please point out to me what I did wrong.

If you a separate 5V 18A power supply for supplying to the LED, then there is no need for the 12V power supply as you already connect the power supply to the 5V pin of the Arduino board as per your drawing.

Rule #1: A Power Supply the Arduino is NOT!

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.

yes, as the other people say. I'm an electronician , your power supply 5V 18 Amperes , it's to dangerous to connect that to your arduino, the board is not creating to support a great power, if someone of your outputs receives all this unlimited power P = U × I = 5 × 18 = 90 Watts,  your board is just able to smell a awful odour. yes, your board burnst with thi great possible intensity. 1. Connect all the several ground together and for supply the arduino take on the USB header
.
2. connect your power supply directly on the leds board.
warning test that,  but it is possible that your board working not more, see all the led of your board and detect step by step if it works normally...


text:
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!

Google something like "C++ ternary operator". There are many good explanations for that operator online

It could probably have been shortened to this instead:
digitalWrite(enable_pin, ! enable_active_state ) ;

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
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:
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.


text:
How to use the M117 temperature sensor from mysentech?
Anyone can help me decode the temperature of the M117 chip from mysentech.com?
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.

    // 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: %04x (%d) | Raw 2's complement  %04x (%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:
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: %02x", data[1]);
    Wire.write(data[0]); log("Command byte 1: %02x", 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: %02x %02x %02x", r, data[0], data[1], data[2]);
            const byte crc = MY_CRC8(data, 2);
            if (crc != data[2]) {
                warn("CRC mismatch: computed: %02x != read: %02x", crc, data[2]);
            }
            else {
                success("CRC matched: computed: %02x == read: %02x", 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: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C",
                raw, raw,
                c2Raw, c2Raw,
                temperature
            );
            #endif

        #if LOG_LEVEL >= LOG_LEVEL_DEBUG
        log("raw: %04x (%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;
}

don't think 0xFFFF, which becomes 1 once 2's complemented ... instead think 0xFFFF, is 1111111111111111.  I'm not reading any zeros

Not saying that FFFF is 1, but  that two complement of FFFf becomes 1. The raw value is the 2 complement of the 16-bit we read.

Ok, I found something weird. My code do work if I request the sensor every 4 seconds at max. But if the frequency is below that, it won't work.
Will replace the sensor, rolling back to TMP112, as before.

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):
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:
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.
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.

Thanks for the answer. Unfortunately, I had already tried CC44, but I made some adjustments according your input to my code but this still gives 0xFFFF raw value. The CRC I got is 0xAC (I did not yet checked it is ok though). Regarding the data sheet, I had already translated it from the Chinese. I'm gonna work with the STM version thy give on the site.

I modified some old CRC8 code I had for the generator polynomial and initial values the datasheet specifies (0x31 and 0xFF respectively) and it confirms that 0xAC is the correct CRC for 0xFFFF. Also verified their 0xBEEF, 0x92 example CRC.  So you getting a well formed  inbound I2C read. If I have cause to edit some of this may make its way into the answer.

I confirm that AC is the right CRC for FFFF. Current prog code seems now correct but still no result beyond the FFFF (I am going to update the question accordingly-. Could it be the result of something's wrong in the wiring of our custom PCB?

Since you're getting a correct CRC an I2C wiring problem seems unlikely to me. If there is such a problem, then it's not likely the sort of problem that can't be mitigated by lowering the I2C data rate. We're now well off discussion the answer written. If I see something new in the question that I can respond to I will. If you're trying to talk to me directly, I can often be found on libera.chat


text:
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.

Yes, I2C is a bus designed for connecting multiple i2c devices via the same bus as long as the i2c devices have different i2c address. If you can read the temperature sensor, but not the IMU, run the i2c scanner to see if you can detect it first. You will definitely need pull-up resistors on both i2c lines if your Arduino or your sensors do not have it.

also asked on Arduino forum https://forum.arduino.cc/t/is-it-possible-to-use-multiple-i2c-sensors-with-arduino-without-an-i2c-multiplexer/1027277

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 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 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 and also this cheap saleae clone works perfect with logic software offered from saleae:

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, 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 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.

But when I connect 4.7k resistors to SDA and SCL lines and Vcc, which comes in the range, the Serial monitor screen is totally white and shows no value.
And when I do not connect any resistor, the temperature sensor is giving correct values but IMU sensor is giving fixed and wrong values.
The temperature sensor I'm using is a module, the Bluerobotics Celsius Fast Response module, and the IMU sensor (MPU 9250) is a 'bare sensor', not a module. Could the problem be because of this? maybe the temperature module already has a built in pull up resistor and the IMU sensor doesn't?

@ssmalik ، if you are adding external pull-up resistors then make sure to turn off the arduino(Atmega328p)  internal pull up resistors because if there is more than one pull up resistor on the same bus with different values , this will give you errors in reading data on the bus , also solving the problem requires debugging using things like logic analyzers as I said

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.