text:
NodeMCU 1.0 - Port D3, relay and pump does not boot
I'm trying to create a watering system using a NodeMCU 1.0, a relay and some pumps.
Currently I've port D0, D1, D2, D5, D6, D7, D8 already in use.
I'm trying to use the port D3 (GPIO0) as follows, but when I plug or reboot the NodeMCU, sometimes (!) at boot the relay starts, the pump starts watering and the board does not finish the boot.

The only way to start the board are the following:

Unplug the current from relay
Unplug D4 until boot ends
Disconnect the pump from relay

I tried to substitute the pump with a led and a resistor and I've no problem.
I tried also to put a resistor before the pump and it starts (but the pump does not work).
At boot my first command (after defining variable and object is setting D3 as HIGH)
#define D0 16
#define D1 5
#define D2 4
#define D3 0
#define D4 2
#define D5 14
#define D6 12
#define D7 13
#define D8 15
#define A0 17
#define TX 1
#define RX 3
#define MSG_BUFFER_SIZE 128

// Initialize clients
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
char msg[MSG_BUFFER_SIZE];
int iteration = 0;
int ID = -1;
int first_run = 1;

void setup() {
  //Initial setup
  digitalWrite(D3, HIGH);
  pinMode(D3, OUTPUT);
  delay(4000);
  Serial.begin(9600);
  ...
}

I really don't understand where is the problem.

what do you expect the top relay to do? ... where is the pump? ... where is the power supply?

D3 is io 0 the boot mode selection pin. it must be HIGH for normal boot. NodeMCU has a pull-up on it.

@jsotola the ralay should turn on and off the water pump when I receive a specific mqtt message. The pump is the white stuff in the picture and is physically nearby the sensor. The power is provided via USB to nodemcu

@Juraj I set D0 as high, is it wrong?

D3 is connected to the FLASH button on the board. It is used to control the boot mode on startup. If this pin is LOW on startup it will stay in flash mode, ready to receive a new program. If it is high on startup it will then execute its saved program (normal boot).
What probably happens here is, that your relay board pulls D3 to LOW, when its connected (probably only a bit stronger than the NodeMCUs builtin pullup resistor). Probably it has a pulldown resistor on its input pin (to keep the relay open by default). The NodeMCU then sees D3 being LOW on startup and stays in flash mode, never executing your code. To let the NodeMCU execute your code, D3 needs to be HIGH at startup! If this happens randomly, then the pullup and pulldown resistors are probably have similar values, so that the noise in the system can switch the state of the pin.
You now have different possibilities:

You could remove the pulldown resistor from your relay board, so that the pullup resistor on the NodeMCU can pull the pin to HIGH during start, until your program will set it to LOW again. Then you need to live with the fact, that the relay will be ON during startup of the NodeMCU, running your pump in that time.
You can do the above, but also move the pump connections to the NC (Normally Closed) contact of the relay. This means the pump is activated, when D3 is LOW, and deactivated, if it is HIGH, so the logic is inverted. D3 being HIGH on startup would then mean the pump isn't running. The caveat is, that if the pumps power is on, which the NodeMCU/relay power is off, the pump will be running.
You can use a different pin for this function. One that is free of a special boot function. We don't know, what you are doing with the other pins. D3 would be a good fit for an input pin, that needs the pullup resistor (like for connecting a button). Or an output pin, where the state at startup is not dictated by the outside device.

Thank you for this precious answer. The first option (remove pulldown) seems fine to me. How can I remove the pulldown and exactly what is it? I've a relay SRD-05VDC-SL-C

I tested to set NC the relay but I get the same result. Sometimes (actually often like 4 times out of 5) the board does not start and remains in flashing. Keep testing the other 2 ways

That part number is only the relay itself, not the relay module, that you use. Can you provide a product link for that? And when doing my second point, you still need to remove the pulldown resistor from your relay module. Using the NC port of the relay doesn't change anything on the signal line. My second point is only to prevent the pump to run during the NodeMCUs startup and its a tradeoff. Best would really be to use a different pin.

