text:
Display images on Arduino LCD screen from PC
I am new to arduino and I am wondering if it is possible to store image data on my computer and send it to my arduino over the USB cable (which is also used for power) to display on a TFT LCD display I have hooked up. All the tutorials I see involve using an SD card to preload the image data on there beforehand.
Still, my display doesn't have an sd card slot, nor is it practical for my application as the images I want to display will be determined during runtime. I have sent small pieces of data over the COM port to my arduino from my PC but I don't know how I could do it with potentially large image data. The arduino will be plugged into my computer 24/7. If this is possible could I get a little guidance on where to start?  Thank you

receive the data and display it as it is being received

Since you don't give a clue about the TFT you have in mind, I'll try to describe the process using the following assumptions about the TFT that have to be true for the rest to work:

one full frame of pixel data for the TFT used would not fit into the Arduinos RAM, but one line of that frame will,
the pixel data can be sent line by line to the TFT without a need to start the next line inside a certain timeframe (i.e. you could, in theory, just tell the TFT to update line 42 out of order, as an example),
the TFT has its own way of remembering its display data (i.e. does not need a continuous refresh 60 times per second).

In this scenario, your image processing pipeline looks like this:

A program running on your PC decompresses (and possibly resizes) the image file in order to get access to the raw pixel data as it would be displayed on the TFT. This means that this program needs to know the resolution and "data feeding order" of your TFT.
This process then takes one line of the raw pixel data and converts it into a data package to be sent over the serial port. You will need to devise a communication protocol here that your Arduino sketch can work with. The easiest, but not most efficient, way would be to convert it into Base64, because libraries for that exist in practically every language and platform and you are then able to use text-based delimiters like a line break to mark the end of a pixel data line. (Sending binary data is more efficient, but harder and more prone to sychronization errors, because you have no in-band signalling of "end of data line".)
Your Arduino sketch reads that data package (if Base64-encoded: by using Serial.read until you encounter a line break) and converts it back to raw pixel data, in whatever format your TFT (or library for that TFT) needs the data (it might require the color format in e.g. GRB instead of RGB).
This raw pixel data line is then sent to the TFT.

You will have to determine the baud rate you can send over your serial link (determined by maximum baud rates of both PC and Arduino, and sometimes the cable quality in between). Keep in mind that a serial connection is slow; you probably will be able to watch the image rendering on the TFT line by line.
You may be able to make this more efficient by employing something like RLE (Run-Length Encoding) on the pixel data sent over the serial line, but that would be another iteration of your protocol.

Perhaps I am wrong, but TFT LCD stands for Thin Film Transistor LCD, correct?  This description applies to many types of LCDs.  The vast majority of them do not work as described in the answer.  Specifically, it will be very difficult to impossible for an Arduino Uno to display anything on a vast majority of TFT LCDs.

@st2000 OP insinuated that they already have found a tutorial to display something on their TFT, so I stated in my assumptions what that TFT or library must be able to do in order to support this solution.

Ok.  Say so in the answer (something like: I assume you have this or that smart serial port LCD) and I'll upvote it.  Recall that the point of stackexchange sites are to help other people with similar problems find clear / concise answers.

You could "stream" the data from the PC to the LCD, which means you wouldn't need to store it (or maybe store a line or so).
Without knowing which Arduino and which LCD it is hard to give more advice than that.

There are so many different LCDs that with out specifying a specific LCD only very general answers can be provided that may be of limited value.

Just about all Arduinos can handle an Alpha Numeric LCDs. But these have very limited graphics, if any.

Most can handle low resolution B&W Graphics LCDs.

Most can handle sending geometric shapes and alpha numeric to (smart) Serial Port Color LCDs. Only some Arduinos will be able to handle sending arbitrary images (like a photograph) to (smart) Serial Port Color LCDs.

And few will be able to handle sending data to a common TTL or LVDS Color LCDs.


text:
Problem with reading data from ELM327
The idea was to create a bluetooth device on the arduino to read data from the machine (ELM327 v2.1) using the HC-05 bluetooth module.
In this code the bluetooth module is switched to MASTER mode and connected to ELM327 using its MAC address. The responses of the module in the code are in the comments.
#include <SoftwareSerial.h>
SoftwareSerial bluetoothSerial(4, 5);

void setup() {
  Serial.begin(9600);
  Serial.print("READY");
  bluetoothSerial.begin(38400);
  delay(1000);
  getSetAtCommand("AT");                         //OK
  getSetAtCommand("AT+CMODE=0");                 //OK
  getSetAtCommand("AT+PSWD=1234");               //OK
  getSetAtCommand("AT+ROLE=1");                  //OK
  getSetAtCommand("AT+BIND=0010,CC,4F3603");     //OK
  getSetAtCommand("AT+LINK=0010,CC,4F3603");     //OK
  delay(1000);
  getSetAtCommand("AT+STATE?");  // OK: CONNECTED
  delay(1000);
  getSetAtCommand("ATZ");      //no answer, the buffer is empty
  getSetAtCommand("AT015B");//no answer, the buffer is empty
  getSetAtCommand("015B");      //no answer, the buffer is empty
  getSetAtCommand("ATRV");   //no answer, the buffer is empty
  getSetAtCommand("0105");    //no answer, the buffer is empty
  getSetAtCommand("at i");   //no answer, the buffer is empty
  getSetAtCommand("at rv");   //no answer, the buffer is empty
  getSetAtCommand("ati");    //no answer, the buffer is empty
  getSetAtCommand("atrv");   //no answer, the buffer is empty
}

void loop() {
}

void getSetAtCommand(String command) {
  Serial.println(command);
  String added_command = command + "\r\n";
  bluetoothSerial.print(added_command);
  delay(500);
  while (bluetoothSerial.available()) {
    Serial.write(bluetoothSerial.read());
  }
}

Since the State returns CONNECTED, I assume that it is connected to the ELM.
To the command AT+PAIR=0010,CC,4F3603,20\r\n the module does not respond. The module also does not respond to commands such as ATZ\r\n, AT015B\r\n, 015B\r\n, ATRV\r\n, 0105\r\n, at i\r\n, at rv\r\n, ati\r\n, atrv\r\n. Sometimes the answer is ERROR[0], as I understand it means that there is no such command.
It seems to me that these commands don't reach the ELM at all. What can be the problem?
The ELM327 itself works, connects to the phone without any problems and shows the data.
Tried through the simulator on a laptop, the connected bluetooth model is displayed in the bluetooth devices on the laptop and also does not work as with the ELM.

Do you have a manual or doc for ELM327 v2.1 that you can share?

@Fahad unfortunately not if you find on the Internet

I can't seem to find it. How do you know of the AT commands? Is there an instruction somewhere?

try AT$ ... it worked on old modems to display the available command set ... maybe the command is also implemented in your device

source: Stack Exchange

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

sort: votes


text:
Controlling Stepper motor using RC receiver
I am using Arduino UNO with a DM556 Micro step driver to control the Stepper motor.
PUL+ --> pin 3
DIR+ --> pin 5
RC receiver --> pin 2
Using CH2 of receiver
With out the RC receiver (R9SX) everything works fine, the motor works perfectly. However I cannot figure out how to control it with RC. I tried to find a tutorial using Micro step driver but everybody appears to use Arduino Nano or some other equipment.
The code I am using makes the motor work extremely slow and only in one direction.
I'd really appreciate it if some one can point error in my code or provide me with a suitable one for my use case.
CODE:
// Define Pins
#define RCPin 2
#define DIR 5
#define STEP 3

// Set up time variables for Stepper motor
unsigned long previousMotorTime = millis();
long MotorInterval;

// Set up time variables for RC Read
volatile long Pulses = 0;
int PulseWidth = 0;

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

  // RC Read Setup
  pinMode(RCPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(RCPin), PulseTimer, CHANGE);

  // Set DIR and STEP pins to OUTPUT
  pinMode(DIR, OUTPUT);
  pinMode(STEP, OUTPUT);

  // Set initial direction (LOW = one direction, HIGH = the other direction)
  digitalWrite(DIR, LOW);
}

void loop() {
  digitalWrite(STEP, LOW);

  // Only save HIGH pulse lengths
  if (Pulses < 2000){
    PulseWidth = Pulses;
  }

  // Stepper motor speed, bigger MotorInterval is a slower speed.
  if (PulseWidth >= 1400 && PulseWidth <= 1600) {
    digitalWrite(STEP, LOW); // Motor doesn't move if the joystick is near the midpoint
  } else if (PulseWidth < 1400) {
    digitalWrite(DIR, LOW);
    MotorInterval = map(PulseWidth, 1000, 1400, 1, 25); // Map the RC signal to the motor speed in reverse when the joystick is pulled down
  } else if (PulseWidth > 1600) {
    digitalWrite(DIR, HIGH);
    MotorInterval = map(PulseWidth, 1600, 1984, 25, 1); // Map the RC signal to the motor speed when the joystick is pushed forward.
  }

  // Check if the MotorInterval time has elapsed and step the motor.
  unsigned long currentMotorTime = millis();
  if (currentMotorTime - previousMotorTime > MotorInterval) {
    digitalWrite(STEP, HIGH);
    previousMotorTime = currentMotorTime;
  }
}

// Function to measure the length of the pulses from the remote control
void PulseTimer() {
  static long StartTime = 0;
  long CurrentTime = micros();
  if (CurrentTime > StartTime) {
    Pulses = CurrentTime - StartTime;
    StartTime = CurrentTime;
  }
}

Do you have a spec sheet for your motor?

reduce your program to only the minimal code required to spin the motor in one direction at the highest speed ... does it turn fast enough?

I used some other sketch to check this and it works great.

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


text:
Reading from DHT22 with Arduino, powered by external source
I have the following situation. When I power my DHT22 with the 3.3V from the Arduino UNO (and Ground it there), then I can read the data perfectly fine using the DHT library from Adafruit.
However, when I connect the DHT22 to my own external power supply (and respective ground), it fails. The reason for using this external power supply is so I can hook it up to a ESP8266 later.
The power supply I build uses a 5V adapter, then an LD33V converter and (just for experimentation) an 100nF capacitor to reduce any noise on the line.
I measured this external power supply and it indeed gives off 3.3V after the LD33V. I check the datasheet of the LD33V and it should be able to 'give' 5mA, whereas the DHT22 needs less than 1mA for operation.
I don't know where to look at this moment. Can someone point me in the right direction? Much appreciated :)
Cheers

Have you connected the external power supply ground to the Arduino's ground? If not, one is "floating" with respect to the other. But they need to have the same reference - the ground sides of their power supplies.