I bought this relay (https://it.aliexpress.com/item/1005005865597217.html).
It's the model with 4 channels


text:
Sampling rate too slow
I have an Arduino Nano connected to an Adafruit H3LIS331 accelerometer. The sampling is initiated by a button press, which sets a delay to prepare for the measurement, and then the sampling begins. The defined sampling rate is 1 kHz. However, when reading the values from the serial monitor using PySerial, I get approximately 350 samples per second.
Code:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_H3LIS331.h>
#include <Adafruit_Sensor.h>

// Button pin
#define SWITCH 8

const unsigned long REPETITION_INTERVAL = 1000; // repetition time in milliseconds, 6000ms is 6 seconds

// Initiate H3LIS331 library
Adafruit_H3LIS331 lis = Adafruit_H3LIS331();

void setup(void) {
  Serial.begin(115200);          // Open Serial Monitor
  while (!Serial) delay(10);

  if (! lis.begin_I2C()) {
    Serial.println("Couldnt start H3LIS331 sensor!");
    while (1) yield();
  }

  Serial.println("H3LIS331 found!");

  lis.setRange(H3LIS331_RANGE_400_G);   // Set range of possibe 100, 200, or 400 G! In our case 400g
  Serial.print("Range set to: ");

  switch (lis.getRange()) {
    case H3LIS331_RANGE_100_G: Serial.println("100 g"); break;
    case H3LIS331_RANGE_200_G: Serial.println("200 g"); break;
    case H3LIS331_RANGE_400_G: Serial.println("400 g"); break;
  }

  lis.setDataRate(LIS331_DATARATE_1000_HZ);  // Set data rate/time resolution to 1000Hz
  Serial.print("Data rate set to: ");

  switch (lis.getDataRate()) {
    case LIS331_DATARATE_POWERDOWN: Serial.println("Powered Down"); break;
    case LIS331_DATARATE_50_HZ: Serial.println("50 Hz"); break;
    case LIS331_DATARATE_100_HZ: Serial.println("100 Hz"); break;
    case LIS331_DATARATE_400_HZ: Serial.println("400 Hz"); break;
    case LIS331_DATARATE_1000_HZ: Serial.println("1000 Hz"); break;
    case LIS331_DATARATE_LOWPOWER_0_5_HZ: Serial.println("0.5 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_1_HZ: Serial.println("1 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_2_HZ: Serial.println("2 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_5_HZ: Serial.println("5 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_10_HZ: Serial.println("10 Hz Low Power"); break;
  }
}

void loop() {
  int buttonPressed = digitalRead(SWITCH);

  // If the button pressed
  if (buttonPressed) {
    Serial.println("5 seconds preparation...");

    // Wait 5 seconds (5000 milliseconds) for the measurement to take effect
    delay(5000);

    Serial.println("Measurement Started");
    unsigned long startTime = millis() + REPETITION_INTERVAL;
    while(startTime >= millis()) {
      // Get a new sensor event, normalized
      sensors_event_t event;
      lis.getEvent(&event);

      // Based the range of the H3LIS331, display the results measured in g
      Serial.print("\t\tX:"); Serial.print(event.acceleration.x / SENSORS_GRAVITY_STANDARD);
      Serial.print(" \tY:"); Serial.print(event.acceleration.y / SENSORS_GRAVITY_STANDARD);
      Serial.print(" \tZ:"); Serial.println(event.acceleration.z / SENSORS_GRAVITY_STANDARD);
    }
    Serial.println("Measurement Ended");
  }
}

How can I speed this up?

You can speed it up by not printing while you sample.

@StarCat Thanks! How can I save the data without printing it?

how do you save startTime?

please copy the content of the  serial monitor and paste it into your question ... format as code

@StarCat is likely correct. Also, understand millis() will eventually roll over and when it does your code will run for a long long time before exiting. Consider storing all your samples in an array and printing it out after sampling is completed.

Thaks you all for the comments.
@starCat, i didn't mention that i do not have and sd card on the arduino nano. How can store the data?

source: Stack Exchange

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

sort: votes


text:
How to connect TFT screen (ST7735S) to Arduino?
I'm learning to work with Arduino and I decided to work with a TFT display (driver ST7735S, I connect to Arduino Uno), but I encountered a problem in the form that my contacts are labeled differently than in all the examples I looked at (example - no MOSI contacts/ MISO and CLK, instead of BL - BLK), because of which I am confused and cannot connect the screen correctly -
please, help)
Display photo:

what are the pin labels?... you only said what they are not, which is not very useful ... please update you post

Connections
Connections as follows:

BLK -> 5V
CS -> D10 (or anything, i.e. D9 -  just change the #define below)
DC -> D9 (or anything, i.e. D8 -  just change the #define below)
RST -> D8 (or anything, i.e. D7 -  just change the #define below)
SDA -> D11
SCL -> D13
VDD -> 5V
GND -> GND

Using TFT library
You can use the TFT library:
#include <TFT.h>
#include <SPI.h>

With the following #defines:
#define CS 10
#define DC 9
#define RST 8

Note: if you used different pins, then just change the numbers.
Create an instance and initialise with:
TFT myDisplay = TFT(CS, DC, RST);

myDisplay.begin();

Using GFX
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>

With the following #defines:
#define CS 10
#define DC 9
#define RST 8

Note: if you used different pins, then just change the numbers.
Create instance1:
Adafruit_ST7735 myDisplay = Adafruit_ST7735(CS,  DC, RST);

Initialise with
myDisplay.initR(INITR_BLACKTAB);

Further reading

Beginner Arduino - Using a 1.8 Inch TFT Display
Guide to 1.8 TFT Display with Arduino

Footnote
1
Alternative instance creation, which is slower, but you can use different MOSI/SCLK pins (hence the additional #defines):
#define SCLK 13   // You can change this
#define MOSI 11   // You can change this
Adafruit_ST7735 myDisplay = Adafruit_ST7735(CS, DC, MOSI, SCLK, RST);

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


text:
Reading MODBUS on ESP32
I'm working on a project for Smart Meter in this I'm reading MODBUS RS485 on ESP32 via MAX485 TTL To RS485
Overview : So, basic flow is, reading MODBUS as per MOSBUS Mapping list given by Smart Meter Manufacturers, I added those hardcoded values in code, read those register values one by one, convert the reading to decimal/float, arrange all required reading in specific format, send the JSON data with https POST request. And then further display those on graph or whatever on server.
Note : I'm reading only 4 slave ID's as of now. So maximum 4 Numbers of meter can be connected once at a time.
Testing Scenario (a lab with less noise and interference around) : I'm able to read data on ESP32 perfectly fine, with changing MODBUS Slave IDs on the meter, even while running.
Onsite Scenario (a place with HIGH voltage Electrical Panel) : Sometime it reads data perfectly fine, Some it reads only some of the Slave IDs (Out of 4), other time there is no data readings on ESP32
Debugging : To rectify the onsite issue, I checked if the meter is working fine or not with RS485-to-USB converter and read data on MODSCAN Application on PC. And meter is working perfectly fine. Then what I noticed is, ESP32 also started getting reading while I have connected RS485-to-USB converter in parallel.

And if I removed the RS485-to-USB converter, ESP32 immediately stopped reading any data.
Temporary Solution : To fix this, I removed the RS485-to-USB converter from my PC, and given direct 5V supply to RS485-to-USB Converter. And ESP32 started reading data again from MODBUS.

Question I need help with are

I couldn't understand what does the RS485-to-USB converter
connection in parallel doing.
Does it helping in improving RS485 signal and as a repeater?
What is the easier way to overcome this, as hardware as well as if only firmware fix is possible?

Some References and term I used above

ESP32 30 Pins
RS485-to-USB

MAX485 TTL To RS485

PCB inside Panel :

Additional as Required

Meter Manufacturer 1 A-B:50.5 Ohm      B-A:42.9K Ohm
Meter Manufacturer 2 A-B:0.329M Ohm    B-A:0.327M Ohm
MAX485 to TTL        A-B:120 Ohm       B-A:120 Ohm
RS485-to_USB         A-B:26.5 Ohm      B-A:26.3 Ohm

Could you please re-write the post, because I cannot understand what's going on. How are you connecting the ESP32 to the modules? Where are your grounds? This needs a lot more to determine how to fix this; it indeed seems like a noise issue. I would say that this can probably be fixed with an RS485 repeater. It also potentially sounds like you might be missing a terminating resistor.

@jsotola My bad, please take a look again. let me know if there is any other I can provide you to understand the issue I'm facing

@NickS. I rewrite the question in detail now, please take a look again

How long is your cable, RS485 requires twist pair with shielding, not just two plain wire, this is especially important in the noisy application environment. 2) RS485 requires two terminal resistors (120 ohms) at the two end of the bus, maybe your MAX485 module doesn't have the termination resistor, but your USB-RS454 dongle provided that...

@JustdoinGodswork can you measure the resistance between A and B on the MAX485 module? When it's powered off. How about on the meters? If you can power them off. Also, the last picture shows me that the ESP32 is simply connected to the RS485-USB dongle thru the MAX485 module, how does that enable you to read meter data?

@hcheung At one location it's not even 1 meter long, just three meters are connected with different slave IDs (ID:1, ID:2, and ID:3). But there are CTs nearby of 2000/5A ratio. So I'm not sure if that is causing the issue.
I'm using CAT6 for RS485 between Meters but from the last meter to ESP32 its plain wire as shown in last image (connection to orange Screw-Terminal connector)

@NickS. Added the required resistance values in the above question. In the last picture you can see an orange colored Screw Terminal, that's where I connected RS485 from Electric Meter (yellow colored two wire refer last picture)

Also, it doesn't seem just about the resistor issue. Because if it's a resistor issue, it should be fixed even with RS485-to-USB connected in parallel without any power. but ESP32 only reads when the USB connected to a power source as I showed in the picture above of Temporary Solution.

@JustdoinGodswork those don't look good per se, but I don't know how you're measuring them. We have verified that the module has a terminating resistor and that's good. One thing I don't understand - have you tried plugging the meter's RS485 connection into the green connector on the MAX485 module or are you solely using the orange terminals? If yes, why? Are the two connected on the board?

@NickS. For measuring resistance, I removed all connections from the meter, MAX485 Converter module, and USB. Then use a multimeter in resistance-measuring mode.  The orange connector comes out of the casing/box, so I'm using that for meter RS485 as of now. Also, they are shorted on the PCB with A to A and B to B. This already works perfectly fine while testing in lab with the orange connector only.

@JustdoinGodswork let's continue in the chat.


text:
Programming ATtiny1616 error: A programmer is required to upload
I have this ATtiny1616 breakout board and I'm attempting to upload an Arduino sketch to it following this documentation, but I'm getting the error "A programmer is required to upload" upon uploading a simple blink sketch. I have the following parameters set in the IDE:
Board: ATtiny
Chip: Attiny1616
Programmer: Serial UPDI: Slow 57600 baud
I am using this USB-Serial adapter and it is connected to the ATtiny like so:
USB Vcc -> Vin
USB GND -> GND
USB RX -> 1k OHM
USB TX -> 1k OHM
1k OHM -> UPDI
And I have an LED connected to pin 5 of the ATtiny:
PIN 5 -> LED -> 220 OHM -> GND
Any help would be greatly appreciated. Thank you.
Edit: Below is the circuit. I also thought that maybe I had RX and TX mixed up, so I tried switching those connections but that didn't work either.

Edit 2: Using Arduino IDE 1.8.19 I get this error:
pymcuprog.pymcuprog_errors.PymcuprogError: UPDI initialisation failed

The error message seems to imply that you have not selected an appropriate programmer from the list available in the IDE tools menu ( bottom of page). The Adafruit recommendation (your link) is SerialUPDI - SLOW: 57600 baud.

Thank you for your response, however as per my OP I have that parameter set.

are these header pins soldered on the PCB or you simply plug the header pins to the breadboard?

I just have male header pins connected from the jumper cables to the breadboard.

I guess then you are using Arduino IDE 2.x. There is a known behaviour difference between that and 1.x which can cause confusion leading to your error message. See https://forum.arduino.cc/t/a-programmer-is-required-to-upload/1101631 . If this solves it then write your own answer with a bit more detail.

Thank you for that. Using IDE 1.8.19, no longer is there the programmer error but I get a different error now in the updated OP.

If you Google for that error message you find some variants of the circuit added between the usb/uart adaptor and the attiny. Some with a Schottky diode and some with other resistor values. The values may also depend on whether the usb/uart adaptor has resistors in series with TX and RX. If that usb/uart adaptor is 3v3 like the Adafruit version, you could also try powering tha attiny at 3v3

Please make sure that your USB to serial adapter is working well. If the adapter itself is faulty, it can create problems. Also, check if you have all the necessary drivers installed.
Here is another tutorial regarding how to program the ATTiny1616  Breakout board using the MegaTinycore library. You can find it here :
https://www.pcbway.com/project/shareproject/ATTiny1616_Minimal_Breakout_board_QFN_bad990fc.html

In order to use a USB-Serial adapter as a SerialUPDI programmer, it needs to wire it as the diagram shown below
                        Vcc                     Vcc
                        +-+                     +-+
                         |                       |
 +---------------------+ |                       | +--------------------+
 |                     +-+                       +-+                    |
 |                     |      +----------+         |                    |
 |                  TX +------+   1k     +---------+ UPDI               |
 |                     |      +----------+    |    |                    |
 | USB-Serial Adaptor  |                      |    |  Target AVR Board  |
 |                     |                      |    |                    |
 |                  RX +----------------------+    |                    |
 |                     |                           |                    |
 |                     +--+                     +--+                    |
 +---------------------+  |                     |  +--------------------+
                         +-+                   +-+
                         GND                   GND

Thank you for your response, however upon connecting the ATtiny as described in your post I'm still getting the same error. I'm updating my OP with a picture of my connections.

What IDE are you using? Arduino IDE with MegaTinyCore? or something else?

Yes, I'm using the Arduino IDE with MegaTinyCore. I also would like to note that in attempt to getting it to work, I pressed the "Burn bootloader" button, when using an Arduino to try to connect to the ATtiny. Could that have messed something up?

No idea. I never use the boot loader. In fact, I nowadays don't even use MegaTinyCore and Arduino IDE often, I mostly just have VS Code, AVRDude and  bare metal. I think you should consider soldering the header to the board, the problem you are facing might just be bad connection.

"burn bootloader...". This can cause a problem if it succeeds in uploading a bootloader because it has the potential to convert the updi pin to a reset pin preventing further updi programming and needing a high voltage programmer to undo it. However, if you chose the board variant something like "attiny 1616 without optiboot " then "burn bootloader..." simply updates fuses. On these Attinys with a low pin count a bootloader is not recommended. The term "burn bootloader" in the IDE causes much confusion because it may not mean burn bootloader.

Errata: With the MegaTinyCore, loading the bootloader does not automatically convert the UPDI pin to a reset pin on the attiny 1616. See https://forum.arduino.cc/t/programming-and-implementing-attiny1616-with-breakout-board-error-a-programmer-is-required-to-upload/1232433/14


text:
Slider servo doesn't give the right output
#include <HCPCA9685.h>
#include <Wire.h>
#define I2CAdd 0x40

HCPCA9685 HCPCA9685(I2CAdd);
String state = "";

int servo5Pos;
int servo5PPos;

void setup() {
  Wire.begin();
  Serial.begin(4800);
  HCPCA9685.Init(SERVO_MODE);
  HCPCA9685.Sleep(false);
  servo5PPos = 63;

}

void loop(){
  if (Serial.available() > 0){
    state = Serial.readString(); // Read the data as string
    Serial.print(state + "\n");
    // If "Waist" slider has changed value - Move Servo 5 to position
    if (state.startsWith("s5")){
      String stateS = state.substring(2, state.length()); // Extract only the number. E.g. from "s1120" to "120"
      servo5Pos = stateS.toInt(); // Convert the string into integer
      // We use for loops so we can control the speed of the servo
      // If previous position is bigger then current position
      Serial.print(servo5Pos);
      if (servo5PPos > servo5Pos){
        for (int pos = servo5PPos; pos >= servo5Pos; pos--) {
          HCPCA9685.Servo(5, pos);
          delay(20);
        }
      }
      if (servo5PPos < servo5Pos){
        for (int pos = servo5PPos; pos <= servo5Pos; pos++) {
          HCPCA9685.Servo(5, pos);
          delay(20);
        }
      }
      servo5PPos = servo5Pos;
    }
  }
}

I'm trying to communicate my MIT Block Code to this Arduino Code, to control a servo via slider. By giving it a ''s5'' text to move the servo. However, I get this output instead when I'm printing the data received. Below is the code output and MIT block code.

what were you expecting to see in the output? ... please replace the picture of text with the text

what is your question? ... please add a focused, answerable question to your post

Welcome to SE/Arduino! Please take the [tour] to learn how this site works, and read "[ask]". Please [edit] your question to replace the image of text with actual text. -- This "code output" you show, which device generates that? -- Your sketch expects just an integer after the servo number, but the text you show has a floating point number. Are you aware of this? -- How do you think are the different messages separated? The text you show has no separator between them. Did you consider to add for example a \n?

Do not use Serial.readString()
Your main issue here is that you seem to assume that the serial port
transmits messages from your computer to your Arduino. It doesn't. It
only transmits a stream of bytes (ASCII characters here), which is what
the Arduino gets ate the other end.
Serial.readString() has no way of knowing where one message ends and
the next one begins. Instead, it relies on a very simple heuristic: if
one full second has elapsed with no byte being received, then it assumes
whatever has been received so far is a complete message. This works
reasonably well for messages manually typed at the serial monitor,
because you are unlikely to type two messages within one second.
When you move the slider, however, your block code sends messages in
quick succession: “s539.7”, then “s540.8”, then “s543”... The Arduino
then receives a string of characters: 's', '5', '3', '9', '.',
'7', 's', '5', '4', '0', '.', '8', 's', '5', '4',
'3', ... This is interpreted as a single message by
Serial.readString().
Solution: Use an “end of message” indicator instead of (or in
addition to) the “start of message” indicator. The characters CR (\r)
and LF (\n) are popular choices. You can then use
Serial.readStringUntil() to get a full message.
Or, better yet, do not use the String class at all. See
Reading Serial on the Arduino.


text:
ESP-WROOM-02 with on-board 18650 battery. How to charge it?
I have a ESP-WROOM-02 module with on-board 18650 battery. V+ and GND are exposed on the board.
Can I directly charge the battery using an USB-C connector with the two cables (red and black) directly soldered to the battery poles on the board?

The lithium battery must be charged by a specialized CC/CV control chip. The module in question already has one, namely a TP5400, sitting between the mounted micro-USB connector and the 18650 battery holder. You should use the same USB connector for both programming the MCU and charging the battery.


text:
PCINT of PortC for an analog device
I would like to use analog signals from joystick axes in program. Firstly, I found out that external interrupts can be applied for 2 and 3 pins of PortB only. Now I am trying to use PCINT for A0 and A1 pins for instant reaction in program and implementation transition between modes of alarm clock, which is the main goal of a project. I saw how it cold be done with encoder, but I have a joystick physically. Can PCINT-interrupts can be used to react changing of analog signals?
Target part of code and breadboard diagram are below.
#include <LiquidCrystal.h>
#include <RTClib.h>
#include <ezButton.h>

#define set0(R,b) R&= ~(1<<b)
#define set1(R,b) R|= 1<<b

//#include <avr/io.h>
//#include <avr/interrupt.h>

int lcd_V0 = 13;
int RS = 11;
int RW = 10;
int E = 9;
int D4 = 4;
int D5 = 5;
int D6 = 6;
int D7 = 7;

int DHT11 = 12;
int Buzzer = 8;
int Joystick_button = 1;

LiquidCrystal lcd(RS, RW, E, D4, D5, D6, D7);
RTC_DS1307 rtc;
ezButton button(Joystick_button);

int Joystick_X = A1;
int Joystick_Y = A0;
bool X_changed = false;
bool Y_changed = false;
volatile int X = 0;
volatile int Y = 0;

void setup() {
  lcd.begin(16,2);
  lcd.display();

  rtc.begin();

  pinMode(Buzzer, OUTPUT);
  pinMode(Joystick_button, INPUT_PULLUP);

  set0(DDRC, 0);
  set1(PORTC, 0);
  set0(DDRC, 1);
  set1(PORTC, 1);
  set1(PCICR,PCIE1);
  set1(PCMSK1,PCINT8);
  set1(PCMSK1,PCINT9);
}

void loop() {
  button.loop();
  if(X_changed){
     X = analogRead(Joystick_X);
     Y = analogRead(Joystick_Y);
     lcd.setCursor(0, 0);
     lcd.print(String(Y) + String(X));
     }
  if(Y_changed){
     X = analogRead(Joystick_X);
     Y = analogRead(Joystick_Y);
     lcd.setCursor(0, 1);
     lcd.print(String(Y) + String(X));
     }
  }

ISR( PCINT1_vect )
{
  if((PINC&(1<<0))==0){Y_changed = true;}
  if((PINC&(1<<1))==0){X_changed = true;}
}

PCINTx_vect are for GPIO pins. There is ADC_vect (ADC conversion complete vector). Open the datasheet and search for "Interrupt Vectors" table within the datasheet and read the chapter about ADC to see how to use it, or alternatively google "ATmega328 ADC interrupt".

If the joystick is going to be operated by a human, or any sort being incapable of sub-millisecond moves, then you don't need interrupts. As long as your loop() is non-blocking, simply reading the analog values within loop() will be fine.

There is no equivalent of Pin Change interrupts for the ADC. While you can trigger the ADC automatically and then interrupt on completion via ADC_vect, that is not fitting for your situation. Also you would need to switch between both A0 and A1, since there is only one ADC in the Uno. I second Edgar here: There is no good reason to use interrupts for this. Your current loop()  is already running faster than any human can notice or react, even if you don't check for a changed pin. So just do it in loop()


text:
Reading from Analog Mic and Transmitting over BLE (Nano 33 BLE)
I'm trying to read from an analog mic with a sampling frequency of 10 kHz and transmitting the data over BLE on Arduino Nano 33 BLE Sense Rev 2. The MCU reaches that sampling rate with no problem but once I activate BLE it starts having a delay too big to keep up with the 10kHz
Is it possible doing something like this on Arduino, or will I have to try with a different chip?


text:
Problem in serial communication between ESP32 and GSM A7670C
I am using A7670C GSM breakout board with an ESP32.
Connections

RX-TX
TX-RX
GND-GND

I am giving external power to the GSM module, 3.8 V according to theproduct description.
When I sent the AT command to GSM module, I don't get output on the serial monitor of the Arduino IDE.
The message is sent to a particular number successfully, but I don't receive the message from mobile.
This is my code:
#include <HardwareSerial.h>

HardwareSerial mySerial(2);

void setup() {
  mySerial.begin(115200); // Setting the baud rate of GSM Module
  Serial.begin(115200);   // Setting the baud rate of Serial Monitor (Arduino)
  delay(100);
  SendMessage();
  RecieveMessage();
}

void loop() {
  if (Serial.available() > 0)
    Serial.write(Serial.read());

  switch(Serial.read()) {
    case 's':
      SendMessage();
      break;
    case 'r':
      RecieveMessage();
      break;
  }

  if (mySerial.available() > 0)
    Serial.write(mySerial.read());
}

void SendMessage() {
  mySerial.println("AT+CMGF=1");    // Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  mySerial.println("AT+CMGS=\"+91XXXXXXXXXX\"\r"); // Replace x with mobile number
  delay(1000);
  mySerial.println("I am SMS from GSM Module"); // The SMS text you want to send
  delay(100);
  mySerial.println((char)26); // ASCII code of CTRL+Z
  delay(1000);
}

void RecieveMessage() {
  mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to receive a live SMS
  delay(1000);
}

Other AT commands also don't give me an OK message on the serial monitor, or any other message. I have tried software serial, but it doesn't work.


text:
OS detection with Arduino Uno
I've been searching for a bit, and feel like it's impossible, but I will ask anyway: is it possible for an Arduino to detect what OS it uses, like how a rubber ducky does via USB?
I want specific code to run when it's plugged in a different operating system.
Is there any possible way to do that?
I've tried to find libraries for it, or any other stuff, but I can't seem to find any.

Not sure, how a rubber ducky does it, though it will definitely will be by a clever use of the USB protocol. With the Uno that would only work, if you hack the USB-Serial chip (Atmega32u4 I believe), which handles the USB connection for the Uno.

According to the Rubber Ducky’s Web site, it uses passive OS fingerprinting. You may try FingerprintUSBHost on a Leonardo or similar USB-enabled Arduino (not an Uno).


text:
KIE-TS-300B turbidity sensor not working
I'm working with a clone Arduino micro board. I've got the color sensor up and running fine. So the problem isn't the card.
I'm using the example code, just to try out the module:
        // the setup routine runs once when you press reset:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
    }

    // the loop routine runs over and over again forever:
    void loop() {
      // read the input on analog pin 0:
      int sensorValue = analogRead(A0);
      // print out the value you read:
      Serial.println(sensorValue);
      delay(1);  // delay in between reads for stability
    }

A0 is on the output, ground and 5V wires are setup right. The red light on the module is red. I'm getting readings about 200-ish. That's about 1.5 V, if I convert it. I can't block it with an opaque object, that doesn't change the readings. I removed the cover, to see if it helps, still the same. I've tried three different sensors.
The one I'm using is this device: TS-300B Turbidity sensor water turbidity module turbidity detection module.
Any suggestions as to how, and why, is this happening?


text:
Issue with multiple RC522s connected to Arduino Uno
I'm building a puzzle with four RC522 modules. When I connect more than one RC522 to an Arduino Uno, the device stops working randomly. Initially, everything seemed fine. I began adding the modules one by one, but suddenly, without any apparent reason, the whole system stopped functioning.
I attempted to locate the issue by disconnecting all the RC522 modules. When only one RC522 is connected, everything works correctly. However, when I attach the MISO and MOSI pins of the second RC522 to the Arduino, the first device stops working. Additionally, when I tried using the DumpInfo example of the library, the output after adding the second device is as follows:
    Card UID: 33 6C E8 F6
    Card SAK: 08
    PICC type: MIFARE 1KB
    Sector Block   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  AccessBits
      15     63   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             62  MIFARE_Read() failed: A MIFARE PICC responded with NAK.
             61  MIFARE_Read() failed: Timeout in communication.
             60  MIFARE_Read() failed: Timeout in communication.
      14     59  PCD_Authenticate() failed: Timeout in communication.
      13     55  PCD_Authenticate() failed: Timeout in communication.
      12     51  PCD_Authenticate() failed: Timeout in communication.
      11     47  PCD_Authenticate() failed: Timeout in communication.
      10     43  PCD_Authenticate() failed: Timeout in communication.
       9     39  PCD_Authenticate() failed: Timeout in communication.
       8     35  PCD_Authenticate() failed: Timeout in communication.
       7     31  PCD_Authenticate() failed: Timeout in communication.
       6     27  PCD_Authenticate() failed: Timeout in communication.
       5     23  PCD_Authenticate() failed: Timeout in communication.
       4     19  PCD_Authenticate() failed: Timeout in communication.
       3     15  PCD_Authenticate() failed: Timeout in communication.
       2     11  PCD_Authenticate() failed: Timeout in communication.
       1      7  PCD_Authenticate() failed: Timeout in communication.
       0      3  PCD_Authenticate() failed: Timeout in communication.

It's noticeable that whenever I remove the MISO and MOSI pins of the second RC522, everything works.
I've tried using six different Arduinos and eleven different RC522 modules. Initially, they workef correctly, but after some time, everything went wrong, similar to the issue described above. I've experimented with different codes, considered power drop issues, and even added a 2 A power supply. I've used both 3.3 V and 5 V supplies and attempted to add pull-up resistors to each CS line. I also made sure that every connection is correct by using the multimeter. I also tried to add decoupling cap on the VCC. I used shared and separated RST pins.
Two sample programs are below, the simple one just to test the modules:
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         3         // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
    Serial.begin(9600);     // Initialize serial communications with the PC
    while (!Serial);        // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
    SPI.begin();            // Init SPI bus
    digitalWrite(SS_PIN, HIGH);
    mfrc522.PCD_Init();     // Init MFRC522
    delay(4);               // Optional delay. Some board do need more time after init to be ready, see Readme
    mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
    Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
    // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
        return;
    }

    // Select one of the cards
    if ( ! mfrc522.PICC_ReadCardSerial()) {
        return;
    }

    // Dump debug info about the card; PICC_HaltA() is automatically called
    mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

My own code:
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN_A 10
#define RST_PIN_A 3

#define SS_PIN_B 9
//#define RST_PIN_B 7

#define SS_PIN_C 8
//#define RST_PIN_C 5

#define SS_PIN_D 7
//#define RST_PIN_D 6

#define RELAY_PIN 4  // Pin connected to the relay

MFRC522 mfrc522Array[] = {
  MFRC522(SS_PIN_A, RST_PIN_A),
  MFRC522(SS_PIN_B, RST_PIN_A),
  MFRC522(SS_PIN_C, RST_PIN_A),
  MFRC522(SS_PIN_D, RST_PIN_A)
};

String MasterTagA = "336CE8";
String MasterTagB = "336CE8";
String MasterTagC = "336CE8";
String MasterTagD = "336CE8";

String MasterMainTag = "MASTER_TAG"; // Replace with the main master tag

String tagIDA = "";
String tagIDB = "";
String tagIDC = "";
String tagIDD = "";

bool accessGrantedA = false;
bool accessGrantedB = false;
bool accessGrantedC = false;
bool accessGrantedD = false;

bool mainMasterTagDetected = false;

MFRC522::MIFARE_Key key;

unsigned long activationTime = 0;  // Time of last activation
unsigned long debounceDelay = 4000;  // Delay for relay activation (4 seconds)

// Function declarations
void activateRelay();

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

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, HIGH);  // Ensure relay is initially deactivated

  for (int i = 0; i < 4; i++) {
    mfrc522Array[i].PCD_Init();
  }

  Serial.println("Scan a MIFARE Classic card");

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
}

void loop() {
  for (int i = 0; i < 4; i++) {
    if (getID(&mfrc522Array[i], i)) {
      if (mainMasterTagDetected) {
        activateRelay();
        mainMasterTagDetected = false; // Reset main master tag detection flag
      } else {
        switch (i) {
          case 0:
            checkAccess(tagIDA, MasterTagA, accessGrantedA, "A");
            break;
          case 1:
            if (accessGrantedA) {
              checkAccess(tagIDB, MasterTagB, accessGrantedB, "B");
            }
            break;
          case 2:
            if (accessGrantedA && accessGrantedB) {
              checkAccess(tagIDC, MasterTagC, accessGrantedC, "C");
            }
            break;
          case 3:
            if (accessGrantedA && accessGrantedB && accessGrantedC) {
              checkAccess(tagIDD, MasterTagD, accessGrantedD, "D");
            }
            break;
        }
      }
      printAccessControlStatus();
    }
  }

  // If all access granted and relay not activated yet
  if (accessGrantedA && accessGrantedB && accessGrantedC && accessGrantedD && millis() - activationTime >= debounceDelay) {
    activateRelay();
    // Reset access granted flags
    accessGrantedA = false;
    accessGrantedB = false;
    accessGrantedC = false;
    accessGrantedD = false;
  }
}

boolean getID(MFRC522* mfrc522, int moduleIndex) {
  if (!mfrc522->PICC_IsNewCardPresent()) {
    return false;
  }
  if (!mfrc522->PICC_ReadCardSerial()) {
    return false;
  }

  String tagID = "";
  for (uint8_t i = 0; i < 3; i++) {
    tagID.concat(String(mfrc522->uid.uidByte[i], HEX));
  }
  tagID.toUpperCase();
  if (tagID == MasterMainTag) {
    mainMasterTagDetected = true; // Set main master tag detection flag
  }
  storeTagID(tagID, moduleIndex);
  mfrc522->PICC_HaltA();
  return true;
}

void storeTagID(String tagID, int moduleIndex) {
  switch (moduleIndex) {
    case 0:
      tagIDA = tagID;
      break;
    case 1:
      tagIDB = tagID;
      break;
    case 2:
      tagIDC = tagID;
      break;
    case 3:
      tagIDD = tagID;
      break;
  }
}

void checkAccess(String tagID,
String masterTag, bool& accessGranted, String moduleName) {
  Serial.println(tagID);

  if (tagID == masterTag) {
    accessGranted = true;
    Serial.print("Access Granted to Module ");
    Serial.println(moduleName);
  } else {
    accessGranted = false;
    Serial.println("Access Denied!");
  }
}

void activateRelay() {
  digitalWrite(RELAY_PIN, LOW);  // Activate relay
  delay(2000);  // Wait for 2 seconds
  digitalWrite(RELAY_PIN, HIGH); // Deactivate relay
  activationTime = millis(); // Update activation time
}

void printAccessControlStatus() {
  Serial.print("Access Control Status: ");
  Serial.print("Module A: ");
  Serial.print(accessGrantedA ? "Granted  " : "Denied  ");
  Serial.print("Module B: ");
  Serial.print(accessGrantedB ? "Granted  " : "Denied  ");
  Serial.print("Module C: ");
  Serial.print(accessGrantedC ? "Granted  " : "Denied  ");
  Serial.print("Module D: ");
  Serial.println(accessGrantedD ? "Granted  " : "Denied  ");
}

this is the method which I connected the modules:

UPDATE 1:
I added 1 sec delay before accessing each rc522 but did not solve the problem.
UPDATE 2
When the 1st module is connected to arduino and its SDA pin connected to the pin 10, the output of DumpInfo code is as follow
Card UID: 23 FC A0 FD
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  AccessBits
  15     63   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
         62   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         61   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         60   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
  14     59   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
         58   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         57   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         56   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
  13     55   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
         54   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         53   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         52   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
      12     51   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             50   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             49   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             48   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
      11     47   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             46   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             45   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             44   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
      10     43   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             42   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             41   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             40   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       9     39   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             38   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             37   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             36   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       8     35   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             34   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             33   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             32   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       7     31   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             30   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             29   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             28   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       6     27   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             26   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             25   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             24   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       5     23   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             22   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             21   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             20   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       4     19   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             18   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             17   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             16   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       3     15   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             14   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             13   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
             12   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       2     11   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
             10   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
              9   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
              8   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       1      7   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
              6   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
              5   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
              4   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
       0      3   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
              2   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
              1   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
              0   23 FC A0 FD  82 08 04 00  62 63 64 65  66 67 68 69  [ 0 0 0 ]

But when I connect the second one to the arduino (2nd SDA: Pin9) the output for the first one would be similar to this one:
Card UID: 23 FC A0 FD
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  AccessBits
  15     63   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
         62   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         61   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
         60   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
  14     59  MIFARE_Read() failed: The CRC_A does not match.
  14     58   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]  Inverted access bits did not match!
         57  MIFARE_Read() failed: Timeout in communication.
         56  MIFARE_Read() failed: Timeout in communication.
  13     55  PCD_Authenticate() failed: Timeout in communication.
  12     51  PCD_Authenticate() failed: Timeout in communication.
  11     47  PCD_Authenticate() failed: Timeout in communication.
  10     43  PCD_Authenticate() failed: Timeout in communication.
   9     39  PCD_Authenticate() failed: Timeout in communication.
   8     35  PCD_Authenticate() failed: Timeout in communication.
   7     31  PCD_Authenticate() failed: Timeout in communication.
   6     27  PCD_Authenticate() failed: Timeout in communication.
   5     23  PCD_Authenticate() failed: Timeout in communication.
   4     19  PCD_Authenticate() failed: Timeout in communication.
   3     15  PCD_Authenticate() failed: Timeout in communication.
   2     11  PCD_Authenticate() failed: Timeout in communication.
   1      7  PCD_Authenticate() failed: Timeout in communication.
   0      3  PCD_Authenticate() failed: Timeout in communication.