Ah, I edited the question to make that a bit more clear. When I power with the arduino, I use the ground provided by the arduino. When I use my own power supply, I use the ground provided by that. So to my idea nothing is 'floating' if I understand you correctly

When I now attach the signal pin of the DHT22 to my Arduino, and power the DHT22 with my own power supply (and ground it there) AND connect a ground to the arduino. THEN I can measure the temperature on the arduino. Thanks

Perfect. "Floating" just means the two grounds are not (necessarily) at the same level. "... AND connect a ground to the arduino" is exactly what had been missing.


text:
Issues using mini microphone module off AliExpress
I have been trying to get a mini microphone module with an inbuilt microphone module I got from AliExpress to my Arduino to confirm if it is working. It was a four pin microphone with pins labeled V, L, and two G pins. The V represents voltage in and the L represents audio output positive.
Here is the link to the microphone:
https://www.aliexpress.com/item/1005004277353392.html?spm=a2g0o.productlist.main.23.61e36f2fBMHvFk&algo_pvid=15b05576-cd73-4eb7-a476-4503b8a706a7&algo_exp_id=15b05576-cd73-4eb7-a476-4503b8a706a7-11&pdp_npi=3%40dis%21USD%210.54%210.39%21%21%21%21%21%40211bf3f716869249882567444d07ba%2112000028601598840%21sea%21NG%214345576938&curPageLogUid=plaZEQWq7SRB
However, when I ran the code to check whether it works the value does not change that much, Is there something I'm doing wrong (I'm a beginner btw) or is the microphone not just working?
My code
const int audioPin = A0; // Analog input pin connected to the microphone module output

void setup() {
  Serial.begin(9600); // Initialize the Serial Monitor
}

void loop() {
  int audioValue = analogRead(audioPin); // Read the analog value from the microphone module

  Serial.println(audioValue); // Print the analog value to the Serial Monitor

  // Add a small delay to control the rate of readings
  delay(10);
}

I connected the output (L) to A0 and connected both the G pins to the arduino ground, I connected the V pin to the 3.3V pin on the Arduino Uno.

Does your Uno operate at 3.3V or 5V? If it's 5V, you can power the microphone module with 5V which may help. The images the seller provides do not show the bottom of the circuit board. Assuming there are no components on the other side of the board, the amplification provided by the components we can see will be limited. If you have access to an oscilloscope, you could verify the module is not defective.