Thanks for replay, I added 1sec delay between accessing modules., but did not work.

Did you check the documentation or source code of the MFRC522 library that it supports multiple devices?

Try to follow the ReadUidMultiReader example.

@thebusybee yes, it supports multiple devices.

@hcheung thanks for your help. It sometimes works sometimes not. I turned off my pc and when I turned it on, it stopped working. I also use new board and new RC522 with new cables.

@hcheung I think it might be related to rst pin.

Here is also an old thread regarding how to interface multiple MFRC522 RFID modules. You can see the links given in the answers: https://arduino.stackexchange.com/questions/74993/read-simultaneously-rfid-tag-with-multiple-rfid-reader-mfrc522


text:
Driving stepper to follow sequential positions
I was exploring the stepper motor library AccelStepper and using it because of it's easy interface to control multiple stepper motors simultaneously. Recently I got a problem. I needed a stepper motor to follow position commands of the following kind :
int steps[] = { -0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 4, 4, 4,
                4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, -0, -1, -1, -1, -2, -2, -3,
                -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
                6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 3, 3,
                3, 2, 2, 1, 1, 0, -0 };

This array is truncated in the middle. Actual command is continous throughout the first position to last position.These are the absolute steps that the motor needs to turn.
I generated the pulses to achieve this as following:
void loop() {
  delay(5000);

  int stepperDelay = 9000;

  for (int i = 0; i < 701; i++) {
    int moveTo = steps[i + 1] - steps[i];
    if (moveTo < 0) {
      digitalWrite(dirPin, LOW);
    } else {
      digitalWrite(dirPin, HIGH);
    }
    for (int x = 0; x < abs(moveTo); x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(stepperDelay);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(stepperDelay);
    }
  }

}