What much exactly is "not much"? The module looks, like a raw microphone with a simple amplifier circuit, but without any further processing. Thus you would get directly the signal on your analog pin, which is an alternating voltage (probably around 0.5*V (aka 2.5V on 5V supply voltage), where you need to sample at least 2 times as often as the highest frequency, that you want to measure (nyquist frequency). Also this module will probably not provide enough gain to fill the full 5V range, that you have with the Uno.

The arduino operates by 5V btw, and when I say the value does not change much when I check my Serial Monitor, it gives a value of about 400 to 460 varying a lot and even when I speak to the microphone, it does not seems to go higher than that or change. I was thinking that it was noise. I am not so familiar with an oscilloscope, but when I connected it to the oscilloscope, it seemed to have a lot of noise, with repeating patterns even when I was not speaking to it and when I did speak to it, I could not tell if it was detecting it or not.

If you can't detect the sound on an oscilloscope, then the Arduino won't detect it either, so you would need to get a better microphone module. Also think about what you want to do with the sound module. The Uno is not really capable of audio processing (or at least very limited in it)

If you look carefully on the PCB, it has an AC-coupling capacitor on the L line which block the DC bias from the transistor, and you only get half of the signal. You need to connect the Arduino Analog input directly to the transistor output (i.e. to bypass the capacitor). You can measure the DC voltage at the output transistor, if it is at 1.5v without input signal, you will get +/- xxxmV swing against 1.5v that you can read with the Arduino analog input.

Have you checked to see if it is a hardware problem? It could be the fact that it is just off AliExpress. Usually, the display images are better than the actual product and if this is true, you can see a few bad soldering connections. I might want to go over some of them with a soldering iron.


text:
5v hall current sensor with a 3v3 mcu
current sensor (5v) with a 3.3v MCU
I am trying to make a hall effect current sensor (ACS712ELCTR-20A-T) work with a 3.3v MCU.
The current sensor is powered with 5v. I specifically choose this sensor because I need to measure current up to 7A powering a led strip. I know INA219 is easier to use (i2c) but it can only read up to 3A.
My ACS712 has a sensitivy of 100mV/A according to the datasheet.
Here is my code :
void getCurrent() {
  //float acs_rest_voltage = (float) (analogRead(currentPin) * (3.3 / 1023));
  float acs_value = 0.0, acs_sum = 0.0, acs_rest_voltage = 2.5;

  for (uint8_t i = 0; i < 11; i++) {
    acs_sum += analogRead(currentPin);
    delay(3); // wait for the ADC to settle
  }
  acs_value = acs_sum / 11;

  float currentRaw = ((((acs_value) * (3.3 / 1023.0)) - acs_rest_voltage) / 0.100);

  //current = 2.178956044 * currentRaw - 0.2223241758; // linear regression calibration
  current = currentRaw;

  if (current < 0.0 || current > 321.0) {
    current = 0.0;
  }
}

it reads 11 samples, averages them, applies a formula, and returns the current.
The returned current value is so inaccurate that I even tried to apply a linear regression calibration formula.
The wiring is quite simple :
ACS712 has VCC to 5v rail.
MCU (seeeduino xiao) has vcc to 3.3v through a LDO voltage regulator (AMS1117).
So ACS712 and MCU share the same ground.
ACS712 data out pin goes to MCU analog pin (I believe adc is 10 bits) through a voltage divider. I assumed DOUT could output up to 5v so i divided accordingly so the MCU can get 3.3v max data.
This did not work great (inaccurate values).
I was so desperate that I even tried plugging the ACS712 data OUT to the MCU directly. Since my current wont reach more than 10A, i'm confident it wont output more than 3.3v (it outputs 100mv/A)
Here are 2 schematics of 2 options I tried :

The voltage measured at ACS712 data out when current is zero is 2.5v
When i increase the current (higher brightness on led strip), here is something weird : the voltage I read with my DMM decreases when the amps increases... ? ? ?
I must be doing something wrong, either circuit or code (or both)

swap the contacts on the ACS712. it is intended to measure AC with the output oscillating around 2.5 V

@Juraj I'm afraid I already tried it as well. Believe it or not, it behaves the same : voltage read at the DMM decreases as the current increases

you can "overclock" an INA219 by adding two more 0.1ohm resistors in parallel with the module's built-in one, then multiplying any read current values by 3.

@dandavis I will give it a try. How accurate would it be ?I think the problem is the ACS712 chip, I measure voltage at OUT pin with a DMM for currents at 0A, 1A, 2A, 3A : the response is non-linear.

The output of 2.5V for 0A is as specified by the datasheet. For increasingly negative currents the voltage will decrease. For increasingly positive currents it will increase. So these symptoms by themselves don't really indicate a problem. Through I would expect the direction of voltage change to switch between positive and negative depending on the direction of the current through the sensing inputs. Are you sure, that this doesn't change, when you swap the input current contacts?

the ina would be very accurate, and can be calibrated to near perfection. the precision would be 1/3rd of the pre-modification value, which is still pretty good for many things.

@chrisl You are right. It increases when I switch the inputs. I am confused now because I tried it many times already. Anyways, I really think the acs712 chips are potatoe. The 100mV/A claim is wrong. Quiescent voltage reads 2.5V, when I increase to 1A it wont read 2.6V at my DMM, neither would it read 2.7V when my PSU outputs 2A. Worst : the change is not even something I could translate into something like y=ax+b. The problem with the INA219 is that it is a shunt, not a hall effect, so I can not power the INA with the same power source it reads.


text:
Arduino Uno R3 assembly code to push a button and turn on a LED
I've been trying this for days without success...
I need to turn on a LED on portb when a button in portd is pushed. Cabling works, I've tested it with Arduino IDE and it works like a charm.
This is what I got so far:
.global main
.equ LED, PB5
.equ BUTTON, PD3
main:
   ldi r22,0xff                    ;all bits in portb are output
   out _SFR_IO_ADDR(DDRB),r22
   ldi r21,0x00                    ;all bits in portd are input
   out _SFR_IO_ADDR(DDRD),r21
   ldi r19, 0b00000000             ;unpushed button
   ldi r18, 0b00100000             ;pushed button
   eor r16, r16
loop:
   out BUTTON, r16                 ;read button to r16
   cp r16, r18                     ;compare r16 with r19 (button on)
   cbi _SFR_IO_ADDR(PORTB),LED
   breq loop                       ;go back to loop
   sbi _SFR_IO_ADDR(PORTB),LED     ;if z=1, turn led on turn led on
   rjmp loop                       ;back to loop

It is much easier with sbis, if I got it right...
#include <avr/io.h>
.equ LED, PB5
.global main
ldi r16,0xff
out _SFR_IO_ADDR(DDRB),r16
ldi r16,0x00
out _SFR_IO_ADDR(DDRD),r16

main:
    sbis portd, 3
    rjmp ledoff
    ldi r16,0xff
    sbi _SFR_IO_ADDR(PORTB),LED   ; turn on led
    rjmp main
ledoff:
    ldi r16,0x00
    cbi _SFR_IO_ADDR(PORTB),LED   ; turn off led
    rjmp main

But I got this error compiling:
.pio\build\uno\src\main.o: In function `main':
(.text+0x8): undefined reference to `portd'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\uno\firmware.elf] Error 1

This line:

   ldi r18, 0b00100000             ;pushed button

does not match the definition of BUTTON. You are setting bit 5 of
the register, whereas the button is on bit 3. In order to avoid
this kind of error, I would rather write
   ldi r18, _BV(BUTTON)            ;pushed button

Then, here:

   out BUTTON, r16                 ;read button to r16

you are not reading anything: you are writing somewhere. I guess you
mean:
   in r16, _SFR_IO_ADDR(PIND)      ;read button to r16

Note that this reads the whole port at once. If you are only interested
in one bit, you should then
   andi r16, _BV(BUTTON)           ;keep only the relevant bit

before the comparison.
One last thing: you may want to read about the sbis and sbic
instructions: they could simplify the code you have here.

Edit: answering the updated question.

undefined reference to `portd'

This is because there is no such thing as “portd”. You mean
_SFR_IO_ADDR(PORTD). Well, no, you should actually use
_SFR_IO_ADDR(PIND), as this is the port input register, whereas
PORTD is the output register.
A couple of extra notes:

Do not put code before main: it will not be executed, as the C
runtime jumps to main after its initialization.
The instructions ldi r16, … within the main loop serve no purpose:
you are not using this register after the program initialization.


text:
With reference to Arduino Keyboard library, it does not have a keymap for UK keyboard, has anyone created a KeyboardLayout_en_UK.cpp file for this?
With reference to the Arduino Keyboard library, it does not have a keymap for the UK keyboard. I have tried to find a keyboard map that shows the hex value for the UK keyboard but I didn't have any luck.
If you look in the Arduino Keyboard library: Arduino\libraries\Keyboard\scr\KeyboardLayout_en_US.cpp
it has some other languages but no keyboard layout for a UK keyboard.
It does say somewhere I think on GitHub that a keyboard layout file can be added, but where can I get that file or how can I create that file?
Has anyone already created a KeyboardLayout_en_UK.cpp file I could use, please?

Edgar Bonet, a regular contributor here, has some additional layouts at https://github.com/arduino-libraries/Keyboard/tree/master/src - however the UK keyboard doesn't seem to be present. He can probably help you, no doubt he will see this post shortly.

Thanks for useful info

As an example of what you might do ...
First copy the file KeyboardLayout_en_US.cpp and rename it as KeyboardLayout_en_UK.cpp.
Most of the entries will be the same. Now looking at the layout in https://github.com/arduino-libraries/Keyboard/blob/1.0.4/src/KeyboardLayout.h we see this:
  +---+---+---+---+---+---+---+---+---+---+---+---+---+-------+
  |35 |1e |1f |20 |21 |22 |23 |24 |25 |26 |27 |2d |2e |BackSp |
  +---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-----+
  | Tab |14 |1a |08 |15 |17 |1c |18 |0c |12 |13 |2f |30 | Ret |
  +-----++--++--++--++--++--++--++--++--++--++--++--++--++    |
  |CapsL |04 |16 |07 |09 |0a |0b |0d |0e |0f |33 |34 |31 |    |
  +----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---+----+
  |Shi.|32 |1d |1b |06 |19 |05 |11 |10 |36 |37 |38 |  Shift   |
  +----+---++--+-+-+---+---+---+---+---+--++---+---++----+----+
  |Ctrl|Win |Alt |                        |AlGr|Win |Menu|Ctrl|
  +----+----+----+------------------------+----+----+----+----+

The third key along the top row of my (US) keyboard (below the function keys) has @ on top and 2 on the bottom. It has the code 1f in the chart.
In the US layout file we see, in part:
0x2c,          // ' '        0x20
0x1e|SHIFT,    // !          0x21
0x34|SHIFT,    // "          0x22
0x20|SHIFT,    // #          0x23
0x21|SHIFT,    // $          0x24
0x22|SHIFT,    // %          0x25
0x24|SHIFT,    // &          0x26
0x34,          // '          0x27
0x26|SHIFT,    // (          0x28
0x27|SHIFT,    // )          0x29
0x25|SHIFT,    // *          0x2a
0x2e|SHIFT,    // +          0x2b
0x36,          // ,          0x2c
0x2d,          // -          0x2d
0x37,          // .          0x2e
0x38,          // /          0x2f
0x27,          // 0          0x30
0x1e,          // 1          0x31
0x1f,          // 2          0x32
0x20,          // 3          0x33
0x21,          // 4          0x34
0x22,          // 5          0x35
0x23,          // 6          0x36
0x24,          // 7          0x37
0x25,          // 8          0x38
0x26,          // 9          0x39
0x33|SHIFT,    // :          0x3a
0x33,          // ;          0x3b
0x36|SHIFT,    // <          0x3c
0x2e,          // =          0x3d
0x37|SHIFT,    // >          0x3e
0x38|SHIFT,    // ?          0x3f
0x1f|SHIFT,    // @          0x40

I've put the positions of each entry on the right (the offset from the start of the array).
So looking at that table, when the scan code 1f arrives, and SHIFT is pressed, we get 0x40 which is indeed @ in the ASCII table.
Similarly, 1f without SHIFT gives us 0x32 which is 2 in the ASCII table.
Now in your case I believe that key gives " when SHIFT is pressed, so the third line from the top in my example changes from:
0x34|SHIFT,    // "          0x22

to:
0x1f|SHIFT,    // "          0x22

And likewise for the other keys. So, the @ symbol moves to where the quote is in the US keyboard. So change the last line in my example from:
0x1f|SHIFT,    // @          0x40

to:
0x34|SHIFT,    // "          0x40

Those two changes "swap" the locations of the " and the @ symbols.

As noted in the comments, keys marked ¬ and £ do not have a 7-bit ASCII representation so you will not be able to put them in the table (there is no entry for them).

Thanks for this, I'm just getting down to figuring this out myself and this info is really helpful.

I am not aware of a UK layout file for the Arduino Keyboard library. The
library itself does not have such a layout, and a Web search returned
nothing. You may consider creating this layout yourself. The
documentation of Keyboard.begin() states:

Custom layouts can be created by copying and modifying an existing
layout. See the instructions in the Keyboard library’s
KeyboardLayout.h file.

The file KeyboardLayout.h does indeed have detailed
instructions for this. Are they clear enough? If not, please tell me: I
wrote those instructions, and I may try to update them if something in
them is confusing.
Do you feel like trying to create this layout yourself? If so, it would
be nice if you could submit it to the official library as a pull
request. This way other users of the library may benefit from your work.
If you don't feel like doing it, I may give it a try (I have already
created a few of them). In this case, I would appreciate if you could
submit an issue, just to show the maintainers that there is some
interest in having the library provide this layout.

Thanks for your help, I guess I will have a go at creating a KeyboardLayout_en_UK.cpp file

I'd suggest that the one addition which could usefully be made to those instructions is the explicit statement that this only supports 7-bit ASCII. So while a UK keyboard has keys marked ¬ and £, there are not corresponding ASCII codepoints.

@MarkMorganLloyd: “7-bit ASCII” is a pleonasm. Would the sentence “Non-ACSII characters are not supported.”, added to the end of the first paragraph, be suitable? Or should I add “anything outside the range NUL..DEL” in parentheses to explain “Non-ACSII characters”?

@EdgarBonet Either of those forms should do, but remember that a lot of people don't really understand that various codepages etc. based on "extended ASCII" are well outside the original ASCII specification. My experience is that the terms "7-bit ASCII" and "8-bit Extended ASCII" are well-understood, even though I know at least as well as you do that neither is strictly correct.

@MarkMorganLloyd: OK. I submitted the clarification in a pull request

@EdgarBonet I have created a KeyboardLayout_en_UK.cpp file and added to my Arduino keyboard library also I changed Keyboard.h to include the line: extern const uint8_t KeyboardLayout_en_UK[];  I am not very familiar with GitHub and not confident about making a pull request at this time.


text:
NRF24L01 PA+LNA With Arduino
I am using the NRF module for remote communucation.I have been many research about nrf but my nrf module is not working This is my tranmistter code:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

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

const byte address[6] = "00001";

void setup() {
  Serial.begin(115200);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setRetries(15,15);
  radio.setPALevel(RF24_PA_HIGH);

}

void loop() {
  radio.stopListening();
  const char text[32]="Hello world";
  if(radio.write(&text,sizeof(text))){
    Serial.println("Mesaj gönderildi");
  }
  delay(1000);

This is my receiver code:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

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

const byte address[6] = "00001";

void setup() {
  Serial.begin(9600);
  radio.begin();
  delay(400);
  radio.openReadingPipe(1, address);
  radio.setPALevel(RF24_PA_MAX);
//  radio.startListening();
   pinMode(10,OUTPUT);

}

void loop() {
 const char text[32]="";
  radio.startListening();
  if(radio.available())
  {
    while(radio.available()){
    radio.read(&text[0],sizeof(text[0]));
    Serial.println(text);
    delay(1000);
    }
  }
  delay(5);

}

ı tried the setPAlevel min but there is no change.In the transmitter side the write function returns true, but I can't get anything on the receiver side. Also, if I replace the cable connected to miso with the cable connected to mosi on the transmistter side, the write function still returns true. I also used adaptor ams1117

From your Receiver code: radio.read(&text[0],sizeof(text[0])); This looks odd. sizeof(text[0]) is only one byte.

I tried this buy now ı am trying gettinstarted examples in arduino.Mosi and miso pins does not connect to microcontroller but output which ı take is this:Tranmission successful.

Also.I get a radio hardware not responding error when mosi is connected to the arduino mosi pin on the adapter and miso on the adapter is connected to the miso pin on the arduino.When I reverse the cables and connect them, the transmission and reception occur.

const char text[32]=""; from the receiver also looks odd because this buffer is supposed to be writable. Anyway, use the code from the thread here: https://forum.arduino.cc/t/simple-nrf24l01-2-4ghz-transceiver-demo/405123 to test your nrf24L01 devices. Most problems with these nrf24L01 devices are related to inadequate power supplies.

"When I reverse the cables and connect them, the transmission and reception occur." Does this mean that if you cross over MISO and MOSI on the nrf24L01 adapter board,  it all works as expected? I'd be surprised considering the other errors but I suppose it could be a labeling error somewhere.

Yes.But this only happens at the very beginning. I uploaded the program to Arduino, then I get a radio hardware not responding error. Then I plug the mosi cable on the nrf board into the miso on the arduino. The radio hardware not responding error goes away. Transmissin timed out error comes.Then, after plugging the mosi in the nrf module into the mosi on the arduino, and the miso on the miso on the arduino, the transmission becomes successful.

In the receiver code, you are just reading one byte, as 6v6gt pointed out. Check the library to see how read() works.
If you follow the getting started example, this is how you should read bytes in the receiver:
char text[32];

if (radio.available())
{
  uint8_t bytes = radio.getPayloadSize();  // get the size of the payload
  radio.read(&text, bytes);                // fetch payload from FIFO
}

Don't use const for text in the receiver.
Also, you don't need to use stopListening and startListening in the loop(). They should just go to setup().

Tranmission failed or timed out erros is occured.I tried many things but this error is still continues

Update the code in the question that you tried last.


text:
Need help individually controlling 3 LEDs with 3 toggle switches
I'm trying to individually control 3 LEDs with 3 toggle switches. This is the code I'm using
#define LED_PIN1 2
#define BUTTON_PIN1 14

#define LED_PIN2 3
#define BUTTON_PIN2 15

#define LED_PIN3 4
#define BUTTON_PIN3 16

void setup() {
  pinMode(LED_PIN1, OUTPUT);
  pinMode(BUTTON_PIN1, INPUT);

   pinMode(LED_PIN2, OUTPUT);
  pinMode(BUTTON_PIN2, INPUT);

   pinMode(LED_PIN3, OUTPUT);
  pinMode(BUTTON_PIN3, INPUT);

}
void loop() {
  if (digitalRead(BUTTON_PIN1) == HIGH) {
    digitalWrite(LED_PIN1, HIGH);
  }
  if (digitalRead(BUTTON_PIN1) == LOW)   {
    digitalWrite(LED_PIN1, LOW);
  }
  if (digitalRead(BUTTON_PIN2) == HIGH) {
    digitalWrite(LED_PIN2, HIGH);
  }
  if (digitalRead(BUTTON_PIN2) == LOW) {
    digitalWrite(LED_PIN2, LOW);
  }
  if (digitalRead(BUTTON_PIN3) == HIGH) {
    digitalWrite(LED_PIN3, HIGH);
  }
  if (digitalRead(BUTTON_PIN3) == LOW) {
    digitalWrite(LED_PIN3, LOW);
  }
}

The problem is that this code is causing all 3 LEDs to turn on or off together when any one of the three toggle switches is pushed. Can someone explain why this is happening? Also, what do I need to change so that each LED can be individually controlled?
Thanks!

Are you using an external pullup or pulldown resistor for each button?

How is your wiring done?
This is a working example of how it can be done:
#define LED_PIN1 5
#define BUTTON_PIN1 14

#define LED_PIN2 6
#define BUTTON_PIN2 15

#define LED_PIN3 7
#define BUTTON_PIN3 16

void setup() {
  // set up all the LEDs as OUTPUT
  pinMode(LED_PIN1, OUTPUT);
  pinMode(LED_PIN2, OUTPUT);
  pinMode(LED_PIN3, OUTPUT);

  // set up all the buttons as INPUT
  pinMode(BUTTON_PIN1, INPUT);
  pinMode(BUTTON_PIN2, INPUT);
  pinMode(BUTTON_PIN3, INPUT);
}

void loop() {
  // turn the LED on when button is pressed
  digitalWrite(LED_PIN1, digitalRead(BUTTON_PIN1));
  digitalWrite(LED_PIN2, digitalRead(BUTTON_PIN2));
  digitalWrite(LED_PIN3, digitalRead(BUTTON_PIN3));
}

When you just want the LED to be on when the button is pressed and off when the button is unpressed you can simplify the code by directly writing the button state to the LED like so: digitalWrite(LED_PIN, digitalRead(BUTTON_PIN)). Because read of the button will return either HIGH or LOW you can directly drive the LED with this.
Also make sure you check the pin's you are using on your device. Pin 3 is the reset pin. I therefore changed the pins to 5, 6, 7 to make sure you're using digital pins.

If you want to see a working example in action, take a look at this tinkercad. Be aware that I'm using an arduino uno here, so make sure that you use correct pins using the previous pin layout when adapting this to your Arduino nano. You can simulate this circuit by clicking on the 'simulate' button and test this working example by clicking on the buttons in the circuit.


text:
How do you take the simplest continuous reading from a Garmin Lidar Lite V4 using I2C on a Particle Boron v4.1.0?
Hey there Stack community.
I'm working with the Particle Boron v4.1.0.
I'm connecting a Garmin Lidar Lite V4 on I2C.
I'm using the LIDARLite_v4LED.h header file found in the library given for this device, "LIDAR-Lite" and my goal here is to op-check the sensor, by taking readings in the simplest way according to the .h file.
Wiring:
I've soldered 22AWG solid wire to each respective pin on the sensor:
GND : black, going directly to ground.
VCC : red, 3.3V pin on the Particle Boron.
I2C SDA : blue, SDA Pin0 on the Particle Boron with a 4.7K ohm pull-up resistor, connected to ground on one end, and running to Pin0 on the Boron.
I2C SCL : green, SCL Pin1 on the Particle Boron with a 4.7K ohm pull-up resistor, connected to ground on one end, and running to Pin1 on the Boron.
I've run an I2C scan which confirmed the address at 0x62.
According to the manual at: https://static.garmin.com/pumac/LIDAR-Lite%20LED%20v4%20Instructions_EN-US.pdf
To take a reading you must perform the following actions, which are embedded in the library's .h file functions:
"Obtaining Measurements from the I2C Interface
You can obtain measurement results from the I2C interface.

Write 0x04 to register 0x00.
Read register 0x01.
Repeat step 2 until bit 0 (LSB) goes low.
Read two bytes from 0x10 (low byte 0x10 then high byte 0x11) to obtain the 16-bit measured distance in centimeters."

#include <LIDARLite_v4LED.h>

const int I2CADDRESS = 0X62;
uint16_t distance;

LIDARLite_v4LED L1;

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

void loop() {
    L1.takeRange(I2CADDRESS);
    L1.waitForBusy(I2CADDRESS);
    L1.getBusyFlag(I2CADDRESS);
    distance = L1.readDistance(I2CADDRESS);
    Serial.printf("Distance = %u\n", distance);
}

When I run the code above the Serial Monitor shows 0 continuously for the reading, which is incorrect.
Do you happen to see what I'm doing wrong?
Here is what's happening in each respective function call above:
void LIDARLite_v4LED::takeRange(uint8_t lidarliteAddress)
{
    uint8_t dataByte = 0x04;

    write(0x00, &dataByte, 1, lidarliteAddress);
} /* LIDARLite_v4LED::takeRange */

void LIDARLite_v4LED::waitForBusy(uint8_t lidarliteAddress)
{
    uint8_t  busyFlag;

    do
    {
        busyFlag = getBusyFlag(lidarliteAddress);
    } while (busyFlag);

} /* LIDARLite_v4LED::waitForBusy */

uint8_t LIDARLite_v4LED::getBusyFlag(uint8_t lidarliteAddress)
{
    uint8_t  statusByte = 0;
    uint8_t  busyFlag; // busyFlag monitors when the device is done with a measurement

    // Read status register to check busy flag
    read(0x01, &statusByte, 1, lidarliteAddress);

    // STATUS bit 0 is busyFlag
    busyFlag = statusByte & 0x01;

    return busyFlag;
} /* LIDARLite_v4LED::getBusyFlag */

uint16_t LIDARLite_v4LED::readDistance(uint8_t lidarliteAddress)
{
    uint16_t  distance;
    uint8_t * dataBytes = (uint8_t *) &distance;
    // Read two bytes from registers 0x10 and 0x11
    read(0x10, dataBytes, 2, lidarliteAddress);
    return (distance);
} /* LIDARLite_v4LED::readDistance */

Thanks in advance for any assistance!
NOTE: The code doesn't show any errors. It's possible I damaged the chip on the sensor when I soldered, as I'm a newb to all of this! However, I've put two sensors together and tried them each separately with the same code, and got the same results in an attempt to rule this out. I did better soldering the second sensor, and find it highly unlikely I damaged them both.

Pull-up resistors need to be connected to VCC, not to ground... VCC is up, ground would be down.

Thank you romkey, I've corrected this. Unfortunately, I get exactly the same results having fixed the pull-up resistors. I have the resistors connected to 3.3V now.

According to the Wiring diagram found here: https://static.garmin.com/pumac/LIDAR-Lite_v3HP_Instructions_EN.pdf The resistors appear to be connected to ground. But it refers to them as pull-up resistors in the reference table. Now I'm uncertain if the resistors should be connected to ground or power...EDIT: SCRATCH THAT! I misread the wiring diagram, they are connected to power.

OH BOY! I solved it. I had to include wire.h and initiate Wire.begin(); in setup.

Hey glad you got it working! You figured out the hard part on your own :)

As romkey pointed out, I had the pull-up resistors wired wrong. Pull-up resistors are connected to power, not to ground.
Then I had to include wire.h and initiate Wire.begin(); in setup.


text:
Why does analogRead(A0) deliver different Values when called in a library file vs calling it in the sketch directly
I wanted to write a library representing a sensor to later on have an array of sensors.
I generated a file MoistureSensor.h:
#ifndef MoistureSensor_h
#define MoistureSensor_h

#include <Arduino.h>

class MoistureSensor {
  private:
    uint8_t sensPin;
    int sensValue;
    int sensId;

  public:
    MoistureSensor(uint8_t pin,int id);
    int getValue();
    int getId();
};

#endif

and MoistureSensor.cpp:
    // MoistureSensor.cpp
#include "MoistureSensor.h"

MoistureSensor::MoistureSensor(uint8_t pin, int id) {
  sensPin = pin;
  sensId  = id;
}

int MoistureSensor::getValue() {
  sensValue = analogRead(sensPin);
  return sensValue;
}
int MoistureSensor::getId() {
  return sensId;
}

this is the main sketch running on a Arduino Mega:
#include "MoistureSensor.h"

MoistureSensor sens1("A0", 1);

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

void loop() {
  Serial.println("Value from analogread:");
  Serial.println(analogRead(A1));
  Serial.println("Value from library:");
  Serial.println(sens1.getValue());
  Serial.println("End");
  delay(1000);

}

So when I run this the serial monitor shows:
Value from analogread:
600
Value from library:
496
End

Why doesn't this print the same value?
Does the .cpp file interpret the data from analogRead() different than the sketch?
Also both values where moving up and down depending on the response of the sensor.
Thanks in advance.

it should be MoistureSensor sens1(A0, 1);, not MoistureSensor sens1("A0", 1);. we don't write analogRead("A0")

In simple terms it has to use more memory to call the library. When you read it in the sketch it is one line. If in a library function you have to call the library, this causes the system to save its location in RAM then it executes the instruction. You are doing many more instructions with the library.

Trying to compile your sketch, I get the following compiler warning:
warning: invalid conversion from 'const char*' to 'uint8_t {aka unsigned char}'
 MoistureSensor sens1("A0", 1);
                             ^
note:   initializing argument 1 of 'MoistureSensor::MoistureSensor(uint8_t, int)'

This means that, whereas the MoistureSensor() constructor expected its
first argument to be of type uint8_t, you provided a const char*
instead. Indeed, a string literal like "A0" decays to a const char*
pointer when you pass it as a function argument.
The fix is to pass the actual pin number to your constructor:
MoistureSensor sens1(A0, 1);

But then, there is a second issue. In your test sketch, you have your
MoistureSensor object read A0, whereas the direct analogRead()
reads pin A1. If you want to get the same value, you should read the
same pin.
Side note: the change from uint8_t to byte has absolutely
nothing to do with your issue. These two types are synonyms.

I found a solution:
changing the parameter of the constructor
MoistureSensor::MoistureSensor(uint8_t pin, int id, int rawMax, int rawMin)`` from uint8_t tobytesolved this issue for me. I also changed the parameterization to MoistureSensor sens1(1, 1);`

there is no difference between byte and uint8_. it just a different name for the same thing.


text:
Working with pulseIn() and millis()
I'm trying to use pulseIn with elapsed time using millis(), I don't want to use interrupts instead of pulseIn (I need pulseIn because I need accurate pulse time), the elapsed time doesn't need to be very accurate, so to calculate the elapsed time I've added to the elapsed time the time the arduino is blocked, The problem is the calculated elapsed is very inaccurate, I suspect it sometimes never enters if(elapsed > 1000*60*2), Why is that? How can I fix that?
Thanks.
Code
unsigned long startTime = 0;
unsigned long elapsed = 0;
unsigned int val = 0;
uint32_t time_wait_pulse = 0;

void setup(){
  startTime = millis();
}

void f(){
  uint32_t time = 0;
  time += pulseIn(pin, LOW);
  if(time > 0) {
   ...
   time_wait_pulse += time;
  } else {
   time_wait_pulse += 1000000; //default pulseIn timeout (micros)
  }
}

void loop(){
    elapsed = millis() - startTime + (unsigned long)(time_wait_pulse/1000);
    if(elapsed > 1000*60*2){
      val++;
      startTime = millis();
      time_wait_pulse = 0;
    }

     noInterrupts();
     f();
     interrupts();
}

millis() is using interrupts to work. When deactivating interrupts for your function f(), you prevent that the value returned by millis() can actually change in that time.
So if the interrupt associated with millis() occurs during the execution of f(), you will lose time in your measurement and it will be inaccurate. It will get worse the more time the code spends with interrupts off vs on. micros() will still be updated without interrupts on (since it directly reads the register of Timer0), but it will still lose time after about 500ms, since then it cannot compensate for multiple overflows in that time period.
The way to go forward depends on your requirements. Is it really needed, that you disable interrupts for the pulseIn() measurement? What accuracy do you get in both cases (interrupts on vs off) and what accuracy do you need? If you absolutely need to turn off interrupts, only do it for the shortest time (only around pulseIn()). You can built your own time keeping analog to millis() using a 16bit Timer (you didn't specify what Arduino you are using), which would give you way more time, that the microcontroller can spend without interrupts on before loosing time in the measurement.You can also use a different prescaler to further increase this time, though sacrificing precision for it.

You can time reasonably long intervals using Timer 2 (on the Atmega328) as described in my page about timers.
The example there is this:
void startTimer1 ()
  {
  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  // zero it
  TCNT1 = 0;
  TIFR1 |= bit (TOV1);  // clear overflow flag
  // start Timer 1
  TCCR1B =  bit (CS10) | bit (CS12);  //  prescaler of 1024
  }  // end of startTimer1

unsigned long getTimer1Reading ()
  {
  unsigned long elapsed = TCNT1;
  if (TIFR1 &  bit (TOV1))
     elapsed += 65536;
  return elapsed;
  }  // end of getTimer1Reading

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

  }  // end of setup

void loop ()
  {
  Serial.println ("Starting ...");
  Serial.flush ();

  startTimer1 ();

  delay (7560);
  float secs = (1.0 / F_CPU * 1024) * getTimer1Reading ();

  Serial.print ("Time taken = ");
  Serial.print (secs);
  Serial.println (" seconds.");

  } // end of loop

The code above uses Timer 1 to time an interval up to 8.388 seconds. It users a prescaler of 1024, which means each "count" of timer 1 is 1/16e6 * 1024 of a second (0.000064 seconds, or 64 µs). Since it can count up to 65536 we can time 0.000064 * 65536 = 4.194304 seconds. Then the timer overflows, but we can test the "overflow flag" and know the overflow occurred. That lets us time up to 8.388608 seconds before we miss the fact that there was a second overflow.
This code works even if interrupts are off, because the timing is done by the hardware timer.
Output on my Uno:
Starting ...
Time taken = 7.56 seconds.


text:
Unable to upload sketch to Lolin S3 Pro (ESP32-S3)
I'm trying to upload a simple sketch to the new Wemos Lolin S3 Pro but unfortunately I can't seem to get it to work. I get the following error message:
    Connecting......................................

A fatal error occurred: Failed to connect to ESP32-S3: No serial data received.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
Failed uploading: uploading error: exit status 2

The following board is causing problems:
https://www.wemos.cc/en/latest/s3/s3_pro.html
It seems that there is no USB to UART chip and also no boot button.
As board I selected the "LOLIN S3 Pro" in the Arduino IDE and under Platformio I had selected the "lolin_s3".
I have also tried it under platformio with the following build flags but unfortunately without success:
build_flags = -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1

I am really perplexed what could be the cause?
Btw: I bought 3 of these boards and all 3 have the same issue.

OK I managed to solve it although I find its a little bit annoying it seems that you need to always set this board in download mode manually. (Press and hold boot and click reset button once).
If you are using Arduino IDE use the following options:

USB CDC On Boot -> Enabled
Upload Mode -> Hardware CDC / UART0

If you are using PlatformIO use the following build flags:
build_flags = '-DARDUINO_USB_MODE=1' '-DARDUINO_USB_CDC_ON_BOOT=1'

Also a good source: https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/tutorials/cdc_dfu_flash.html


text:
Arduino IDE equivalent to DataView?
I am working on a project with Bluetooth commands between various devices. I would like to try and convert a string to a DataView Object on Arduino, so I can send it over BLE, much like this function written in Javascript:
function str2DV(str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint8Array(buf);
  for (var i=0, strLen=str.length; i<strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  var DV = new DataView(buf);
  return DV;
}

Is this possible with Arduino? I have yet to find a solution....

Have you seen this library? https://github.com/bakercp/BufferUtils

There is no use for a DataView in the Arduino environment. In the
JavaScript language, a string and an array of bytes are two very
different things. That's why you need something like this str2DV()
function to convert between them. In C++, they are one and the same
thing: no need to convert. Sometimes the type uint8_t (also named
byte) is used in preference of char for storing binary data, but you
can just typecast between these types. The typecast typically compiles
to zero machine instructions, as the underlying data representation is
the same.
For example:
extern some_lib_function(const uint8_t *buffer, int buffer_length);

const char *my_message = "Hello, World!\n";
some_lib_function((uint8_t *) my_message, strlen(my_message));

If your string is in the form of a String object, rather than a plain
C-string, then use the c_str() method to get the plain string back:
String my_message = "Hello, World!\n";
some_lib_function((uint8_t *) my_message.c_str(), my_message.length());


text:
Using HTTPClient with ESP not working
I have a program running on an esp8266 that attempts to fetch json data from an HTTPS endpoint that is hosted on aws amplify (data comes from a next.js app).
I can retrieve the data correctly when I use WifiClient alone, but when I want to use HttpClient, I get this error:
[HTTP] GET... failed, error: connection failed

This is my code:
void Network::get_data()
{
    if (consumption_data)
        return;

    const char *endpoint = "https://.....";

    wifi_client.setInsecure();
    http_client.setTimeout(10000);

    if (!http_client.begin(wifi_client, endpoint))
    {
        Serial.println("Connection failed");
    }

    // Make the HTTP request
    String payload;
    int http_code = http_client.GET();

    if (http_code == HTTP_CODE_OK)
    {
        payload = http_client.getString();
    }

    else
    {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http_client.errorToString(http_code).c_str());
        return;
    }

    Serial.print("Payload: ");
    Serial.println(payload);

    // Parse JSON response
 }

My class contains these:
    WiFiClientSecure wifi_client;
    HTTPClient http_client;

The endpoint is accessible from postman and doesn't require any auth headers. Any idea what the problem may be?
Thank you

what is the value of http_code?

It starts off as 400. And then -1 for the subsequent requests. The 400 error is the output text I provided above.

Its always best to add more information to the question itself.


text:
Selecting the Right GPIOs
I've bought this 4 relay ESP8266 board to active lights and window shades.
In an odd way - its relays are not pre-connected to a certain IO's but let you choose which IOs will operate relays (by jumpering desired IOs). See Item below.
.
To operate my design, 4 inputs and 4 outputs are needed.
Exposed IOs are: io0,io2,io4,io5,io12,io13,io14,io15,io16.
while 9 IOs available only 8 are needed. I use randomnerdtutorials.
Misfits:

io0 and io2 can not serve as inputs since switch will fail boot (designed inputs are toggles),
io16 and io2 as outputs, are HIGH on boot, causing it to turn on for a fraction of second every boot (which turns on light or sliding window shades) - which I want to avoid.

which leaves:

Inputs: io16, io5,io4,io13
Outputs: io0,io14,io12,io15

Questions:

Is pins selection is OK ?
Why io15 is colored yellow and will it affect its use as an output?

3.io16 the only will be OK as input ?
4.io0 as an output (Relay)? since at reset all relays are powered off (want to be sure).

For Question 2, I guess GPIO15 is yellow because the pin must be low at boot time. It would be OK, for example, to power a led which is wired on the LOW side but not to sink one wired on the HIGH side.
Question 3 is not very clear.

why is "misfit 1" an issue? If you write your own code, you can ignore inputs during startup and choose the startup condition yourself.

@6v6gt Question2: Will it /Can it affect an output ? I guess not ( so why is it yellow ? ), Question 3 - table does not say if IO16 if it will fail on boot ( assigning it as input, can be toggled LOW).

@hennep you are not correct. Boot will fail, no mater what the code will be.

@guyd, most modern embedded processors can configure pins in software for multiple purposes. So, if you need the I2C serial bus to talk to an external chip you couldn't use GPIO 5 and 4.  But if you don't need to use the I2C bus you can use GPIO 5 and 4.  Is this the type of Answer you were looking for?  Let us know and someone can write up a more complete Answer.

@guyd A pin is not defined as an output (using pinMode() ) until the boot activity has finished and the sketch begins to run. Important only is that you don't connect anything to the pin which may violate its required startup condition. Hence, for GPIO15, it would be OK to connect a LED between it and the GND power rail because the pin would be LOW at boot time. It would not be OK to connect a LED between the 3.3v rail and GPIO15.

@st2000 Perhaps I'm not explaining my self correctly. I know io5 or io4 can be used as inputs or output, in addition to their I2C role. Never the less, certain IOs as io0 and io2 will fail boot if they are set to LOW (as in my case - Toggle switches), regardless if they were defined or not later in code using pinMode. Now - all 9 gpios I've got, some fit to be an input (or output) and some are not.

Since you only need 4 for the relays it does not matter as long as they are not predefined. You can use the A/D and a resistor array as inputs for the buttons. I generally use a I2C an external chip for I/0 such as an PCF8574. The PCF8574 defaults to INPUT on startup which is turning  all the outputs on. My designs use them as active low. That Way during reset etc no glitches. It only sources a very small amount of current but will sink several mills. There are many other devices you can use as well.


text:
Are intel hex files converted into a binary format before they are written to Atmega's flash?
I have been going through some resources on bootloaders, programmers, etc (I'm very new to this specific subject) and how they work with the Atmega chips and Arduino board programming. My research may have been shallow but none of the online articles/blogs/forum posts that I have been through mentioned that the .hex file (in intel hex ASCII format) needs to be converted to any other kind of binary format. It did seem odd to me though that one would directly write ASCII plain text into an MCU's flash. Also, when using AVR Burn-o-Mat (a GUI front end for avrdude) I did notice a couple of times that the number of bytes being flashed was significantly less than the actual size of the hex file. Most recently I went through this library on github which converts intel hex into a binary format. So am I right in saying that the hex file needs to be converted to binary? So for instance, does avrdude basically do this before sending the binary stream to the bootloader (when uploading a sketch via the IDE)?

I use that library in a sketch which reads hex from SD card and writes it as binary to flash on Arduino Mega. https://github.com/JAndrassy/ArduinoOTA/blob/master/examples/Advanced/SD2Flash2BootAVRHex/SD2Flash2BootAVRHex.ino

If you read the documentation of Avrdude, you will find that it is able to use different formats of the binary to flash, including binary. The command line argument includes the specifier.

Yes, the hex codes in the .hex file are read in by avrdude (or other programs) and written to the MCU in binary. A small microprocessor would not be able to read ASCII format commands.
See my answer about What happens when code is uploaded using the bootloader?

(Following on from some comments)

I did notice a couple of times that the number of bytes being flashed was significantly less than the actual size of the hex file

I think there is some confusion here, because of the different way numbers can be represented, or stored. Just for example, the number which we know as "twenty" could be written (in a file) as:

20 (decimal)
00020 (decimal with leading zeroes)
0014  (hex)
0024 (octal)
10100 (binary digits)

Now a program like Avrdude could read numbers in any of those formats, internally convert them to "binary" and send a single byte, being that binary number, to the MCU for placing into a program memory byte.
The .hex format, which the Arduino system produces as part of the compilation process, uses lines in this format:
Line format:
  :nnaaaatt(data)ss
  Where:
  :      = a colon
  (All of below in hex format)
  nn     = length of data part
  aaaa   = address (eg. where to write data)
  tt     = transaction type
           00 = data
           01 = end of file
           02 = extended segment address (changes high-order byte of the address)
           03 = start segment address *
           04 = linear address *
           05 = start linear address *
  (data) = variable length data
  ss     = sumcheck
            * We don't use these

The above from comments in my file https://github.com/nickgammon/arduino_sketches/blob/master/Atmega_Hex_Uploader/File_Utils.ino
Example: Optiboot in all its glory (only 512 bytes):
:107E0000112484B714BE81FFF0D085E080938100F7
:107E100082E08093C00088E18093C10086E0809377
:107E2000C20080E18093C4008EE0C9D0259A86E02C
:107E300020E33CEF91E0309385002093840096BBD3
:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E6000A2D0813461F49FD0082FAFD0023811F036
:107E7000013811F484E001C083E08DD089C08234E0
:107E800011F484E103C0853419F485E0A6D080C0E4
:107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000102F00270E291F29000F111F8ED06801E7
:107EB0006FC0863521F484E090D080E0DECF843638
:107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160
:107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80000AD08FE07ACF813511F488E018D01DD067
:107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0009093C60008958091C00087FFFCCF809118
:107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F0E098E1908380830895EDDF803219F02E
:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:047FF000FF270994CA
:027FFE00040479
:0400000300007E007B
:00000001FF

So, a line in the .hex file will start with a colon, then a length, then an address, then a transaction type, then some variable amount of data, and then a sumcheck. These are stored in the file in hexadecimal notation.
The very first thing we can deduce from this is that the file size will be over double the amount of memory that is programmed. For example, to program "AB" in hex, this would take two bytes in the .hex file ("A" followed by "B") but these would be converted into the equivalent one-byte "binary" number, which would end up in the MCU memory.
Then, because of the colon, the transaction type, the line length, and the sumcheck, the file will be somewhat longer still, than double the number of bytes to be programmed into the MCU. That is the file layout overhead.

"[...] would not be able [...]" is not correct as a general statement. The authors of the bootloader deliberately decided to use only binary data. ;-) You might also want to add that Avrdude is able to read multiple formats of the binary to flash, including binary.

I wrote that in the context of the question "It did seem odd to me though that one would directly write ASCII plain text into an MCU's flash - the ASCII plain text file is not written into flash memory and then executed. Certainly a microprocessor could read ASCII text and interpret it under program control, but the ASCII text is not itself loaded into flash and executed.

I see, so it is the wording of "to read". You mean "to read for execution" and I understood "to read for programming the flash". As there might be more like me, would you mind to enhance the answer? -- Because it were a waste of space to store programs in ASCII coded hex, I did not think of this.

I have attempted to explain it better.

:-D Wow. Yes, it's cool to explain Intelhex, and a good thing in the context. -- Please don't get it wrong, my humble issue targets just the "to read" in the second sentence, and it can be clarified satisfyingly with the content of your first comment.

"Because it were a waste of space to store programs in ASCII coded hex" - the use of sumchecks helps verify that the data has been read correctly, so it isn't a total waste of space.

Also the use of the address bytes means the hex file can be more compact. It means you can write 100 bytes here and then 50 bytes there without having to pad out the difference with thousands of zeroes.

That's all correct, and therefore formats like Intelhex have their share and advantages. Anyway, we were talking about storing a program on-chip. And because it complicates things a lot if machine code were stored in Intelhex for execution, I had no idea that you meant that.


text:
Best way to send a boolean (1/0) to a windows application in real time?
I have an arduino mega connected to a light sensor that reads the status of a machine's indicator light. I have a C++ application that controls the machine, and I would like the arduino to send the application the status of the indicator light in real-time so that the application can control the machine.
Essentially, I just want to constantly send a "1" or "0" through the serial monitor to a C++ application. What would the best way to do this be? I am confused as to the difference between serial.Write() and serial.Print(), what is more optimal for this application?

what amount of delay is acceptable?

I just want to constantly send a "1" or "0" ... it makes more sense to send data when transition occurs and send a heartbeat data the rest of the time

you have to define best before the question   an be answered

Since "optimal" is already a superlative, there is no "more optimal". :-D

It might sound like a good idea to send "0" or "1" in real time, for a fast response, but that might be counter-productive.
For one thing, you are spamming serial data which could slow down the receiving machine slightly. For another, if the sampling rate is faster than the baud rate, then the sending buffer will fill up, and the data being sent will be "old". Say the buffer size is 64 bytes, then the data being sent (and therefore received by windows) could be 64 bytes ago, and not real time.
I would suggest sending a "1" (with Print rather than Write) when the light is on, and then nothing until you detect that the light is off, then send a "0". And ditto for the transition back to being on. Thus the serial data flow merely indicates transitions and not the current state. This greatly reduces the amount of data, and makes it much less likely you will lose some or it will be out of date.
And just in case, send the current state (0 or 1) every second or so, just in case the listening end has only just been turned on.

That makes sense, I only care when the light turns on so I only need to tell the application that the light is on, the default is that the light is off. Thanks!

I agree with both previous answers. Nick Gammon gives excellent advise
on how to handle this situation, and Rohit Gupta gives you the gist of
write() v.s. print(). I would like to elaborate on this write() /
print() distinction though.
These methods of the Arduino API can be confusing, as they have many
different signatures.
write()
Let's look at write() first, as it is the simplest of them:
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);

These are meant to send a single byte and an array of bytes
respectively. You can send arbitrary bytes, which is usually termed
“binary data”. Note that any data, including text, is binary data: the
term binary here simply means that there is no restriction on the
bytes you can send.
size_t write(const char *buffer, size_t size);

This is the same as the previous one, for the case when the buffer is of
type “array of char”. It can still send arbitrary data.
size_t write(const char *str);

This is a version for sending C-strings, i.e. NUL-terminated buffers.
This one cannot send a zero byte, as that byte is interpreted as a
string terminator. It is thus inappropriate for sending binary (in the
sense of “arbitrary”) data. For this reason, I believe the inclusion of
this overload is a mistake made by the designers of the API, and I would
avoid it in preference of print() which, for this type of argument,
does exactly the same thing.
Note that, in every instance, write() takes the data you give it and
sends it as-is. There is no attempt at formatting it in any manner.
print()
As stated by Rohit Gupta, print() is meant for sending text. If you
have some data to send that is text to start with (like a literal
string), print() sends it as-is, and is thus quite similar to
write(). This is the case for the following overloads:
size_t print(const String &);  // sends a String object
size_t print(const char[]);    // sends a C-string
size_t print(char);            // sends a single character

Then you have some overloads for printing various kinds of numbers. All
of these involve a binary-to-text conversion. The two remaining
overloads, which involve __FlashStringHelper and Printable, are a
bit too technical and I will not discuss them here.
Comparison
All the statements below do the same thing, they send "A" through the
serial port:
Serial.write(65);        // sends a byte with binary value 65
Serial.write('A');       // the ASCII code of 'A' is 65
Serial.print('A');       // a char is print()ed by sending it as-is
Serial.print(char(65));  // 'A' is a shortcut for char(65)
Serial.print("A");       // a one-character string