Writing the pulses myself gave me a satisfactory result in transition from one abs position to another abs position. The overall working was smooth to the extent I desired.
But, it's gonna take me a lot more effort to apply this to three different stepper motors simultaneously, so I tried to use AccelStepper to do the same thing. I tested the following code :
void setup() {
  st1.setMaxSpeed(maxSpeed);
  st1.setAcceleration(acc);
  st1.setCurrentPosition(0);
}
void loop() {
  delay(5000);

  for (int i = 0; i < 703; i++) {
    st1.moveTo(m1_steps[i]);
    while (st1.distanceToGo() != 0 ) {
      st1.run();
    }
  }

}

This code when I tested, made the motor to follow the same trajectory, but it failed to make it smooth. The movement is not smooth, appears to have some pause betweeen every step.
has anyone any clue what might be the appropriate way ?
I tested with both A4988 driver and TB6600, same issue.

Pause between steps is what a stepper motor does.  That's how it works.  If you want a shorter pause so it looks smoother then increase the speed.

for the A4988,  the STEP input does not have to be a square wave ... the motor moves on low/high transition only ... the input has to stay high for only 1 microsecond

@Delta_G Thanks for the reply !! I am not actually complaining about the pause between the steps, it's actually between two positions in the array. For some reasons library method seems to implement it more coarser at any speed for that matter. I ended up implementing a non-blocking for loop to simultaneously actuating three motors. I would love to hear your thoughts on that.