All the statements below send "65" through the serial port:
Serial.write(54); Serial.write(53);    // send two binary values
Serial.write('6'); Serial.write('5');  // ASCII('6') = 54...
Serial.write("65");       // sends text in a pre-formatted buffer
Serial.print("65");       // same
Serial.print(65);         // print() does the number-to-text conversion
Serial.print(int('A'));   // same

As a general rule, I recommend to always use print() for sending text,
and use write() only for sending data that is not (reliably known to
be) text.

Yes, excellent. I struggle to explain exactly the difference between binary and non-binary. For example "00110001" is arguably binary, however it is an ASCII string with binary digits in it. However (in C++) 0b00110001 is binary in a different sense.

Serial.write sends binary data, whereas Serial.print sends ASCII data.  So it depends on whether you want Windows to receive ASCII 0 and 1 or binary 0 and 1.
I would suggest that you use print and send ASCII data.


text:
How to communicate pt2262 and pt2272 modul

There is a library called Virtual wire. I used it, but without success. I couldn't quite understand its pins. Can you explain? How can I use it?First picture receiver(pc2272) second picture tranmitter(pc2262 module ı used)

please add the information that you are looking at ... explain what part you do not understand

For example, there are 4 channels. How will I use each of these channels? In some places, the receiver assumes that the data is received when the pin to which the receiver is connected is HIGH. Is this true? I couldn't understand how it works in general

Also .What is the difference nrf24l01?

wbere are you seeing this information? ... add all info to the question ... please use the edit button to add it


text:
Where to store struct used for driver initialization
I'm doing a small project with ESP32 board. When initializing a driver, multiple structs are passed to initialization functions. I know that there are two ways to store such structs:

Storing structs on heap (with calloc or malloc)

adc_continuous_config_t cfg = calloc(1, sizeof(adc_continuous_config_t));

cfg->sample_freq_hz = 4500;
cfg->conv_mode = ADC_CONV_SINGLE_UNIT_1;
cfg->format = ADC_DIGI_OUTPUT_FORMAT_TYPE;

adc_continuous_config(*handle, cfg);
free(cfg);

Storing structs on stack

adc_continuous_config_t cfg = {
    .sample_freq_hz = 4500,
    .conv_mode      = ADC_CONV_SINGLE_UNIT_1,
    .format         = ADC_DIGI_OUTPUT_FORMAT_TYPE1,
};

adc_continuous_config(*handle, &cfg)

I was wondering which approach is encouraged.

It depends on several details, like: What is the requested lifetime of the data? Will the data be reused later? Are the values of the structure known at compile time? And probably some more. So this question cannot be answered in general.

I think the struct is only used for driver initialization which will only happen once in the machine's lifetime which means it will not be reused until reboot. All the values of the struct are simply predefined constants so they are known at compile time.