@jsotola thanks for the insight. I will try that to save extra microseconds.

Is it just that accelstepper is slowing down at the end of one and speeding up at the start of the next?

@Delta_G yes, something like that. Perhaps it's because of the run() method which tries to optimize the movement of due steps, but in my case since the due steps changes in a loop as it has to go through the positions given in the array resulting in lack of continuity. I tried to search how the 3D printers are coded since they have to loop through the gcode as well but didn't find useful information.

If you don't want acceleration and deceleration between steps, then pick a different stepper library.  AccelStepper is specifically written to add that acceleration and deceleration.  Try the normal Arduino Stepper library instead.


text:
Deciphering AD7730 outputs
I am currently working with a AD7730 chip for analog-digital conversion. The chip is programmable, and I have been pulling code from GitHub as well as other links.
I am unfamiliar with SPI (the communication protocol it uses), which I believe is most of the problem. I have been using the code pulled from this library on GitHub as well as its wiring diagram.

The wiring diagram above is nearly identical to my wiring with the only exception that the load cell and amplifier have been replaced with a voltage source. Here is the header file for the code:
#ifndef AD7730_h
#define AD7730_h

#include "Arduino.h"
#include "SPI.h"
#include "Math.h"

class AD7730 {
    public:
        AD7730(int resetPin, int readyPin, int chipSelect);
        void reset(); // resets the AD7730 chip. Equivalent to a power down power up.
        void internalCalibrate(); // performs internal zero and full scale calibrations of the chip
        void systemZeroCalibrate(); // performs system zero scale calibration only of the system (sets the intercept to zero in the linear transfer function)
        void systemFullCalibrate(); // performs full scale calibration of the system.
        void waitForReady(); // pause until ready pin goes low
        void offsetDAC(float offset); // Sets the DAC tare offset value. Allowed range is -40 to 40 (mV) in increments of 2.5 mV
        void range(int range); // Sets the voltage range (gain) of the chip. Allowed values are 10, 20, 40, 80. 10mv range is most sensitive
        void vRef(float volts); // Sets the value of the high reference voltage. Allowed values are 2.5, 5 volts
        void channel(int chan); // Sets the input channel (1 or 2)
        void filter(int avg); // Sets the number of samples to be averaged by the smoothing filter. Default is 512. Max smoothing is 4095.
        void continuousConversionMode(); // places the chip in continuous conversion mode (but does not begin continuous reading)
        void unipolar(); // sets the chip in unipolar conversion mode
        void bipolar(); // sets the chip in bipolar conversion mode (default)
        unsigned long read(); // takes a single reading of the raw result from the AD7730 chip using the parameters set above.
        float readVoltage(); // takes a single voltage reading from the chip using the parameters set above and converts to a voltage.
    private:
        int _resetPin;
        int _readyPin;
        int _CS;
};

#endif

Here is the class file:
#include "Arduino.h"
#include "AD7730.h"
#include "SPI.h"
#include "Math.h"

AD7730::AD7730(int resetPin, int readyPin, int chipSelect) {
    SPI.begin();
    SPI.setDataMode(SPI_MODE3);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV128);

    pinMode(resetPin, OUTPUT);
    pinMode(readyPin, INPUT);
    pinMode(chipSelect, OUTPUT);
    pinMode(MISO, INPUT);
    pinMode(MOSI, OUTPUT);
    digitalWrite(resetPin, HIGH);
    digitalWrite(chipSelect, HIGH);

    _resetPin = resetPin;
    _readyPin = readyPin;
    _CS = chipSelect;
}

void AD7730::reset() {
    // perform a hardware reset using the reset pin on the chip
    digitalWrite(_resetPin, LOW);
    delay(200);
    digitalWrite(_resetPin, HIGH);
    delay(200);
}

void AD7730::internalCalibrate() {
    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (2 byte register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte1 = (byte1 & 0x1f) | (0x4 << 5); // update byte1 to write internal zero scale calibration to chip

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write updated second byte
    digitalWrite(_CS, HIGH);

    waitForReady(); // wait for internal zero scale calibration to complete

    byte1 = (byte1 & 0x1f) | (0x5 << 5); // update byte1 to write internal full scale calibration to chip

    digitalWrite(_CS, LOW);
    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write updated second byte
    digitalWrite(_CS, HIGH);

    waitForReady(); // wait for internal full scale calibration to complete
}

void AD7730::systemZeroCalibrate() {
    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (2 byte register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte1 = (byte1 & 0x1f) | (0x6 << 5); // update byte1 to write system zero scale calibration to chip

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write updated second byte
    digitalWrite(_CS, HIGH);

    waitForReady(); // wait for system zero scale calibration to complete
}

void AD7730::systemFullCalibrate() {

    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (2 byte register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte1 = (byte1 & 0x1f) | (0x7 << 5); // update byte1 to write system zero scale calibration to chip

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write updated second byte
    digitalWrite(_CS, HIGH);

    waitForReady(); // wait for system zero scale calibration to complete
}

void AD7730::waitForReady() {
    while(digitalRead(_readyPin)) {
        // keep waiting as long as ready pin remains HIGH
    }
}

void AD7730::offsetDAC(float offset) {
    int index = (int)(offset/2.5);
    int sign = 0;
    if (index < 0) {
        sign = 1;
        index *= -1;
    }
    int toSend = (sign << 5 | index); // format offset setting as byte to send to DAC register

    digitalWrite(_CS, LOW);
    SPI.transfer(0x04); // set next operation as single write to the DAC register
    SPI.transfer(toSend); // write data to DAC register
    digitalWrite(_CS, HIGH);
}

void AD7730::range(int range) {
    // format range setting is 2 bits to write to Mode register
    int bits;
    if (range <= 10) {
        bits = 0;
    } else if(range <= 20) {
        bits = 1;
    } else if(range <= 40) {
        bits = 2;
    } else {
        bits = 3;
    }

    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (16 bit register)
    int byte1 = SPI.transfer(0xff); // read first byte
    int byte2 = SPI.transfer(0xff); // read second byte

    byte2 = (0xcf & byte2) | (bits << 4); // replace current range bits with specified bits

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write updated second byte
    digitalWrite(_CS, HIGH);
}

void AD7730::vRef(float volts) {
    int bit;
    if(volts <= 2.5) {
        bit = 0;
    } else {
        bit = 1;
    }

    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (16 bit register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte2 = (0x7f & byte2) | (bit << 7); // replace current range bits with specified bits

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write updated second byte
    digitalWrite(_CS, HIGH);
}

void AD7730::channel(int chan) {
    int bits;
    if (chan==1) {
        bits = 0;
    } else {
        bits = 1;
    }

    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (16 bit register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte2 = (0xfc & byte2) | bits; // replace current channel bits with specified bits

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write updated second byte
    digitalWrite(_CS, HIGH);
}

void AD7730::filter(int avg) {
    digitalWrite(_CS, LOW);
    SPI.transfer(0x13); // set next operation as single read of Filter register (24 bit register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte
    int byte3 = SPI.transfer(0x00); // read third byte

    // trim input parameter to 12 bits
    if (avg > 4095) {
        avg = 4095;
    }
    byte1 = avg >> 4; // fill byte1 with 8 most signicant bits of avg
    byte2 = (byte2 & 0xf) | avg << 8; // 4 least significant bits of avg spill over to byte2

    SPI.transfer(0x03); // set next operation as single write to Filter register
    SPI.transfer(byte1);
    SPI.transfer(byte2);
    SPI.transfer(byte3);
    digitalWrite(_CS, HIGH);
}

void AD7730::unipolar() {

    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (16 bit register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte1 = (byte1 & 0xef) | 0x10; // configure unipolar conversion mode

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write second byte
    digitalWrite(_CS, HIGH);
}

void AD7730::bipolar() {

    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (16 bit register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte1 = (byte1 & 0xef); // configure bipolar conversion mode

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write second byte
    digitalWrite(_CS, HIGH);
}

void AD7730::continuousConversionMode() {
    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (16 bit register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte

    byte1 = (byte1 & 0x1f) | (0x01 << 5); // configure for continuous conversion mode

    SPI.transfer(0x02); // set next operation as single write to Mode register
    SPI.transfer(byte1); // write first byte
    SPI.transfer(byte2); // write second byte
    digitalWrite(_CS, HIGH);
}

unsigned long AD7730::read() {
    // use when chip is in continuous conversion mode. This function takes a single reading so should be used in a loop.
    unsigned long result;

    digitalWrite(_CS, LOW);
    SPI.transfer(0x11); // set next operation as single read from Data register (24 bit register assuming the chip is used in 24 bit mode)
    digitalWrite(_CS, HIGH);

    waitForReady();

    digitalWrite(_CS, LOW);
    int byte1 = SPI.transfer(0xff);
    int byte2 = SPI.transfer(0xff);
    int byte3 = SPI.transfer(0xff);
    digitalWrite(_CS, HIGH);

    result = byte1*256L*256L + byte2*256L + byte3;
    return result;
}

float AD7730::readVoltage() {
    digitalWrite(_CS, LOW);
    SPI.transfer(0x12); // set next operation as single read of Mode register (16 bit register)
    int byte1 = SPI.transfer(0x00); // read first byte
    int byte2 = SPI.transfer(0x00); // read second byte
    digitalWrite(_CS, HIGH);

    unsigned long raw = read();
    int unipolar = (byte1 & 0xe0) >> 4; // mask out and shift polarity bit; 0 is bipolar, 1 is unipolar
    float mV;

    int range = (byte2 & 0xc0) >> 4; // mask out and shift range bits
    if (range == 0) {
        range = 10;
    } else if (range == 1) {
        range = 20;
    } else if (range == 2) {
        range = 40;
    } else {
        range = 80;
    }

    if (!unipolar) {
        mV = (float)range*((float)raw - (float)8388608)/(float)8388608;
        return mV;
    } else {
        mV = (float)range*(float)raw/(float)16777216;
        return mV;
    }
}

And here is the Arduino file that uses these two library files:
#include <AD7730.h>

AD7730 adc(8,9,10); // create new instance with reset pin = 8, ready pin = 9, chip select pin = 10

void setup() {
  Serial.begin(9600);
  adc.reset();          // reset the AD7730 chip
  adc.filter(512);      // set digital filter to 512 samples (This setting provides good filtering of 50 hz and 60 hz noise)
  adc.range(10);        // set voltage range to 10 millivolts (this sets the gain of the internal amplifier)
  adc.offsetDAC(0);     // use this function to correct for a wheatstone bridge circuit whose resistors aren't perfectly balanced
  adc.unipolar();       // set chip to unipolar mode
  adc.internalCalibrate();          // run internal calibration of chip before reading voltages
  adc.continuousConversionMode();   // place chip in continuous conversion mode
}

long result;            // declare variable to hold conversion results. Since the AD7730 is a 24bit ADC, the 16bit int data type will not work for this.

void loop() {
  result = adc.read();              // take a single conversion result from the chip
  Serial.println(result);           // print conversion result to the serial monitor
}

Running the above Arduino code produces output, albeit not correct. Putting the chip in its unipolar 10 mV range mode somehow outputs values of 40 mV when the analog signal is set to 0.00 mV. As the signal is increased or decreased in voltage, the output responds correspondingly but not according to the prescribed gain on the data sheet and sometimes it appears to change non-linearly. This happens with all voltage ranges and both the unipolar and bipolar modes: the output signals do not match the input signals to any degree.
I am wondering if this has to do with the conversion to mV at the bottom of the class file. Specifically,
if (!unipolar) {
    mV = (float)range*((float)raw - (float)8388608)/(float)8388608;
    return mV;
} else {
    mV = (float)range*(float)raw/(float)16777216;
    return mV;
}

However, given that the ADC is reading with 24 bits, the 8388608 and 16777216 are accurate. Any help would be appreciated. I have been trying to troubleshoot this for about a month with no success.

The conversion seems legit. Did you change anything to the library or to the provided example? If not, you may want to collect more precise data and file an issue on the library's GitHub project.

Nothing has been changed from the library or the provided example. The only difference is that I am using a voltage supply for my ADC signal rather than some sort of load cell.

If the circuit is build out from breadboard, I would want to check if the crystal really oscillate, the tray capacitance plus the 22pf capacitors might not match the load capacitance of the crystal that you purchased.


text:
I encounter an error in the ISR function when using the code specified in this community for arduinodue to act as a slave in spi communication
#include<SPI.h>

volatile boolean received;
volatile byte receivedData;

ISR (SPI_STC_vect)        //Inerrrput routine function
{
  receivedData = SPDR;   // Get the received data from SPDR register
  received = true;       // Sets received as True
}

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

  pinMode(MISO,OUTPUT);   //Sets MISO as OUTPUT
  SPCR |= _BV(SPE);       //Turn on SPI in Slave Mode
  received = false;
  SPI.attachInterrupt();  //Activate SPI Interuupt
}

void loop()
{
  if(received) {
    SPDR = receivedData;    // send back the received data, this is not necessary, only for demo purpose
    received = false;
    Serial.print(receivedData, HEX);
  }
}

the compiler gives an error with isr specified

What is the error?

@JRobert It's quite encrypted, but he mentioned "arduinodue" so I suspect Arduino DUE (with completely different MCU) :D

This program seems to have been written for an AVR-based Arduino, like a
classic Uno or Nano. The registers SPCR and SPDR, the bit SPE on
SPCR, and the SPI_STC interrupt, are all documented on the
ATmega328P’s datasheet.
Yours is an Arduino Due, which uses a completely different
microcontroller. AVR-specific code cannot run on the Due.

There is a code of SPI Slave for DUE at https://forum.arduino.cc/t/arduino-due-spi-interrupt/574857/3.


text:
Interfacing with Arducam OV2640 from Mac to deploy Image processing libraries
I purchased a Arducam OV2640 https://www.amazon.com/gp/product/B012UXNDOY/ however I am on a MAC. So I am not able to run the capture a image from the camera, which runs only on windows.
The example code is here, however I do not see any functions to capture an image or turn on the video streaming. https://github.com/ArduCAM/Arduino/blob/master/ArduCAM/examples/mini/ArduCAM_Mini_2MP_OV2640_functions/ArduCAM_Mini_2MP_OV2640_functions.ino
I tried sending msg to serial port 0x10,0x20 etc but no response.
I want to capture images from the camera and use it on my computer alternatively I want to run a OpenCV like library on the Arduino Module. How do I connect python code to the Arduino Module? Are there image processing models that can be deployed on the Arduino? Please help me get started.
Update: March 24th: I was able to update the code ArduCAM_Mini_2MP_OV2640_functions.ino to the Arduino, and read-write to the serial port through usb. However, the bytes read do not seem to ba a JPEG image. How do I understand the stream of bytes that are returned?
ser = serial.Serial('COM3', 115200)
ser.write(b'8')
ser.write(b'\x10')
import time

# Read the size of the JPEG data buffer from Arduino
f = open('image.jpg', 'wb')
print('Send Pic')
i = 0
while i < 10:
    if ser.in_waiting > 0:
        data = ser.read(1)
        print("Received:", data)
        # Write the JPEG data to a file
        f.write(data)
    else:
        print(i)
        i += 1
        time.sleep(1)

f.close()

You said: "I want to run a OpenCV like library on the Arduino Module". There are many Arduino platforms, but likely most of them would run out of resources before any significant amount of the OpenCV library was ported to them.

That is correct; This is a hobby project. The idea is to build and deploy a model onto the board - and use it to take an action based on it.


text:
Heltec WiFi LoRa 32 (V3) - Encode/decode packets to binary (make message shorter)
I'm using Heltec WiFi LoRa32 boards (ESP32-S3 + SX1262).
Could you please help me how to encode data e.g. from temperature and humidity sensor into binary or hexadecimal form - to make the LoRa packet length shorter? Similar to what LoRaWAN does.
For example I have two values:
float temperature = 21.56;
float humidity = 76.21;

I use the official Heltec library for LoRa radio (https://github.com/HelTecAutomation/Heltec_ESP32/blob/master/src/radio/radio.c), I only transfer data via LoRa (not LoRaWAN), so it is necessary to make it work with the library function Radio.Send().
Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); //send the package out

I found this example: https://create.arduino.cc/editor/LogMaker360/770f60c9-52c5-4d29-b417-4804b278db20/preview
and this tutorial: https://www.thethingsnetwork.org/docs/devices/bytes/
I'm confused in this, so I would appreciate a parto of code example compatible with Heltec library for encoding and decoding compatible with Heltec library functions.
Thank you

21.56 can be represented by two bytes as 2156

If you want to send both temperature and humidity in a single packet,
the easiest way is to define the packet as a struct with two fields:
struct LoraData {
    float temperature;
    float humidity;
};

You can then send the raw bytes by typecasting the address of such a
struct to uint8_t*. This, however, is generally not recommended,
because it violates C++ type aliasing rules. You can circumvent this
issue by defining a union:
union LoraPacket {
    LoraData data;
    uint8_t bytes[sizeof(LoraData)];
};

This represents an area of memory that can be interpreted as containing
either the numeric data data, or an array of bytes. Then you can fill
the data field and send the raw bytes:
void send_dummy_data()
{
    LoraPacket packet = {
        .data = {
            .temperature = 12.56,
            .humidity = 76.21
        }
    };
    Radio.Send(packet.bytes, sizeof packet);
}

At the other end, you do the same thing backwards: you fill in the bytes
and read back the numeric data:
void rx_done(uint8_t *payload, uint16_t size, int16_t, int8_t)
{
    if (size != sizeof(LoraPacket)) {  // sanity check
        Serial.println("Bad packet size");
        return;
    }
    LoraPacket packet;
    memcpy(&packet.bytes, payload, size);
    Serial.print("temperature: ");
    Serial.println(packet.data.temperature);
    Serial.print("humidity: ");
    Serial.println(packet.data.humidity);
}

Radio.Send( (uint8_t *)txpacket, strlen(txpacket) );

Noted that strlen(txpacket) is only applicable if the txpacket is a string. Since temperature is a floating point value, it should be sizeof(temperature)(see further explanation below).
I think there is a misunderstanding that this send a "shorter" data because you saw the uint8_t, but it is not the case. A single-precision floating point data is stored as a 4-byte data in according to IEEE754 format. What the RadioSend((uint8_t *) temperature, sizeof(temperature)) does is it simply cast the floating point value to a pointer of byte (i.e. uint8_t) that is point to the beginning of the temperature in memory so that it can send the data byte-by-byte, the sizeof(temperature) is equivalent to sizeof(float) so it is equal to 4. The data that going through the radio transmission is still 4-byte floating point value.
To send the temperature and humidity, you just need to send the temperature and humidity data as:
float temperature = 21.56;
float humidity = 76.21;

RadioSend((uint8_t *) temperature, sizeof(temperature));
RadioSend((uint8_t *) humidity, sizeof(humidity));

However, as point out by @jsotola, if you want, there is a way to reduce the data to be sent from 4-byte floating point to 2-byte int16_t by converting the float to int16_t by multiply the floating point value with 100. The converted data is only 2-byte long as an int16_t without losing the precision of the floating point (which has precision of 2 decimal points).
float temperature = 21.56;
float humidity = 76.21;

int16_t temperature_in_integer = (int16_t) temperature * 100; // integer 2156
int16_t humidity_in_integer = (int16_t) humidity * 100;  // integer 7621

// send 2-byte each
RadioSend((uint8_t *) temperature_in_integer, sizeof(temperature_in_integer));
RadioSend((uint8_t *) humidity_in_integer, sizeof(humidity_in_integer));

On the receiving end, the received data need to be divided by 100 to get back the actual temperature and humidity value.
If this is a little confuse to you, I would suggest you pick up a book of C or C++ and learn the foundation of  data types, data casting and pointer.

Glad to hear that, if this helps, consider to accept it as answer by clicking the "tick" sign.

But what about if I want to send the values in one packet - how to pack it? Especially when on some nodes I measure different kind of values?
And how to deal with the received data on the receiver's side?
Thanks

You don't need to purposely pack it, it send 4+4 bytes. Personally I don't know how internally the RadioSend and Lora handle the data, so I can' really answer that. For receiving, the int16_t data is quite straightforward. For float, you can read my answer to this question on how to read back the float from the received buffer.

I need to send all values in one packet and then on the receiver's side decode it and seperate the palyoad to individual values. Is this possible?

Come to think about it, You can create an array of float (or a struct of float) and send in 8-byte all together. array[0] be the temperature value and array[2] be the humidity value.

I also has an example on my blog which show pack temperature and humidity in a struct and send over transmission. You can take a look at that. If you have further question, you should raise in a separate question, the StackOverflow/StackExchange is better for one question at a time. Not keep adding questions when one has been answered.

Ok, and is it possible to somehow ensure that when measuring different variables to determine which variable is in the packet at a given position or do I just need to know?
For example, if I send temperature and humidity from one device and pressure, voltage and current from another?
Or just have a position for each variable in the packet, and in case it will not be measured leave for example zero?
Thanks


text:
Heltec WiFi LoRa 32 (V3) - Difference of various datatype packets length
I'm using Heltec WiFi LoRa32 boards (ESP32-S3 + SX1262).
For example I have two measured values:
float temperature = 21.56;
float humidity = 76.21;

I use the official Heltec library for LoRa radio (https://github.com/HelTecAutomation/Heltec_ESP32/blob/master/src/radio/radio.c), I only transfer data via LoRa (not LoRaWAN), so it is necessary to make it work with the library function Radio.Send().
Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); //send the package out

I would like to know if I spare the data length amount when I'll send values via LoRa in floats like:
void loop() {
  if (lora_idle)  {
    delay(1000);
    Paylaod payload;
    payload.temperature = random(-1000, 1000) / 10.0;
    payload.humidity = random(0, 101) / 100.0;

    Radio.Send( (uint8_t *)&payload, sizeof payload);
    Serial.print("sending packet: temperature = ");
    Serial.print(payload.temperature, 2);
    Serial.print(" and humidity = ");
    Serial.println(payload.humidity, 2);
    lora_idle = false;
  }
  Radio.IrqProcess( );
}

instead of sending them as chars like:
#define BUFFER_SIZE 30 // Define the payload size here

char txpacket[BUFFER_SIZE];

void loop()
{
    if(lora_idle == true)
    {
    delay(1000);

        sprintf(txpacket,"21.5676.24");  //start a package

        Serial.printf("\r\nsending packet \"%s\" , length %d\r\n",txpacket, strlen(txpacket));

        Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); //send the package out
    lora_idle = false;
    }
  Radio.IrqProcess( );
}

If I spare the number of transmitted bytes, how many bytes occupy one character in char txpacket[BUFFER_SIZE]?
Thanks

what are you using to measure temperature and humidity?

I'm using SHT31 sensor

the sensor is not accurate to two decimal places... it makes no sense to transmit floating point values

It basically doesn't matter which values are transmitted, but my question is how to effectively send  multiple values by LoRa.

Does this answer your question? Heltec WiFi LoRa 32 (V3) - Encode/decode packets to binary (make message shorter)