Then go with Edgar's solution, placing the structure in flash memory.

You seem to be initializing this struct with constants. In such a case,
I would use neither the heap nor the stack, but a third option: the
“read-only data” section of the program. At global scope:
const adc_continuous_config_t cfg = {
    .sample_freq_hz = 4500,
    .conv_mode      = ADC_CONV_SINGLE_UNIT_1,
    .format         = ADC_DIGI_OUTPUT_FORMAT_TYPE1,
};

Rationale: The constants you are using to fill the struct have to be
stored somewhere in the flash when the program is not running. Although
I do not know the details of the machine language of the ESP32, it seems
to me the compiler has only two options to compile your example code. It
could say:

load a CPU register with the immediate value 4500
store that register at the address of cfg->sample_freq_hz
load a CPU register with the immediate value ADC_CONV_SINGLE_UNIT_1
etc.

Then the values are stored as immediate operands of machine
instructions. The other option would be to store an anonymous version of
the initialized struct in the read-only data section of the program, and
issue a memcpy() to initialize the allocated space at run time.
If you instead store the initialized struct as a global constant, it
will go straight into the read-only data section of the program (like in
the second compiler strategy), and you will use it from there. No extra
copy needed. No extra machine instruction for initializing space
allocated on the heap or stack.
Caveat: I assume adc_continuous_config() expects its second
parameter to be of type “pointer to const data”. If it expects it to
be a pointer to modifiable data, then this will not work.


text:
Smoothing hx711 readings with atmega328
I am making a 50kg weighing scale using HX711 ADC. My project includes Atmega328 along with 74HC595 for driving 5 7segment displays(multiplexed). I am using the function scale.get_units()to fetch the data and the values are very well displayed on the 7segments. The problem I am facing is the readings on the 5th digit (right most 1's) are unstable. Now, if I use scale.read_average(5), my display scanning gets slow. I was wondering if there is a way to average the readings in a loop like the conventional way. I tried it but with no luck! It keeps showing random added numbers. Any help would be highly appriciated. Below is the code inside the loop. Let me know if full code is needed. Thanx in advance!
if (scale.is_ready()) {
    weight = scale.get_units();
    finalWeight = weight * 1000;
}
for (int i = 0; i < 10 ;i++) {
    sum += finalWeight;
}
average = sum / 10;
if (average < 0) {
    break_number(0);
} else {
    break_number(average);
}
display_number();
delay(1);

First of all, this code:
for (int i = 0; i < 10 ;i++) {
    sum += finalWeight;
}
average = sum / 10;

does not average multiple readings. Instead, it takes the single reading
stored in finalWeight, multiplies it by ten (by means of successive
additions), then divides it by ten to get back the same value.
If you want to reduce the noise, you have to take multiple readings and
average them. The reading-taking code must thus be inside the loop. A
simple option may be like this:
void loop() {
    sum = 0;
    for (int i = 0; i < 10; i++) {
        while (!scale.is_ready()) {}  // wait for the scale to be ready
        sum += scale.get_units();
    }
    weight = sum / 10;  // compute the average
    display(weight);    // and display it
}

Note that I have simplified things a bit by removing the scaling
factors. You can take this as simple inspiration and adapt to your
specific needs.
The code above has one problem though: as the code is blocking while
waiting for the scale to be ready, the display is not refreshed. You
could fix this by explicitly refreshing the display within the waiting
loop:
void loop() {
    sum = 0;
    for (int i = 0; i < 10; i++) {
        while (!scale.is_ready()) {  // wait...
            display(weight);         // ...while refreshing the display
        }
        sum += scale.get_units();
    }
    weight = sum / 10;
    display(weight);
}

This should work, but I would however suggest instead a third approach:
write non-blocking code. This is code that never blocks: instead, if
something can be done right now, it does it. If not, it moves along:
void loop() {
    if (scale.is_ready()) {  // if something useful can be done NOW:
        sum += scale.get_units();
        count++;
        if (count >= 10) {
            weight = sum / count;  // update the value to be displayed
            sum = 0;               // reset the averaging variables
            count = 0;
        }
    }

    display(weight);  // unconditionally refresh the display
}

This way, your loop() always runs fast, and you can add code that will
not be blocked by the stuff you wrote earlier.
Edit: As suggested by chrisl in a comment, a moving average may
better serve your needs. I would try the exponentially-weighted version,
as it is lightweight and simpler to implement. You may want to explore
this path.

In addition: Here a moving average might be a good choice, like in the second answer to this question

Thanx a lot!! I will try it.


text:
stream a "big" array of measures to a server through wifi
I'm measuring accelerations at "high frequency" (4kHz) from an accelerometer (ADXL355/ADXL357) to an esp32. It's crucial that no sample is lost while performing a measure which last say 2 seconds, thus I first record all the samples and then send the complete array of measures to a server over wifi knowing the IP and the port of the server.
The measures array is an int array of size 3bytes * 3axis * 4000Hz * 2seconds = 72000 bytes.
I tried to make an http server and send the measures array from the microcontroller to the server with a POST request and serializing the payload with json (ArduinoJSON library), but this is very costy in terms of memory, because I need to duplicate the array of measures and convert it to an array of strings.
Is there a better way to send this array over wifi to the server (some sort of stream?) optimizing the memory usage on the microcontroller? which arduino libraries may help in the task? could you link an example with code of a similar situation?

JSON is a format trivial to write: you do not need a library for this.
For example, an array of numbers could be serialized like this:
void serialize_array(Print &client, int *data, int count) {
    client.print('[');
    for (int i = 0; i < count; i++) {
        client.print(data[i]);
        client.print(i==count-1 ? ']' : ',');
    }
}

This would effectively stream the data without storing the JSON
representation in memory.

Thank you Edgar, what is the client parameter of type Print? Where could I find documentation on understanding how to set it for comunnicate with a given ip:port?

@AlekseyFedorovich: client would be an instance of HttpClient, or EthernetClient, or WiFiClient, or... whatever you are sending your data to. It could even be Serial if you just want to check the payload on the serial monitor. See the documentation of whatever you would use to send an HTTP request.


text:
Break a big file into smaller files
I had a really big .ino file and I decided to break it down into sub-files.
So I had the .ino file, the globals.h file and the functions.h file.
I moved all the global vars and functions to their respective files.
This is what is going on inside:
//.ino
#include "globals.h"
#include "functions.h"

//globals.h
*Has header guard
*All variables here are extern
*Contains function prototypes - the definition is in functions.h
*Contains objects (like softWareSerial)

//functions.h
#include "globals.h"
*contains function definitions

However, my code will not work.
I get a huge list of errors, but the last of which is about SoftwareSerial (in globals.h)
'SoftwareSerial' does not name a type; did you mean 'SoftwareSerial_h'?

Isn'e the code structure that I posted previously valid?
EDIT: I ask here and not on StackOverflow for example, because the IDE has symo idiosyncracies, like it first loads the .ino and then all the other files in an alphabetical manner.
EDIT 2: I followed user's Edgar Bonet advice (thank you). I reached somewhere, but I get multiple definition errors now. This is the pseudocode to show to display my code structure:
    //string_handling_functions.h
    HEADER_GUARD
    #include <SoftwareSerial.h> //used later. If this call happened in main .ino (even before the call to this header file, code would not work)
    #include <model_definitions.h> //used in the function definition in the .cpp file
    byte clear_Buffer(bool, SoftwareSerial*);

    //string_handling_functions.cpp
    #include <Arduino.h>
    #include "string_handling_functions.h"
    FUNCTION DEFINITION GOES HERE

    //model_definitions.h
    HEADER_GUARD
    #defines
    SoftwareSerial object_definition
    Other Objects Definitions (libs called in main .ino file)
    const char example_var PROGMEM = {0};

    //main_ino.ino
    #include "string_handling_functions.h"

I get these type of errors now:
\sketch\string_handling_functions.cpp.o (symbol from plugin): In function `GSM_Module_SW_Serial':
(.text+0x0): multiple definition of `GSM_Module_SW_Serial'
\sketch\main_code.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

All errors are multiple definitions. The items that fall victim to this error are objects and arrays.
Some extra questions:

All the vars in .h files have to be extern?
Can they have a value in the header file? (eg extern char value = {"0"};)

EDIT 3:
After compying to all the rules, I had to create many files (.h and .cpp) to group everything together.
These are the last errors that I get, and they have to do with SoftwareSerial:
In file included from \sketch_general_vars.cpp:2:0:
model_definitions.h:498:1: error: 'SoftwareSerial' does not name a type; did you mean 'HardwareSerial'?
 SoftwareSerial Ter_1_SS_RXOnly (TER_1_RX_PIN, TER_1_TX_PIN);
 ^~~~~~~~~~~~~~
 HardwareSerial
model_definitions.h:499:1: error: 'SoftwareSerial' does not name a type; did you mean 'HardwareSerial'?
 SoftwareSerial Ter_2_SS_RXOnly (TER_2_RX_PIN, TER_2_TX_PIN);
 ^~~~~~~~~~~~~~
 HardwareSerial
model_definitions.h:536:1: error: 'SoftwareSerial' does not name a type; did you mean 'HardwareSerial'?
 SoftwareSerial GSM_Module_SW_Serial(GSM_RX_PIN, GSM_TX_PIN);
 ^~~~~~~~~~~~~~
 HardwareSerial

exit status 1
'SoftwareSerial' does not name a type; did you mean 'HardwareSerial'?

When I #include <SoftwareSerial.h> in that file, then so many errors pop up. Its a cat and mouse game.
First of all, the previous Object calls now get multiple definitios errors, for example multiple definition of GSM_Module_SW_Serial'`.
Secondly, I get countless of these messages (not only for READ_GPS):
ino:1817: undefined reference to READ_GPS'`
READ_GPS is defined in globals_non_model.h, defined in globals_non_model.cpp, included in string_handling_functions.h. This is then included in the main ino (#include "string_handling_functions.h")

Thanks for shortening your posted code.  But in this case it may be too much trimming.  Maybe there's enough information here to determine what has gone wrong.  But I don't see it.  (Also, most of the time, I only look at and fix the 1st compiler error.  Often this fixes many of the other errors.)

@st2000 Thank you for the comment! I will try first to organize the errors into categories and will update the question.

maybe just rename functions.h to functions.ino and remove the #include "functions.h" line. https://arduino.github.io/arduino-cli/0.33/sketch-build-process/#pre-processing

At a guess, 'SoftwareSerial' does not name a type; suggests that the definition of an SoftwareSerial object was seen by the compiler before it had read SoftwareSerial.h. See @edgarbonet's answer, in particular, about partitioning a large project file into separately compiled files. It seems like all of your files are still compiled in one run which leaves compilation order out of your control. That can cause the first use of a symbol such as SoftwareSerial appearing before its declaration.

The include for SoftwareSerial needs to go  into the .ino file (the main project file). That way it is included appropriately. Please see my second answer.

Here is a clean model for splitting a large Arduino project down into individual .cpp and .h files : https://forum.arduino.cc/t/how-to-properly-include-functions-written-on-other-sketch-tabs/565672/4

This is not the right way to split a big .ino file. You should instead
think in terms of functional units, i.e. software “modules” that address
specific concerns. For example, if a subset of your code is intended to
manage an hyperdrive, then you could move that to a dedicated
“hyperdrive” module:
// hyperdrive.h -- module interface
* variable declarations (all extern, no initializers)
* function declarations (i.e. prototypes only)
* class definitions

// hyperdrive.cpp -- module implementation
#include <Arduino.h>     // needed if you use the Arduino API
#include "hyperdrive.h"  // to check consistency with the public interface
* variable definitions (without extern, with initializers when relevant)
* function definitions (with bodies)
* class method definitions

// main.ino
#include "hyperdrive.h"
* code of main program

Edit 1: Answering EDIT 2 of the question.

All errors are multiple definitions

This typically happens when you define a variable in a header (.h) file:
the variable gets defined as many times as that header is included
somewhere. You should not do that. The only things you should ever
define in a header are types, which includes classes. Everything
else (functions and variables) should only be declared in the header,
and defined in the accompanying .cpp file.

All the vars in .h files have to be extern?

Yes. Without the extern keyword, you would have a variable
definition, and variable definitions belong to the accompanying .cpp
file. The extern keyword is needed for writing a variable
declaration.

Can [variables] have a value in the header file?

No. An initial value belongs to the variable definition, not to its
declaration.
Edit 2: Answering EDIT 3 of the question.

model_definitions.h:498:1: error: 'SoftwareSerial' does not name a type

If the header file references types or objects that are defined
elsewhere, it needs to have the relevant #include lines. In this case
you need:
#include <SoftwareSerial.h>

multiple definition of `GSM_Module_SW_Serial'

This line:
SoftwareSerial GSM_Module_SW_Serial(GSM_RX_PIN, GSM_TX_PIN);

is a variable definition. At the risk of repeating myself: you should
not put variable definitions in header files. The header should contain
only the declaration:
extern SoftwareSerial GSM_Module_SW_Serial;

whereas the definition should be in the corresponding .cpp file.

Thanks! I followed your advice and definitely got somewhere. I only get multiple definition errors. I updated my question with my current strategy.

I started a bounty without seeing the edit on your part (perhaps I saw it but forgot it?). I will start implementing what you said. Thank you!

I created a part 3 in the edit history. It looks like a cat and mouse game.

Thank you. The blame is on my part, as I did not understand that you have to do the same for object definitions as well. The only thing left is the long list of undefined reference...

If you split the file into multiple .ino files, then the compiler will concatenate them all into one long .ino file before it compiles.  It will put the one that matches the name of the project first and the rest in alphabetical order.  This can cause problems if things end up being used in that long file before they are defined.
You can start the .ino file names with numbers or something and control the order that they get included in, or you can move that code into .h and .cpp files and include it that way.  Header files will be included in the order you include them in the code.

the Arduino builder adds forward declaration for functions and moves class and struct definitions at the beginning of the concatenated file

Yes, but it doesn't always get things right.  I can give dozens of examples that don't compile because the IDE put something in the wrong order.  It happens especially if you define a struct and a function that either returns that type or takes it as an argument.  I've seen many many cases where the forward declaration gets put in before the struct definition and you get does not name a type error.

that problem is not related to multiple ino files. it can happen with one ino too. and it is the only problem with creation of forward declarations. generating the C++ forward declarations is the most convenient thing the builder does for us

Thanks but as Juraj said, the problem is persistent regardless of the naming of the files.

Yes, but the problem is NOT present when using .h and .cpp instead of .ino files.  In that case the inclusion happens where you tell it to be included and things work the way one would expect having used other tools.

I AM using .h and .cpp files. However, the problems have not yet been solved.

I think @Juraj and I were talking about a different type of problem.

I had the same problem. This solution is wrong but I tried all types of solutions and eventually had the same problem. What I did was place the extracted code in another file and labeled it .ino in the same folder as the original file and it worked. Someday they might add the .insert"filename" command. It worked great in the assembler world.

"Someday they might add the .insert"filename" command." - How would that differ from #include < ... >?

.insert would insert the file where the statement is. It could be code, anything that was properly formatted. Even comments if properly delimited.  This was very useful in the old Assembler days.

#include is the same

#include is NOT the same thing. It will only include specific file types. A file with a simple print statement will not include at the insert point, it just says it cannot find it. "
W_Gil_Base:220:10: fatal error: Test.gil: No such file or directory
#include "Test.gil"
^~~~~~~~~~
compilation terminated.
exit status 1
Test.gil: No such file or directory
"  It is in the same directory as the .ino file.

Correct operation of #include is the same thing; You've found a compiler bug (reported) in the v2.1.0 IDE (maybe all IDE 2.x?). It works if you provide the full path to the include file (which should not be necessary). It works for 'recognized' file extensions (which should also not be necessary. In IDE 1.8.19, the #include directive does work correctly.

I moved all the global vars and functions to their respective files. This is what is going on inside:

As Delta_G said, the concatenated file is the main file first (the one with the name of the project) followed by the other files in alphabetic order. This may move global vars to be declared after they are used in other files. I would have left the global vars in the main file.
However as Edgar_Bonet said in his answer, it would probably be better to make the whole thing modular.

See my answer How the IDE organizes things - it explains it in more detail.

'SoftwareSerial' does not name a type; did you mean 'SoftwareSerial_h'?

Things like includes of libraries therefore have to go in the main file - putting them in sub files breaks the inclusion of those libraries, hence that error message.

You need to treat the .ino file as a project file. Just put in that the includes for things like software serial. That triggers the IDE to include the appropriate libraries. Don't put any other code in it. Put declarations into .h files and definitions (ie. variable values and functions) into .cpp files.
If you do it that way make sure you do the usual C and C++ convention. Make forward declarations of functions, in case you attempt to use a function before its definition is found. These would normally go into .h files.

Some extra questions:
All the vars in .h files have to be extern?

If you don't want multiple declaration errors you should be declaring but not defining variables in your .h files. So yes, they should be extern.

Can they have a value in the header file? (eg extern char value = {"0"};)

No - because you will be including it multiple times, probably. In fact you can't have a value on an extern, it doesn't make sense. Using extern means it is defined elsewhere.

Put the declarations in the .h files with extern in front of them. Then they have to be defined somewhere (ie. given a value). You could make a .cpp file specifically for that purpose.
Did you read the link I gave? That goes into it in some detail.

//.ino
#include "globals.h"
#include "functions.h"

//globals.h
*Has header guard
*All variables here are extern
*Contains function prototypes - the definition is in functions.h
*Contains objects (like softWareSerial)

The includes for SoftwareSerial need to go into the .ino file because that is what the IDE scans for, to see what libraries to link into your project.
Just put the (includes for the) libraries into the .ino file, nothing else.

Header guards just stop multiple copies of the same .h file being included in the same compilation unit. They don't stop multiple .h files being included into different compilation units (multiple .cpp files). So they may not achieve much here.

Thank you! I am using the proper format however the errors remain. I have .h files and their equivalent cpp files with function and variable definitions. However, i get errors like  undefined reference to Battery_level'in the main.ino` file. This var (for example, one of many vars) is declared in a .h file and defined in the .cpp file. The header is included in another header, and this another header included in the main ino file. What is weird is that other vars in the header/cpp file are fine. Only some vars are affected. There are two headers whose vars give errors to the main ino.

And even if include these header files directly to the main ino file (like i said, they are included in another header, which is then included by the ino file), the problems still remain and are exactly the same.

Please make a Minimal, Reproducible Example of this problem. Just make two or three (small) files which reproduce the problem, nothing else, and post their complete contents here.

@user1584421 In the process of making this MRE you will probably hit a point where, before you do X it compiles, and after you do X you get error messages. Then you can see that X is the issue. If you can't see why X is the issue then we can help you.