text:
Can I measure multiple photoresistors from one pin?
I would like to make a laser sensor to detect light coming from a 650nm diode. My current idea would be to use CdS photoresistors/LDRs. I want to measure a few (4-8?) at once, where light falling onto any one of them generates a signal - I don't care from which sensor it actually came. However, I would like to put as many sensors on as few pins as possible.
I've already somewhat figured out that putting LDRs in parallel isn't ideal, because any changes in voltage will become smaller the more I use. Instead, it would seem like a better idea to build some kind of 'switch' by putting each LDR together with a fixed resistor and a transistor. How exactly would a circuit for this look like, or are there better ways to do it?

Can you check this post. I think that what you want https://arduino.stackexchange.com/questions/4027/reading-many-analog-signals-in-arduino

So you want open collector bus and transistors will be used as comparators to pull the bus LOW if any of sensors is active?

I still think the parallel solution could still work. You just have to lower the value of the (pull-up) resistor, to get a bigger range of different values.

solar cells (PV) are much faster than CDS and unlike resistors, can be chained in series.

Depending on how much light falls on it, an LDR can see its resistance fall by several orders of magnitude. Thus, putting several LDRs in parallel could definitely work. Shining a laser on one of them will effectively short the whole parallel assembly into a very low resistance.

If response time is critical (on the order of about a quarter of a second) consider using photo diodes instead of Cadmium sulfide cells.
Also, consider using an Arduino with more ADC ports.  The number of ADC ports is usually a constraint of the processor used.  Different Arduinos use different processors.  Some may have more ADC ports.
Finally, to utilize a single ADC port for multiple unknown resistances, consider using a resistor network where all the unknown resistances and a known pull down resistance are connected to the ADC port. Then, in turn, using as many Arduino digital pins as there are unknown resistance, apply a digital high to only 1 unknown resistance. Keeping the digital pins to all the other unknown resistance in a high impedance state. That is, change them from OUTPUT to INPUT digital ports. Then take an ADC sample. Apply this same procedure for all the other unknown resistances. Consider adding a delay after changing the state of the digital pins to allow for the ADC input to acclimate to the new voltage.

simulate this circuit – Schematic created using CircuitLab


text:
Question about button circuit
I'm quite a beginner at electronics, but thought I would try venture into it.
Currently I'm working on a project where I need to reuse a button module salvaged from some old hardware, but I can't figure out the wiring. The attached image is what I was able to track down on how the circuit is built. I'm not really sure how to wire it? Would it be possible to use this with an ESP32 and differentiate all the buttons?

the picture shows no resistors ... it also shows no circuitry ... please add a view of the back side of the board

Sure. Take a multimeter and measure the resistance between the left-most pin and each of the other pins with all the different combinations of button pairs pressed. Write down the results.
Then build a voltage divider for each output (Connect a resistor to ground on each output, and then connect that pin to an analog input on the Arduino. The resistor value to use will depend on the readings you get, but a 1K ohm resistor would be a good starting point.)
Then set up the 2 input pins on your Arduino as analog inputs and measure the voltage with no buttons, top button, bottom button, and both buttons pressed for each pair. Write those values down. Then write code that checks for voltages roughly equal to your measurements for each button press combo (You will need check for ranges of values, since the values will vary some.)

Thank you so much for the very quick answer. So, am I commpletely wrong to assume it to be something like this? (:
https://imgur.com/a/q9uITj6

@Eyee The circuit on the image in your comment is exactly, what DuncanC described. From the analog input pins each a resistor to ground and a direct connection to the buttons output pin (in your schematics at the right). And the single pin on the left to Vcc (which is 3.3V in your case)

Yup, that looks about right. You might need to experiment with different resistor values. Like I said, a 1k  would be a good place to start.

Thanks alot for the answers!

Do you know the value of R1 in your circuit diagrams? (The resistors that are in parallel with your switches?)

I'm not sure. I tried to measure it, but wasn't able to get a stable reading. The smd component is also blank, so couldn't look it up. The others were labled 102,101, 202 and 202. But I went ahead with your solution and everything works perfectly! Ty very much. Used a 10k ohm resistors for both and I'm able to distinguish the buttons with a rough analog read difference of 300, so it seems pretty stable for now.

source: Stack Exchange

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

sort: votes


text:
Is there a simple HTTP(S) library that doesn't rely on WiFi?
I'm trying to implement a Mobile Network (only) for the ESP32 using Arduino IDE. So to be able to connect to website up/download files etc. I need to be able to handle various HTTP PUT/GET/POST requests. However, the available libraries seem to always rely on additional WiFi related libraries. I don't want to have to load those as well, as they are quire bloated and not needed for my use scenario.
What options do I have for minimalist HTTP request libraries that does not rely on WiFi or BT or ETH?

do you have some library over 'Mobile Network' or only AT commands?

Only AT commands. So now I have to manually construct the request/response with strings, which is a real PITA.

I don't know about mobile network Arduino library with Server implementation. it would require a public IP address so not many would use it

I'm not implementing a server, just a connecting client to download files (to the ESP).

sorry. then you can use TinyGSM. https://github.com/vshymanskyy/TinyGSM

@Juraj That look promising. How do you import that library into the IDE?

is it not in Library Manager?

My bad! I have no idea why I missed it the other day. Thanks.

The TinyGSM library implements Arduino networking Client base class over GSM modem's AT commands. The library is available in Library Manager.

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


text:
How can remove the WiFi/Bluetooth libraries when compiling the firmware using the Arduino IDE?
I have an ESP32-D0WDQ6, which is part of the ESPIRIT freematics development kit. The processor is a 2-core Tensilica LX6 and the module has 520 kB SRAM + 4 MB external on-module flash. It also has the SIM5360E 3G/GSM module. So with that connection, I don't need neither the Bluetooth nor the WiFi stack. However, it seem that when compiling using the Arduino IDE, all these libraries are still included in the compile, even if not used. This is bad as it seem to take up a lot of extra FW space that I need for my growing app, while running my device at high currents, and heating it up.
How can I ensure that WiFi/Bluetooth libraries are not compiled in with the Sketch when using Arduino IDE?
At this point I have tried to disable them, but that required to #include Wifi.h (or similar) which no longer fit on my sketch. (This doesn't make any sense, that I need to include Wifi.h just to be able to disable it.)

UPDATE:
It's most definitely linking all those...

#--------------------------------------
# Linking everything together...
#--------------------------------------

"C:\\Users\\XXX\\Documents\\Arduino\\hardware\\espressif\\esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc"
-nostdlib "-LC:\\Users\\XXX\\Documents\\Arduino\\hardware\\espressif\\esp32/tools/sdk/lib"

    "-LC:\\Users\\XXX\\Documents\\Arduino\\hardware\\espressif\\esp32/tools/sdk/ld"
    -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld -T esp32.rom.libgcc.ld -T esp32.rom.spiram_incompatible_fns.ld
    -u ld_include_panic_highint_hdl -u call_user_start_cpu0 -Wl,--gc-sections -Wl,-static
    -Wl,--undefined=uxTopUsedPriority -u __cxa_guard_dummy -u __cxx_fatal_exception
    -Wl,--start-group "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\BTHealthThermometer.cpp.o"

    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\ECUBluetoothTask.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\FreematicsNetwork.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\FreematicsPlus.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\KolbanTask.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\eCUesp32.ino.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\eCUlogging.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\sketch\\esp32fota.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLE2902.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLE2904.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEAddress.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEAdvertisedDevice.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEAdvertising.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEBeacon.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLECharacteristic.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLECharacteristicMap.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEClient.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEDescriptor.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEDescriptorMap.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEDevice.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEEddystoneTLM.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEEddystoneURL.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEExceptions.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEHIDDevice.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLERemoteCharacteristic.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLERemoteDescriptor.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLERemoteService.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEScan.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLESecurity.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEServer.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEService.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEServiceMap.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEUUID.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEUtils.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\BLEValue.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\FreeRTOS.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\BLE\\GeneralUtils.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\ETH.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFi.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiAP.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiClient.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiGeneric.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiMulti.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiSTA.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiScan.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiServer.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFi\\WiFiUdp.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\SPI\\SPI.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\SD\\SD.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\SD\\sd_diskio.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\SD\\sd_diskio_crc.c.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\FS\\FS.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\FS\\vfs_api.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\HTTPClient\\HTTPClient.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFiClientSecure\\WiFiClientSecure.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\WiFiClientSecure\\ssl_client.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\libraries\\Update\\Updater.cpp.o"
    "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833\\core\\core.a"

-lgcc
-lopenssl
-lbtdm_app
-lfatfs
-lwps
-lcoexist
-lwear_levelling
-lesp_http_client
-lprotobuf-c
-lhal
-lnewlib
-ldriver
-lbootloader_support
-lpp
-lfreemodbus
-lmesh
-lsmartconfig
-ljsmn
-lwpa
-lethernet
-lphy
-lapp_trace
-lconsole
-lulp
-lwpa_supplicant
-lfreertos
-lbt
-lmicro-ecc
-lesp32-camera
-lcxx
-lxtensa-debug-module
-ltcp_transport
-lmdns
-lvfs
-lesp_ringbuf
-lsoc
-lcore
-lfb_gfx
-lsdmmc
-llibsodium
-lcoap
-ltcpip_adapter
-lprotocomm
-lesp_event
-limage_util
-lc_nano
-lesp-tls
-lasio
-lrtc
-lspi_flash
-lwpa2
-lwifi_provisioning
-lesp32
-lface_recognition
-lapp_update
-lnghttp
-lspiffs
-lface_detection
-lespnow
-lnvs_flash
-lesp_adc_cal
-llog
-ldl_lib
-lsmartconfig_ack
-lexpat
-lm
-lfr
-lmqtt
-lc
-lheap
-lmbedtls
-llwip
-lnet80211
-lesp_http_server
-lpthread
-ljson
-lesp_https_ota
-lfd
-lstdc++
-Wl,--end-group
-Wl,-EL
-o "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833/eCUesp32.ino.elf"

"C:\\Users\\XXX\\Documents\\Arduino\\hardware\\espressif\\esp32/tools/gen_esp32part.exe"
-q "C:\\Users\\XXX\\Documents\\Arduino\\hardware\\espressif\\esp32/tools/partitions/default.csv"
"C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833/eCUesp32.ino.partitions.bin"

"C:\\Users\\XXX\\Documents\\Arduino\\hardware\\espressif\\esp32/tools/esptool/esptool.exe"
--chip esp32 elf2image --flash_mode dio --flash_freq 80m --flash_size 4MB
-o "C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833/eCUesp32.ino.bin"
"C:\\Users\\XXX\\AppData\\Local\\Temp\\arduino_build_245833/eCUesp32.ino.elf"

the arduino libraries are not linked if you don't use them. but the closed source SDK is precompiled in 80 .a files. using esp without Espressif SDK is like using a computer without OS.

That's weird, because during the linker part it seem that it links a whole bunch of libraries that I'm supposedly not using. So then there must be 2nd/3rd dependencies that are using them. I'll post the linker output tomorrow. So are there any open alternatives to the SDK?

Arduino libraries are a thin layer over the SDK.

I'm not quite sure, but I'd think that your best option would be to forfeit the Arduino libs and build directly on the Espressif SDK...

Yeah, I really wish that Arduino devs could provide better control for this. Or at least clearly document what are the dependency chain of all the other libraries. WiFi and BT are both huge, so it would be great to be able to get rid of those, when not needed.

I've also seen this forum post, but there were never any response to that post.


text:
3rd Libraries: fatal error: Something.h: File does not exist

I created this question because I find many questions with similar problems,
  so I wanted to provide a reference/ more generic question for these type of problems.

For my projects I have installed 3rd party libraries by cloning from the library's git repository into the folder that preferences.txt's sketchbook.path value exists into a folder named libraries. In other words if the sketchbook.path has the value /home/myuser/sketchbook I clone the repositories into the folder /home/myuser/sketchbook/libraries.
Then on the folder /home/myuser/sketchbook/myexample I store my code myexample.ino that needs a library with header files Something.h.
While I click on Arduino IDE the verify button I get the error:
/usr/share/arduino/hardware/tools/avr/bin/avr-g++ -c -g -Os -Wall -fno-exceptions
    -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD
    -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -D__PROG_TYPES_COMPAT__
    -I/usr/share/arduino/hardware/arduino/cores/arduino
    -I/usr/share/arduino/hardware/arduino/variants/standard
    -I/usr/share/arduino/libraries/SPI
    /tmp/build6596169359663087897.tmp/LoRaSerialGateway.cpp -o
    /tmp/build6596169359663087897.tmp/LoRaSerialGateway.cpp.o
LoRaSerialGateway.ino:15:18: fatal error: Something.h:
compilation terminated.

So my guess is that I cannot make avr-gcc to compile using the 3rd party library. Do you know how to pass into avr-gcc the correct paths for the appropriate libraries?

The Arduino IDE will handle it, provided the libraries are actually installed via the IDE.

Assuming you have a working library system already, i.e., there are some libraries in .../libraries now and they compile properly or at least the compiler are successfully finds them; and you want to add another library, say "CrashAndBurn.h" and "CrashAndBurn.cpp", you need to put those two files into a folder named .../libraries/CrashAndBurn/. Then in your sketch, you add an include directive #include <CrashAndBurn.h>.
An alternative is to put the .h and .cpp files somewhere else, such as a folder under your project folder, and modify the include directive to point to them, as #include "libs/CrashAndBurn.h", where the libs folder is within the sketch folder. Or you could put them in any folder, anywhere, and write an absolute path to them: /home/some/place/else/CrashAndBurn.h

Sometimes you should modify a bit the library's file stricture in case of this library in order to make it avaialble I moved the code in folder ./src outside to the project's root folder.
Also an another problem is that you may use older version of the ide. Especially this can happen in GNU/Linux if you install the arduino ide from the distribution's repositories.

just rename the folder from zip to LoRa in libraries. no need to move files

I used the git method.

I create file system link from git folder to libraries folder, with the correct library name

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


text:
I need help setting up my Arduino Uno with the port
I'm using a Windows computer, and if I recall correctly I installed the IDE using the installer, so I probably don't need to manually install the drivers. However, I can't figure out how to set up the serial port with the Arduino. For me under Tools, there's no "Serial Port" option but instead "Serial Monitor" and "Serial Plotter."
When I tried to upload my file, it failed. When I clicked Serial Plotter, it gave this error message:
Arduino: 1.8.4 (Windows 8.1), Board: "Arduino/Genuino Uno"

Sketch uses 940 bytes (2%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for
local variables. Maximum is 2048 bytes.
avrdude: ser_open(): can't open device "\\.\COM1":
The system cannot find the file specified.

Problem uploading to board.
See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.
Board at COM1 is not available

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

How am I supposed to resolve this?

Check the Hardware manager in Control panel that recognizes your arduino board connected.

Is it a genuine Arduino or a cheap clone from eBay or Amazon?

"under Tools, there's no "Serial Port" option". It's Tools > Port. Is that menu item disabled?

Yes, it's the only option under Tools that's grayed out and disabled for me.

I'm not sure if this is related but my computer doesn't seem to see my Arduino although it's plugged in. If I go to the Device Manager it's not even there.

Before we can help you, you must answer my question.

Yes, I bought it from Adafruit and I am 100% it is completely legit.

If you don't believe me: https://imgur.com/a/fZjc5

You need to see it in the device manager. I don't have Windows 8 to test it on, but I think the Windows versions of the IDE ship with a device driver for it.

It's not a question of believing you - the cheap clones use a different USB chip and the solution to your problem would be completely different depending on if it's a genuine Arduino (CDC/ACM interface) or a cheap clone (CH340G interface). The latter requires special drivers not bundled with the IDE.  Since it is a CDC/ACM interface based one we can assume it's not the drivers if you installed the IDE properly. So it may be your USB cable (note: some cheap charger cables don't have data wires) - try a different USB cable, try a different USB port, and at a pinch, try a different computer.

I figured it out by following the tutorial by Adafruit. I had to install it manually in order for it to work.

The idea behind answering your own question is that it could be helpful to others who are having the same problem. This answer does not provide enough details to be helpful. Please edit to improve it. What tutorial are you talking about? Add a link to it. But don't only rely on the link for your answer because if the link goes dead the information is lost. Add a description of what you mean by "install it manually".

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


text:
Touch Sensor - Determining Pressing/Hold Length and Modifying Program Flow Accordingly
The code below is used for controlling a relay with an Arduino. Pressing the touch sensor connects and disconnects the relay.
If the user presses/touches/holds their finger on the touch sensor for longer than two seconds, how do I adjust the program to do something other than connecting or disconnecting the relay?
#define TouchSensor 9 // Pin for capactitive touch sensor

int relay = 2;

boolean currentState = LOW;
boolean lastState = LOW;
boolean RelayState = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(relay, OUTPUT);
  pinMode(TouchSensor, INPUT);
}

void loop() {
  currentState = digitalRead(TouchSensor);
    if (currentState == HIGH && lastState == LOW){
    Serial.println("pressed");
    delay(1);

    if (RelayState == HIGH){
      digitalWrite(relay, LOW);
      RelayState = LOW;
    } else {
      digitalWrite(relay, HIGH);
      RelayState = HIGH;
    }
  }
  lastState = currentState;
}

You have to determine, how long a the sensor was pressed until released. When it is released you can take the corresponding steps. If the press was shorter than say 1.5s, you can switch the relay. Else you can do something else.
There are many ways to achieve this. You can program it yourself by using the millis() function. You would have to set a timestamp, when the state of the sensor changes to high, then wait for it to go low and substract the timestamp from the current value of millis(). This would give you the duration of press, which you can use in a corresponding if-statement.
Or you can use the Debounce library for it, which makes it a bit simpler (not a lot, but you should consider debouncing depending on the type of sensor you use). Look at the answer from VE7JRO to this question. The debouncer.update() function checks, if the state of the button changed. If so and the value was LOW (in your case this would has to be changed to HIGH), a timestamp is set with the value of millis(). When an update with LOW occurs, the time difference between the two events is calculated and the corresponding action are taken. I will add the code from the answer for reference here:
// Connect one end of a N.O. push button switch to GND and the other
// end to pin 4 of the Arduino.
// NOTE: If the button is held down for less than the debounce delay
//       time, the elapsed time will display the debounce delay time.
#include <Debounce.h>
const byte SWITCH = 4;
unsigned long startTime = 0;
unsigned long endTime = 0;
unsigned long elapsedTime = 0;
const byte debounceDelayTime = 50;

Debounce debouncer = Debounce(debounceDelayTime, SWITCH);

void setup(){
  Serial.begin(9600);
  pinMode(SWITCH, INPUT_PULLUP);
}

void loop(){
  if(debouncer.update()){
    if(debouncer.read() == 0){
      startTime = millis();
      Serial.println("Button Pressed");
    }
    else if(debouncer.read() == 1){
      endTime = millis();
      Serial.println("Button Released");
      elapsedTime = endTime - startTime;
      Serial.print("Button Held Down For ");
      Serial.print(elapsedTime);
      Serial.println(" ms.");
    }
  }
}

For this kind of scenario "activation" of the button is never done when it is pressed. Yes, under "normal" circumstances you press a button, a circuit is made, and something happens.
However, if you need more than just that simple operation you never do anything just when it's pressed.
For example, if you click on a link on a web page, nothing really happens when you press the mouse button. Yes, the link is "selected", but that's all. Nothing active happens until you release the mouse button.  It's the act of "press-then-release" that constitutes a "click" - and then only if the release happens within a certain time after the press.
That allows such other options to happen, such as "press-drag-release" for drag and drop, or  "press-wait-release" for selecting without activating, etc.
So for your scenario you have two desired "triggering" options:

press-release
press-hold

As long as the "release" of the "press-release" happens in a shorter time than the "hold" time of the "press-hold" you can differentiate between them.
So your methodology would look something like this:

Button pressed - record the time
Either:

Button released and time elapsed < 2 seconds, or
Time elapsed >= 2 seconds

As code that may look something along the lines of:
static uint32_t ts = 0;
static uint8_t buttonState = HIGH;

uint8_t buttonValue = digitalRead(ButtonPin);

if (buttonValue != buttonState) { // The state has changed.
    buttonState = buttonValue; // Record it
    if (buttonState == LOW) { // Button has been pressed
        ts = millis(); // Record the time
    } else if (ts > 0) { // Released - ts must have been set by a press
        if (millis() - ts < 2000) { // Less than 2 seconds have passed
            // Run your "press" routine
            ts = 0; // Clear our time stamp.
        }
    }
} else if (ts > 0) { // It hasn't changed state, but was pressed
    if (buttonState == LOW) { // It's held in. Not strictly necessary but can't hurt
        if (millis() - ts >= 2000) { // 2 seconds have passed
            // Run your "hold" routine
            ts = 0; // Clear our time stamp.
        }
    }
}

The time stamp variable ts is both used to record the time the button was pressed and also as a flag to indicate that we are currently in an "unactivated" state.  That is, for the "held" state to indicate whether or not we still need to run our "held" routine or not.  Without that check, after 2 seconds of holding the button the "held" routine would keep running over and over and over again until the button is released. It's kind of like implementing a "forced" release of the button after it has triggered the "held" routine.  After that first triggering of "held" we no longer care what is done with the button. We ignore everything until the next time it is pressed when we set ts again.

This sketch uses a millis() timer to add the concept of time to debouncing a button with the Bounce2 Library, (This library may be included with the current version of the Arduino IDE). This sketch does not contain any code to turn a relay on and off.
// Connect one end of a N.O. push button switch to GND
// and the other end to pin 4 of the Arduino.
#include <Bounce2.h>

byte buttonState = 0;
byte lastButtonState = 0;
const byte buttonPin = 4;
const byte debouncerInterval = 50;         // Time in ms.
unsigned long buttonHeldThreshold = 2000;  // Time in ms.
unsigned long buttonPressTimeStamp;

Bounce debouncer = Bounce();

void setup(){
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  debouncer.attach(buttonPin);
  debouncer.interval(debouncerInterval);
}

void loop(){

  if(debouncer.update()){

    if(debouncer.read() == 0){
      buttonState = 1;
      buttonPressTimeStamp = millis();
      Serial.println("Button Pressed");
    }
    else if(debouncer.read() == 1){
      buttonState = 0;
      Serial.println("Button Released");
    }
  }

  if(buttonState == 1){
    if(millis() - buttonPressTimeStamp >= buttonHeldThreshold){
      buttonState = 2;
      Serial.println("Button Held for 2+ seconds");
    }
  }

  // Print out the contents of the buttonState variable only when it changes.
  if(buttonState != lastButtonState){
    Serial.print("Button state = ");
    Serial.println(buttonState);
    Serial.println();
    lastButtonState = buttonState;
  }
}

Keep in mind that this library has debouncer.rose() and debouncer.fell() functions that may be helpful to you. It's always a good idea to look at the *.h and *.cpp files in the libraries you install. There may be several functions that are not demonstrated in the library's examples. Sometimes the author(s) use code comments in the library which can help you to trouble shoot any issues that may arise.


text:
LCD not displaying text (16x2)

(https://circuitdigest.com/microcontroller-projects/arduino-based-accident-alert-system-using-gps-gsm-accelerometer)
the code is
Serial.println(zValue);
..... .....
........ ...

Here we have also created some other function for various purposes like void gpsEvent() to get GPS coordinates, void coordinate2dec() for extracting coordinates from the GPS string and convert them into Decimal values, void show_coordinate() for displaying values over serial monitor and LCD, and finally the void Send() for sending alert SMS to the predefined number.
Complete code and demo video is given below, you can check all the functions in the code.
Code
#include<SoftwareSerial.h>
SoftwareSerial Serial1(2,3); //make RX arduino line is pin 2, make TX arduino line is pin 3.
SoftwareSerial gps(10,11);
#include<LiquidCrystal.h>
LiquidCrystal lcd(4,5,6,7,8,9);

#define x A1
#define y A2
#define z A3

int xsample=0;
int ysample=0;
int zsample=0;

#define samples 10

#define minVal -50
#define MaxVal 50

int i=0,k=0;
int  gps_status=0;
float latitude=0;
float logitude=0;
String Speed="";
String gpsString="";
char *test="$GPRMC";

void initModule(String cmd, char *res, int t)
{
  while(1)
  {
    Serial.println(cmd);
    Serial1.println(cmd);
    delay(100);
    while(Serial1.available()>0)
    {
       if(Serial1.find(res))
       {
        Serial.println(res);
        delay(t);
        return;
       }

       else
       {
        Serial.println("Error");
       }
    }
    delay(t);
  }
}

void setup()
{
  Serial1.begin(9600);
  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.print("Accident Alert  ");
  lcd.setCursor(0,1);
  lcd.print("     System     ");
  delay(2000);
  lcd.clear();
  lcd.print("Initializing");
  lcd.setCursor(0,1);
  lcd.print("Please Wait...");
  delay(1000);

  Serial.println("Initializing....");
  initModule("AT","OK",1000);
  initModule("ATE1","OK",1000);
  initModule("AT+CPIN?","READY",1000);
  initModule("AT+CMGF=1","OK",1000);
  initModule("AT+CNMI=2,2,0,0,0","OK",1000);
  Serial.println("Initialized Successfully");
  lcd.clear();
  lcd.print("Initialized");
  lcd.setCursor(0,1);
  lcd.print("Successfully");
  delay(2000);
  lcd.clear();
  lcd.print("Callibrating ");
  lcd.setCursor(0,1);
  lcd.print("Acceleromiter");
  for(int i=0;i<samples;i++)
  {
    xsample+=analogRead(x);
    ysample+=analogRead(y);
    zsample+=analogRead(z);
  }

  xsample/=samples;
  ysample/=samples;
  zsample/=samples;

  Serial.println(xsample);
  Serial.println(ysample);
  Serial.println(zsample);
  delay(1000);

  lcd.clear();
  lcd.print("Waiting For GPS");
  lcd.setCursor(0,1);
  lcd.print("     Signal    ");
  delay(2000);
  gps.begin(9600);
  get_gps();
  show_coordinate();
  delay(2000);
  lcd.clear();
  lcd.print("GPS is Ready");
  delay(1000);
  lcd.clear();
  lcd.print("System Ready");
  Serial.println("System Ready..");
}

void loop()
{
    int value1=analogRead(x);
    int value2=analogRead(y);
    int value3=analogRead(z);

    int xValue=xsample-value1;
    int yValue=ysample-value2;
    int zValue=zsample-value3;

    Serial.print("x=");
    Serial.println(xValue);
    Serial.print("y=");
    Serial.println(yValue);
    Serial.print("z=");
    Serial.println(zValue);

    if(xValue < minVal || xValue > MaxVal  || yValue < minVal || yValue > MaxVal  || zValue < minVal || zValue > MaxVal)
    {
      get_gps();
      show_coordinate();
      lcd.clear();
      lcd.print("Sending SMS ");
      Serial.println("Sending SMS");
      Send();
      Serial.println("SMS Sent");
      delay(2000);
      lcd.clear();
      lcd.print("System Ready");
    }
}

void gpsEvent()
{
  gpsString="";
  while(1)
  {
   while (gps.available()>0)            //Serial incoming data from GPS
   {
    char inChar = (char)gps.read();
     gpsString+= inChar;                    //store incoming data from GPS to temparary string str[]
     i++;
    // Serial.print(inChar);
     if (i < 7)
     {
      if(gpsString[i-1] != test[i-1])         //check for right string
      {
        i=0;
        gpsString="";
      }
     }
    if(inChar=='\r')
    {
     if(i>60)
     {
       gps_status=1;
       break;
     }
     else
     {
       i=0;
     }
    }
  }
   if(gps_status)
    break;
  }
}

void get_gps()
{
  lcd.clear();
  lcd.print("Getting GPS Data");
  lcd.setCursor(0,1);
  lcd.print("Please Wait.....");
   gps_status=0;
   int x=0;
   while(gps_status==0)
   {
    gpsEvent();
    int str_lenth=i;
    coordinate2dec();
    i=0;x=0;
    str_lenth=0;
   }
}

void show_coordinate()
{
    lcd.clear();
    lcd.print("Lat:");
    lcd.print(latitude);
    lcd.setCursor(0,1);
    lcd.print("Log:");
    lcd.print(logitude);
    Serial.print("Latitude:");
    Serial.println(latitude);
    Serial.print("Longitude:");
    Serial.println(logitude);
    Serial.print("Speed(in knots)=");
    Serial.println(Speed);
    delay(2000);
    lcd.clear();
    lcd.print("Speed(Knots):");
    lcd.setCursor(0,1);
    lcd.print(Speed);
}

void coordinate2dec()
{
  String lat_degree="";
    for(i=20;i<=21;i++)
      lat_degree+=gpsString[i];

  String lat_minut="";
     for(i=22;i<=28;i++)
      lat_minut+=gpsString[i];

  String log_degree="";
    for(i=32;i<=34;i++)
      log_degree+=gpsString[i];

  String log_minut="";
    for(i=35;i<=41;i++)
      log_minut+=gpsString[i];

    Speed="";
    for(i=45;i<48;i++)          //extract longitude from string
      Speed+=gpsString[i];

     float minut= lat_minut.toFloat();
     minut=minut/60;
     float degree=lat_degree.toFloat();
     latitude=degree+minut;

     minut= log_minut.toFloat();
     minut=minut/60;
     degree=log_degree.toFloat();
     logitude=degree+minut;
}

void Send()
{
   Serial1.println("AT");
   delay(500);
   serialPrint();
   Serial1.println("AT+CMGF=1");
   delay(500);
   serialPrint();
   Serial1.print("AT+CMGS=");
   Serial1.print('"');
   Serial1.print("9821757249");    //mobile no. for SMS alert
   Serial1.println('"');
   delay(500);
   serialPrint();
   Serial1.print("Latitude:");
   Serial1.println(latitude);
   delay(500);
   serialPrint();
   Serial1.print(" longitude:");
   Serial1.println(logitude);
   delay(500);
   serialPrint();
   Serial1.print(" Speed:");
   Serial1.print(Speed);
   Serial1.println("Knots");
   delay(500);
   serialPrint();
   Serial1.print("http://maps.google.com/maps?&z=15&mrt=yp&t=k&q=");
   Serial1.print(latitude,6);
   Serial1.print("+");              //28.612953, 77.231545   //28.612953,77.2293563
   Serial1.print(logitude,6);
   Serial1.write(26);
   delay(2000);
   serialPrint();
}

void serialPrint()
{
  while(Serial1.available()>0)
  {
    Serial.print(Serial1.read());
  }
}

Please make your code readable by putting it in a code block. Also reduce your code to what you need to examine your problem (which is trouble printing to the LCD display). All the other GPS/coordinate calculation code you've included is just noise at this moment. Also, it would be nice if you could include the image in your question instead of in a link. You mention a demo video but it's not there.

One more question: have you tried to adjust the LCD contrast with the potentiometer?

Can you see anything on the LCD?

@Ch Murali, Please answer our questions.


text:
Differences between two common RS485 to TTL modules
I want to "translate" existing code that utilizes one of these modules for the other module.
Specifically, I have code that utilizes an "RS485 to TTL converter". As you can see in this picture:

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

The Arduino side has four pins as well, DI, DE, RE, and RO.
However, all four of these pins are data pins.
Since the protocol is the same, how come the pins are different?
In the "RS485 to TTL converter" code, SoftWareSerial is being used, and it gets the two pins that will eventually connect to the TX and RX on the module as arguments.
How can I translate this code for the MAX485? How should the pinout be?
EDIT: I find it funny that I won the "notable question badge (question with 2500 views)"... And then I look and it has a -1 rating. lol

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

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

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

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

So far as I'm able to tell, your first module must have a feature that automatically enabled RS485 driver when you are sending and disabled it as soon as you aren't. This is not an uncommon feature.
The latter doesn't support it apparently. It looks like a common MAX485 type design which doesn't. Instead it exposes driver enable and receiver enable pins. These are normally active at opposite levels, which allows you to tie them together and run them to a single pin on the Arduino for controlling both at the same time. Any code that you had using the prior module would need to be changed to manually enable the driver when sending and then disable it afterwards.
You would need an extra digital pin (PIN_DE_RE) connected from the Arduino to the module, to both of its RE and DE pins. It would need to be set to output in setup() with pinMode(PIN_DE_RE, OUTPUT); And set to low digitalWrite(PIN_DE_RE, LOW); for a chip following the MAX485 design such that the receiver is enabled and driver disabled initially.
Your write transactions would then need to look like this:
delayMicroseconds(10);
digitalWrite(PIN_DE_RE, HIGH);
delayMicroseconds(10);
your_serial.write(whatever); // or .print etc
your_serial.flush();
delayMicroseconds(10);
digitalWrite(PIN_DE_RE, LOW);
delayMicroseconds(10);

You may not need explicit delays around the digitalWrite since digitalWrite is often slow enough anyway, but the point of them is to give support the minimum time needed between changing the RE/DE pins and a transaction. I picked 10uS somewhat arbitrarily.  More than anything it's just there to raise the point that the timing between the signal change and sending/receiving is important.
For SoftwareSerial .flush() does nothing usually, at least it doesn't on the AVR. But I include it just to make the point that whatever you use to send serial you must make sure the transaction has left the actual device and not merely been queued for send before disabling the RS485 driver. If you were doing this with Serial1 on a Leonardo/Micro/Mega etc it would be important. I'd leave .flush() as is for SoftwareSerial in part because it won't cost you anything to do so and it will make things work if you switch to a buffered-output type serial connection.

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

RS485 is a standard for a communication bus with potentially multiple senders, of course not at the same time. As such, a device needs to disable its transmitting circuit to let others communicate. The application layer protocol is not defined by RS485.
For this reason, a good driver module provides two control inputs beside the data lines:

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

The data lines are commonly denoted like this:

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

How does this work in the module that only has TXD and RXD?
Well, the hardware assumes some specific baud rate, which should be documented.
As soon as the start bit is detected on TXD, the module internally activates the driver (DE). It might additionally disable the receiver (RE) to avoid reception of the message as an echo.
This activation is controlled by a timer that lasts at least as long as the transmission at the specific baud rate needs to be sent.

Now, what to do with the MAX485 module's control lines?
You can connect TXD to DI and RXD to RO, respectively.
If your module simply uses the driver chip manufactured by Maxim, the control input RE has actually inverted logic. This means, the receiver is active, if the line is low. In contrast, the driver is active, if the line DE is high.
Put appropriate calls of digitalWrite() at the places where you want to send something to the sensor. Please be aware that the transmission needs some time. You need to make sure that all bits are sent before you disable the driver.
If you only want to receive from the sensor, just disable the driver and enable the receiver all the time.

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

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

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

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

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

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

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

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

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


text:
How to control Android app with Arduino
I'm trying to connect Arduino Leonardo to an Android tablet. I would like to make the Arduino send commands (using pushbuttons or a slider for example) to the tablet to switch between pages, to select a file on the desktop, to scroll up and down the screen, etc.

Perhaps this is not exactly what you are looking for, but from your examples it seems like using navigational commands from the keayboard/mouse would accomplish a lot of what you are requesting.
Android has USB HID support from honecomb, so you should be able to create a sketch to emulate a keyboard and mouse based on the IO data and it should work with your android device just by plugging the USB cable (if emulating a mouse, it will display the mouse cursor as soon as it is connected).

Android code:
function OnStart() {
    //Create a layout with objects vertically centered.
    lay = app.CreateLayout("linear", "VCenter,FillXY")

    //Create a toggle button.
    btn = app.CreateToggle("LED On/Off", 0.4)
    btn.SetOnTouch(btn_OnTouch)
    lay.AddChild(btn)

    //Add layout to app.
    app.AddLayout(lay)

    //Create USB serial object.
    usb = app.CreateUSBSerial()
    if (!usb) {
        app.ShowPopup("Please connect your Arduino and restart")
        return;
    }
    usb.SetOnReceive(usb_OnReceive)
    app.ShowPopup("Connected")
}

//Called when user touches our toggle button.
function btn_OnTouch(isChecked) {
    if (!usb) return;

    //Send LED command to Uno.
    if (isChecked) usb.Write("ledh")
    else usb.Write("ledl")
}

//Called when we get data from Espruino.
function usb_OnReceive(data) {
   console.log(data)
}

Arduino code:
void setup() {
  pinMode(2,1);
  serial.begin(9600);

  loop() {
    if (serial.Read()="ledh) {
      digitalWrite(2,1);
    }
    if (serial.Read()="ledl) {
      digitalWrite(2,0);
    }
  }
}

The Arduino code has clear syntax errors; please review.

this doesn't answer the question. OP wants to use USB HID capability (emulate keyboard) of the Leonardo

First, get a Lightblue Bean, http://punchthrough.com/bean/
It has everything you need:
- arduino
- bluetooth
- API
- code example
- android sdk
- ...
Develop your product using this platform.
If you want to scale and build your own platform, then you will have a foundation to validate your work.

Half you answers refer to this product. Are you associated with it? You need to disclose any personal stake in it if you are.

not associated with the company, but a happy customer of their product.

It is a good idea to use a LightBlue Bean, only if you are using the Android SDK!
 https://bitbucket.org/littlerobots/beanlib
You can read more about the SDK, and get advice from people who are actually using it.
http://beantalk.punchthrough.com/t/announcing-unofficial-android-sdk/394


text:
Initializing Array of structs
I defined myself a struct:
typedef struct {
  unsigned char current;
  unsigned char start;
  unsigned char target;
  unsigned long startTime;
  unsigned int duration;
} led;

I was able to initialize an instance of that like this:
led h_red = {0,0,255,0,300};

However, when I try to have them in an array:
led leds[LEDS];
leds[0] = {0,0,0,0,0};
leds[1] = {0,0,0,0,0};
leds[2] = {0,0,255,0,300};

I get this error
signal:28:1: error: 'leds' does not name a type
 leds[0] = {0,0,0,0,0};
 ^~~~
signal:29:1: error: 'leds' does not name a type
 leds[1] = {0,0,0,0,0};
 ^~~~
signal:30:1: error: 'leds' does not name a type
 leds[2] = {0,0,255,0,300};
 ^~~~

And I have no idea what I'm doing wrong here. You can see the full change here on GitHub

led h_red = {0,0,255,0,300};

Here, you are defining a variable, and at the same time giving it an
initial value. This is called an initialization.

led leds[LEDS];

Here you are defining an array. Since it is in global scope, and not
explicitly initialized, it is implicitly initialized to all bytes zero.

leds[0] = {0,0,0,0,0};

Here, you are trying to give a value to an element of the array that has
already been defined previously. This is thus not an initialization,
but an assignment. Unlike initializations, assignments cannot exist
outside a function. If you want to assign initial values, you can do it
in setup().
Alternatively, you can initialize the array while you define it:
led leds[LEDS] = {
    {0, 0,   0, 0,   0},
    {0, 0,   0, 0,   0},
    {0, 0, 255, 0, 300}
};

This is the key part to notice: Unlike initializations, assignments cannot exist outside a function. If you want to assign initial values, you can do it in setup(). OP's call to leds[0] = {0,0,0,0,0}; is perfectly valid within another function, such as setup(), but is NOT allowed outside of all function scopes, where only initialization can take place. The OP was accidentally trying to do this assignment in the global scope, where new assignments and regular logic code are not allowed.

I've upvoted @Edgar Bonet's answer, because it is correct.
I want to add some more examples and explanations though.
Key summary:
In C and C++, you can NOT have code logic outside of functions. The global context outside of functions is intended for declarations, definitions, and some initializations/constructors only. All code logic must be inside of a function. Code logic includes post-construction variable assignments, if statements, etc.
Examples:
1. NOT allowed:
Therefore, you can NOT do the following, since it attempts to do non-initializing assignments outside of all function scopes.
Notice also that in C++ (which Arduino is), you don't need to use typedef for structs either, so I've removed that from the struct definition. I'm also using the stdint.h types, which are considered safer and "best practice" for data types, as they specify the exact type size in bits. Use uint8_t in place of unsigned char, uint32_t instead of the Arduino Uno's unsigned long, and uint16_t instead of the Arduino Uno's unsigned int. Also, in C++ in particular, constexpr or enums are preferred over #define to set variable constants.
constexpr uint8_t NUM_LEDS = 3;

struct Led {
  uint8_t current;
  uint8_t start;
  uint8_t target;
  uint32_t startTime;
  uint16_t duration;
};

Led leds[NUM_LEDS];
// NOT OK: Variable (re)assignments are NOT allowed outside of functions in
// C and C++.
leds[0] = {0, 0,   0, 0,   0};
leds[1] = {0, 0,   0, 0,   0};
leds[2] = {0, 0, 255, 0, 300};

void setup()
{
}

void loop()
{
}

2. IS allowed:
You CAN, however, have variable initializations outside of functions, so long as they occur at the same time as construction, so this is perfectly valid:
Led leds[NUM_LEDS];
// This form of aggregate initialization during construction is just fine in the
// global scope outside of all functions.
Led leds[NUM_LEDS] = {
    {0, 0,   0, 0,   0},
    {0, 0,   0, 0,   0},
    {0, 0, 255, 0, 300},
};

void setup()
{
}

void loop()
{
}

3. Also IS allowed:
Or, you can just move your reassignments into a function, such as setup():
Led leds[NUM_LEDS];

void setup()
{
    // This variable (re)assignment is just fine since it's inside
    // of a function.
    leds[0] = {0, 0,   0, 0,   0};
    leds[1] = {0, 0,   0, 0,   0};
    leds[2] = {0, 0, 255, 0, 300};
}

void loop()
{
}

4. Full, runnable example on a PC:
Here's a full, runnable example on a PC, with printing to verify the contents of the struct were changed:
Run it online yourself on OnlineGDB here, or from my eRCaGuy_hello_world repo here: struct_array_initialization.cpp:
#include <stdint.h>
#include <stdio.h>

// Get the number of elements in a C-style array
#define ARRAY_LEN(array) (sizeof(array)/sizeof(array[0]))

constexpr uint8_t NUM_LEDS = 3;

struct Led {
  uint8_t current;
  uint8_t start;
  uint8_t target;
  uint32_t startTime;
  uint16_t duration;
};

// To initialize once at construction. This form of aggregate initialization
// can be used anywhere: both inside and outside functions.
Led leds[NUM_LEDS] = {
    { 1,  2,  3,  4,  5},
    { 6,  7,  8,  9, 10},
    {11, 12, 13, 14, 15},
};

// Print the full contents of an array of `Led` structs
void printLeds(const Led ledArrayIn[], size_t ledArrayLen)
{
    for (size_t i = 0; i < ledArrayLen; i++)
    {
        printf("ledArrayIn[%lu]\n"
               "current   = %u\n"
               "start     = %u\n"
               "target    = %u\n"
               "startTime = %u\n"
               "duration  = %u\n\n",
               i,
               ledArrayIn[i].current,
               ledArrayIn[i].start,
               ledArrayIn[i].target,
               ledArrayIn[i].startTime,
               ledArrayIn[i].duration);
    }
}

int main()
{
    printf("Hello World\n\n");

    printLeds(leds, ARRAY_LEN(leds));

    printf("==============\n\n");

    // Do this to set or change the structs at any time AFTER construction!
    // This variable (re)assignment is only allowed inside of a function, NOT
    // in the global scope outside of all functions!
    leds[0] = {10, 20,  30,  40,  50};
    leds[1] = {60, 70,  80,  90, 100};
    leds[2] = { 0,  0, 255,   0, 300};

    printLeds(leds, ARRAY_LEN(leds));

    return 0;
}

Sample output:
Hello World

ledArrayIn[0]
current   = 1
start     = 2
target    = 3
startTime = 4
duration  = 5

ledArrayIn[1]
current   = 6
start     = 7
target    = 8
startTime = 9
duration  = 10

ledArrayIn[2]
current   = 11
start     = 12
target    = 13
startTime = 14
duration  = 15

==============

ledArrayIn[0]
current   = 10
start     = 20
target    = 30
startTime = 40
duration  = 50

ledArrayIn[1]
current   = 60
start     = 70
target    = 80
startTime = 90
duration  = 100

ledArrayIn[2]
current   = 0
start     = 0
target    = 255
startTime = 0
duration  = 300

Other references:

https://en.cppreference.com/w/cpp/language/aggregate_initialization
[my answer] https://stackoverflow.com/questions/61240589/how-to-initialize-a-struct-to-0-in-c/61240590#61240590

Regarding the first paragraph of your answer; What does "I've upvoted @Edgar Bonet's answer, because it is correct." have to do with the question?


text:
ESP32: spi_master: check_trans_valid(801) when using SPI
I use the following code to communicate with a display:
void Display_HandleDC(spi_transaction_t* p_Transaction)
{
    gpio_set_level((gpio_num_t)LCD_DC, (uint32_t)p_Transaction->user);
}

static void Display_SendCommand(const uint8_t Command)
{
    spi_transaction_t t;

    memset(&t, 0, sizeof(t));

    t.length = 8;
    t.tx_buffer = &Command;
    t.user=(void*)0;

    assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);
}

static void Display_SendData(const uint8_t* p_Data, uint32_t Length)
{
    spi_transaction_t t;

    if(Length == 0)
    {
        return;
    }

    memset(&t, 0, sizeof(t));

    t.length = Length * 8;
    t.tx_buffer = p_Data;
    t.user=(void*)1;

    assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);
}

static uint32_t Display_ReadID(void)
{
    spi_transaction_t t;

    Display_SendCommand(0x04);

    memset(&t, 0, sizeof(t));
    t.length = 4 * 8;
    t.flags = SPI_TRANS_USE_RXDATA;
    t.user = (void*)1;

    assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);

    return *(uint32_t*)t.rx_data;
}

static void Display_Write(int ypos, uint16_t *linedata)
{
    static spi_transaction_t trans[6];

    for(uint8_t x=0; x<6; x++)
    {
        memset(&trans[x], 0, sizeof(spi_transaction_t));
        if ((x&1)==0) {
            //Even transfers are commands
            trans[x].length=8;
            trans[x].user=(void*)0;
        } else {
            //Odd transfers are data
            trans[x].length=8*4;
            trans[x].user=(void*)1;
        }

        trans[x].flags = SPI_TRANS_USE_TXDATA;
    }

    trans[0].tx_data[0] = 0x2A;
    trans[1].tx_data[0] = 0;
    trans[1].tx_data[1] = 0;
    trans[1].tx_data[2] = 320 >> 8;
    trans[1].tx_data[3] = 320 & 0xFF;

    trans[2].tx_data[0] = 0x2B;
    trans[3].tx_data[0] = ypos >> 8;
    trans[3].tx_data[1] = ypos & 0xFF;
    trans[3].tx_data[2] = (ypos + 1) >> 8;
    trans[3].tx_data[3] = (ypos + 1) & 0xFF;

    // Write the data to memory
    trans[4].tx_data[0] = 0x2C;
    trans[5].tx_buffer = linedata;
    trans[5].length = 320 * sizeof(uint16_t) * 8;
    trans[5].flags = 0x00;

    for(uint8_t x = 0; x<6; x++)
    {
        assert(spi_device_queue_trans(_SPI, &trans[x], portMAX_DELAY) == ESP_OK);
    }
}

static void Display_Busy(void)
{
    spi_transaction_t* rtrans;
    for(uint8_t x=0; x<6; x++)
    {
        assert(spi_device_get_trans_result(_SPI, &rtrans, portMAX_DELAY) == ESP_OK);
    }
}

esp_err_t Display_Init(void)
{
    static uint16_t* Line;

    gpio_set_direction((gpio_num_t)LCD_DC, GPIO_MODE_OUTPUT);
    gpio_set_direction((gpio_num_t)LDC_RESET, GPIO_MODE_OUTPUT);
    gpio_set_direction((gpio_num_t)LCD_BACKLIGHT, GPIO_MODE_OUTPUT);

    if((spi_bus_initialize(HSPI_HOST, &_BusCfg, 0) != ESP_OK) || (spi_bus_add_device(HSPI_HOST, &_DevDcfg, &_SPI) != ESP_OK))
    {
        return ESP_FAIL;
    }

    Display_Reset();
    ESP_LOGI(TAG, "ID: %08X", Display_ReadID());

    uint32_t Commands = sizeof(_Init_Cmd_List) / sizeof(_Init_Cmd_List[0]);
    ESP_LOGI(TAG, "Loading initialization commands: %u", Commands);

    for(uint32_t i = 0x00; i < Commands; i++)
    {
        ESP_LOGI(TAG, "     Command %u / %u", i + 1, Commands);
        Display_SendCommand(_Init_Cmd_List[i].Command);
        Display_SendData(_Init_Cmd_List[i].Data, _Init_Cmd_List[i].Length & 0x1F);
        if(_Init_Cmd_List[i].Length & 0x80)
        {
            vTaskDelay(100 / portTICK_RATE_MS);
        }
    }

    Line = (uint16_t*)heap_caps_malloc(320 * sizeof(uint16_t), MALLOC_CAP_DMA);
    if(Line == NULL)
    {
        return ESP_FAIL;
    }

    for(uint32_t i = 0x00; i < 320; i++)
    {
        Line[i] = 0xF8;
    }

    Display_Write(0, Line);
    Display_Busy();
    free(Line);

    return ESP_OK;
}

And this code results in the following error message:
E (1833) spi_master: check_trans_valid(801): txdata transfer > host maximum
assertion "spi_device_queue_trans(_SPI, &trans[x], portMAX_DELAY) == ESP_OK" failed: file "src/Peripherals/Display/display.cpp", line 225, function: void Display_Write(int, uint16_t*)
abort() was called at PC 0x400e47a4 on core 1

ELF file SHA256: bc86d952445723b2

Backtrace: 0x4008e8c0:0x3ffb4b30 0x4008ecb9:0x3ffb4b50 0x400e47a4:0x3ffb4b70 0x400d170d:0x3ffb4ba0 0x400d1873:0x3ffb4bc0 0x400d13ea:0x3ffb4bf0 0x400d194b:0x3ffb4c20 0x40088601:0x3ffb4c40
  #0  0x4008e8c0:0x3ffb4b30 in invoke_abort at .platformio\packages\framework-espidf@3.40001.200521\components\esp32/panic.c:155
  #1  0x4008ecb9:0x3ffb4b50 in abort at .platformio\packages\framework-espidf@3.40001.200521\components\esp32/panic.c:172
  #2  0x400e47a4:0x3ffb4b70 in __assert_func at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdlib/assert.c:62 (discriminator 8)
  #3  0x400d170d:0x3ffb4ba0 in Display_Write(int, unsigned short*) at src/Peripherals/Display/display.cpp:225 (discriminator 1)
  #4  0x400d1873:0x3ffb4bc0 in Display_Init() at src/Peripherals/Display/display.cpp:288
  #5  0x400d13ea:0x3ffb4bf0 in setup() at src/Application/application.cpp:21
  #6  0x400d194b:0x3ffb4c20 in applicationTask(void*) at src/main.cpp:41
  #7  0x40088601:0x3ffb4c40 in vPortTaskWrapper at .platformio\packages\framework-espidf@3.40001.200521\components\freertos/port.c:143

But the error doesn´t occur when I change the DMA channel from 0 to 1:
if((spi_bus_initialize(HSPI_HOST, &_BusCfg, 1) != ESP_OK) || (spi_bus_add_device(HSPI_HOST, &_DevDcfg, &_SPI) != ESP_OK))
{
    return ESP_FAIL;
}

What´s the difference between both channels and why is only channel 1 working?

Your code initializes the SPI bus by calling the spi_bus_initialize(HSPI_HOST, &_BusCfg, 0) function. The last argument of this function (int dma_chan) defines the DMA channel to use, which can be 0, 1 or 2.
Selecting DMA channel "0" will actually not select a DMA channel at all (which is explained in the Espressif documentation):

dma_chan: Either channel 1 or 2, or 0 in the case when no DMA is required. Selecting a DMA channel for a SPI bus allows transfers on the bus to have sizes only limited by the amount of internal memory. Selecting no DMA channel (by passing the value 0) limits the amount of bytes transfered to a maximum of 32.

The reason you get an error when your ESP32 tries to do an SPI transfer when no DMA channel is selected (option 0), is that the transfer apparently is larger than 32 bytes.
The error produced is "E (1833) spi_master: check_trans_valid(801): txdata transfer > host maximum", which reflects that.
The reason DMA channel 1 works correctly, is because that is an actual DMA channel and it has no limit on the amount of bytes transferred (only limited by the amount of internal memory).


text:
Arduino Project - Social distance detector
I am trying to make a social distance detector for a project of mine. There are many projects online about this, but none of them are the right ones. I'm trying to make a thing that attaches to a lanyard. My original plan was when a PIR sensor detected a human, it would trigger the ultrasonic sensor into measuring the distance between the lanyard and the human. The problem is, the PIR sensor was always displaying "high", and after doing some research, a PIR sensor can be only stationary. I am wondering if there are other easy and cheap options other than PIR sensors that can detect humans accurately? Thanks!

how does attaches to a lanyard make it different from the other projects on the web? ... right now it reads like I'm buiding a race car, but mine will be green

Sorry for not clarifying. The lanyard will be hung around a neck, which is not the same as being a "stationary" human detector that will be attached to a wall.

A normal PIR sensor reacts to movement. It does nit measure distance. Thus it is not interessting for your project. There are other real IR distance sensors. Sensors don't have to be stationary. They will work as long as the involved speed is significantly slower than the sensor. That should be true for IR and ultrasonic sensors for mounting on a human. More important is the direction. When carried around the neck, you need to keep your sensor front facing.

If a PIR sensor doesn't work, what other options I can do to distinguish between humans and objects?


text:
ESP32 Compile Error - Face tracking Pan and tilt camera Arduino
I have been working on a code for a project of mine. I am making an face tracking Pan and tilt camera using the ESP32, but I am getting some errors that I do not know how to solve.
#include <ArduinoWebsockets.h>
#include "esp_http_server.h"
#include <WiFi.h>
#include "camera_index.h"
#include "esp_camera.h"
#include "fb_gfx.h"
#include "fd_forward.h"

const char* ssid = "NSA";
const char* password = "Orange";

// Arduino like analogWrite
// value has to be between 0 and valueMax
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 180)
{
  // calculate duty, 8191 from 2 ^ 13 - 1
  uint32_t duty = (8191 / valueMax) * min(value, valueMax);
  ledcWrite(channel, duty);
}
int pan_center = 90; // center the pan servo
int tilt_center = 90; // center the tilt servo

#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"

using namespace websockets;
WebsocketsServer socket_server;

static inline mtmn_config_t app_mtmn_config()
{
  mtmn_config_t mtmn_config = {0};
  mtmn_config.type = FAST;
  mtmn_config.min_face = 80;
  mtmn_config.pyramid = 0.707;
  mtmn_config.pyramid_times = 4;
  mtmn_config.p_threshold.score = 0.6;
  mtmn_config.p_threshold.nms = 0.7;
  mtmn_config.p_threshold.candidate_number = 20;
  mtmn_config.r_threshold.score = 0.7;
  mtmn_config.r_threshold.nms = 0.7;
  mtmn_config.r_threshold.candidate_number = 10;
  mtmn_config.o_threshold.score = 0.7;
  mtmn_config.o_threshold.nms = 0.7;
  mtmn_config.o_threshold.candidate_number = 1;
  return mtmn_config;
}
mtmn_config_t mtmn_config = app_mtmn_config();

httpd_handle_t camera_httpd = NULL;

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

  // Ai-Thinker: pins 2 and 12
  ledcSetup(2, 50, 16); //channel, freq, resolution
  ledcAttachPin(2, 2); // pin, channel

  ledcSetup(4, 50, 16);
  ledcAttachPin(12, 4);

  ledcAnalogWrite(2, 90); // channel, 0-180
  delay(1000);
  ledcAnalogWrite(4, 90);

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;
  //init with high specs to pre-allocate larger buffers
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif
  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  s->set_framesize(s, FRAMESIZE_QVGA);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  app_httpserver_init();
  socket_server.listen(82);

  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");
}

static esp_err_t index_handler(httpd_req_t *req)
{
  httpd_resp_set_type(req, "text/html");
  httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
  return httpd_resp_send(req, (const char *)index_ov2640_html_gz, index_ov2640_html_gz_len);
}

httpd_uri_t index_uri = {
  .uri       = "/",
  .method    = HTTP_GET,
  .handler   = index_handler,
  .user_ctx  = NULL
};

void app_httpserver_init ()
{
  httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  if (httpd_start(&camera_httpd, &config) == ESP_OK)
    Serial.println("httpd_start");
  {
    httpd_register_uri_handler(camera_httpd, &index_uri);
  }
}

static void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes)
{
  int x, y, w, h, i, half_width, half_height;
  fb_data_t fb;
  fb.width = image_matrix->w;
  fb.height = image_matrix->h;
  fb.data = image_matrix->item;
  fb.bytes_per_pixel = 3;
  fb.format = FB_BGR888;
  for (i = 0; i < boxes->len; i++) {

    // Convoluted way of finding face centre...
    x = ((int)boxes->box[i].box_p[0]);
    w = (int)boxes->box[i].box_p[2] - x + 1;
    half_width = w / 2;
    int face_center_pan = x + half_width; // image frame face centre x co-ordinate

    y = (int)boxes->box[i].box_p[1];
    h = (int)boxes->box[i].box_p[3] - y + 1;
    half_height = h / 2;
    int face_center_tilt = y + half_height;  // image frame face centre y co-ordinate

    //    assume QVGA 320x240
    //    int sensor_width = 320;
    //    int sensor_height = 240;
    //    int lens_fov = 45
    //    float diagonal = sqrt(sq(sensor_width) + sq(sensor_height)); // pixels along the diagonal
    //    float pixels_per_degree = diagonal / lens_fov;
    //    400/45 = 8.89

    float move_to_x = pan_center + ((-160 + face_center_pan) / 8.89) ;
    float move_to_y = tilt_center + ((-120 + face_center_tilt) / 8.89) ;

    pan_center = (pan_center + move_to_x) / 2;
    Serial.println(pan_center);
    ledcAnalogWrite(2, pan_center); // channel, 0-180

    tilt_center = (tilt_center + move_to_y) / 2;
    int reversed_tilt_center = map(tilt_center, 0, 180, 180, 0);
    ledcAnalogWrite(4, reversed_tilt_center); // channel, 0-180

  }
}

void loop()
{
  auto client = socket_server.accept();
  camera_fb_t * fb = NULL;
  dl_matrix3du_t *image_matrix = NULL;

  while (true) {
    client.poll();
    fb = esp_camera_fb_get();
    image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3);

    fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item);

    box_array_t *net_boxes = NULL;
    net_boxes = face_detect(image_matrix, &mtmn_config);

    if (net_boxes) {
      draw_face_boxes(image_matrix, net_boxes);
      free(net_boxes->score);
      free(net_boxes->box);
      free(net_boxes->landmark);
      free(net_boxes);
    }

    client.sendBinary((const char *)fb->buf, fb->len);

    esp_camera_fb_return(fb);
    fb = NULL;
    dl_matrix3du_free(image_matrix);
  }
}

The error that occured was in this section of code:
static esp_err_t index_handler(httpd_req_t *req)
{
  httpd_resp_set_type(req, "text/html");
  httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
  return httpd_resp_send(req, (const char *)index_ov2640_html_gz, index_ov2640_html_gz_len);
}

I got this error in the compiler:
‘index_ov2640_html_gz’ was not declared in this scope

Any ideas on why this happened? Thanks.

That variable is not declared in the code, that you show. What is it and whete did you eant to declare it?


text:
How to pause a loop
any ideas on how could i code this loop so when i press a button everything stops (Vernier stops reading temperature), and then when i press the button again it (Vernier reader) stars working.
   #include "VernierLib.h"
    VernierLib Vernier;
    #define led 13
    #define button 12
    int switchState = 0;
    float sensorReading;
    void setup() {
      Serial.begin(9600);
      Serial.println(Vernier.sensorName());
      Vernier.autoID();
      pinMode(12, INPUT);
    }
    void loop() {
      static float base_temp = 0;
      static float t = 0;
      t = Serial.parseFloat();
      if (t != 0) {
        base_temp = t;
      }
      sensorReading = Vernier.readSensor();
      Serial.print(sensorReading);
      Serial.print(" ");
      Serial.println(Vernier.sensorUnits());
      Serial.print("Željena temperatura: ");
      Serial.println(base_temp);
      if (base_temp > sensorReading) {
        digitalWrite(led, HIGH);
      } else {
        digitalWrite(led, LOW);
      }
      delay(1500);
    }

Assume you did #define BUTTON 12 as I suggested.
Somewhere inside your loop you could code:
if (digitalRead(BUTTON) {        // First button press
  while (digitalRead(BUTTON));   // Wait till button release
  while (!digitalRead(BUTTON));  // Wait till second button press
  while (digitalRead(BUTTON));   // Wait till button release
}

This "hangs" from the first button press to the second button release. The code assumes your button takes pin 12 HIGH when pressed and LOW otherwise. This is a bit difficult to realize in hardware (well, not really; but you will beed an external Pull-Down resistor). The easier way will be to connect pin 12 to GND when button is pressed, and use the internal PullUp-resistor: pinMode(BUTTON, INPUT_PULLUP);. Then the logic of the while condition has to be reverted:
if (!digitalRead(BUTTON) {        // First button press
  while (!digitalRead(BUTTON));   // Wait till button release
  while (digitalRead(BUTTON));    // Wait till second button press
  while (!digitalRead(BUTTON));   // Wait till button release
}

For reading the button I suggest using the Bounce2 library. Then you can wire your button to a fitting digital pin, the other side to ground. Use
button.attach( BUTTON_PIN ,  INPUT_PULLUP );

To use the internal pullup of the Arduino. Define a global state variable, that holds, if your code should run or not.
bool code_running = true;

Then in your main code (additional to calling the update function of the library) use
if(button.fell()){
    code_running = !code_running;
}

to toggle the state variable on button presses. Then, still in void loop(), use an if statement with the state variable to execute your code:
if(code_running){
    // put your code here
}

Note, that your code should not block for long periods for this to work correctly. You should always write your code in a non-blocking way, meaning, that no function call or loop will take longer than a few ms to execute. Otherwise your button action will not be responsive enough.

Yes, i wrote it like you said, but then i get the error at button.attach( BUTTON_PIN , INPUT_PULLUP). I wrote it like this: button.attach(button, INPUT). The error says "request for member  'attach' in '12' // (i defined the button to pin 12), which is of non-class type 'int'" What does this mean?

The code that I showed is from the examples of the Bounce2 library. button is an instance of that class, not the pin number like you tried. Please refer to the examples, that come with the Bounce2 library, and learn how to use the library. Then you should be able to write the button code

You "#define button 12". So the precompiler modifies "button.attach()" to "12.attach()", thus the error message.

To avoid those errors (especially in larger programs), try to use different terminology for constants and variables/objects. Usually you will #define BUTTON 12, so button may be used as variable without errors. And do not define a pin number at the start when you do not use the definition later on - use pinMode(BUTTON, INPUT) and digitalRead(BUTTON) - it will save you hours of debugging later on.


text:
Use 2 DHT22 AND PASS THE DATA TO SD Error File data does not exsist
anyone can help me please to fix this error when I try to compilate says File does not exsist. It would be great if anyone can post the entirely code.
Link of code below if anyone can help me please:
https://create.arduino.cc/editor/Jawad2001/5ea57339-7ca1-4f8d-ab00-f4f1aa639209/preview
error: expected')' before 'f'
Sorry I'm new at this sorry for the annoyances.
Thanks For all your Help.

#include <SD.h>;

I don't know why but says expected initializer  before "." token

sorry, without ;. it should be #include <SD.h>

I know but i did it without ;

i don't know why but the program says the error is in Filedata2.txt

this line is defining a variable File data.txt;  (it is actually an object) .... you cannot have a period . in a variable name, maybe use an underline instead. File data_txt;

It helped but now i have other problem in void get data

data_file was not declared in this scope i publicated the new errors

@jawadbouhali, i formatted the error printout so that it was readable and you messed it up again ...... please use the {} to format the error printout

data_file was not declared in this scope ..... are you saying that you declared the variable name data_file?   ..... where did you declare it? ....... please look at the errors one at a time and try to figure out why they are being presented ....... do not look at all of the errors at the same time, that leads to confusion

The code needs to be inside the post, not behind a link.

Here are several things I can see from your code that cause most of the error messages.
1) You declare
File data_txt;
File data2_txt;

but you later use data_file and data_file2. This is why you see the "not declared in this scope" errors.
2) You do not properly define the functions getData() and getData2(). You start with the definition of getData2() inside the function getData().
First finish the function getData() by closing all brackets you opened and then define the function getData2(), like this:
void getData() {
//the code of getData() goes here....
}

void getData2() {
//the code of getData2() goes here....
}

3) I assume you want to write to data_file in getData() and to data_file2 in getData2()?! Nevertheless, you also use data_file in getData2().
Update after your edit:
Regarding the compilation error, you do not open a curly bracket
{
after getData2().
However, there are several other issues that will lead to problems, even if it finally does compile without problems.


text:
how do i fill an array from a grayscale sensor (SKU:SEN0147)?
I'm designing a safe lock of 4 digits, but the password is in terms of colors, I have 3 colors. we are obliged to use a grayscale sensor (SKU: SEN0147).
The assignment is as follows:
Write a program on Arduino that will be used as a safe lock. Consider having 3 colors black white and grey. Black = 0, Red = 1 and White = 2.
• When the microcontroller is turned on, the safe is locked. The Serial Monitor should display: “System is online.”
• The combination lock should be saved in an array of integers called arr_code.
• The user has 3 trials to open the safe
• The system will wait for the user to enter 4 colors. To enter a color, the grayscale sensor should be place on top of the desired color. Once ready the push button is pressed. Once released, the color is saved in another array called arr_user_code.
• Once 4 colors are entered, the system should test automatically if the code entered by
the user is equal to the code saved in arr_code.
• If the wrong code is entered, the serial monitor displays: “Wrong Code. Try Again.”
• If the user enters the wrong code 3 times in a row the system is locked and a message is
displayed: “System Locked.”
• If the correct code is inserted, the Led on pin 13 is turned on.
• The combinations entered by the user should be displayed on the Serial Monitor. The Arduino program should be clear, separated into functions and documented.
The program I wrote is the following:
char led_pin = 13;
char pb_pin = 4;
int gs_pin = A3;

int arr_code[4] = {14, 14, 14, 14};//color im testing on
int arr_user_code[4];

int counter;
int Lock_Interval = 2500;
bool compare;

bool equal = true;

bool Array_Compare(int *a, int *b) {//function for comparision
  for (int i = 0; i < 4; i++) {
    if (a[i] != b[i]) return false;
  }
  return true;
}

void Button_Wait(int buttonPin) {//function to sense if button is pressed
  int curr_state;
  int prev_state;

  while (1) {
    prev_state = curr_state;
    curr_state = digitalRead(buttonPin);
    if (curr_state != prev_state) {
      if (curr_state == false) {
        delay(10);
        return;
      }
    }
  }
}

int GS_Value(int gsPin) {//function to get GSsensor value
  Button_Wait(pb_pin);
  int gs_value = analogRead(gs_pin);
  return gs_value;
}

void setup() {
  // put your setup code here, to run once:
  pinMode(led_pin, OUTPUT);
  pinMode(pb_pin, INPUT);

  Serial.begin(9600);//sync

  digitalWrite(led_pin, false);//start with a turned off LED
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("System Online");
  Serial.println("Please Enter Passcode: ");

  for (counter = 0; counter < 3; counter++) {
    for (int i = 0; i < 4; i++) {
      arr_user_code[i] = GS_Value(gs_pin); //uploading GSsensor values to array !!!the problem is here!!!

      Serial.print('GS_Value');//printing GSsesnor values on monitor
      Serial.print(" ");//inserting space
    }
    Serial.println(" ");//skipping a line after every attempt

    compare = Array_Compare( arr_code[4], arr_user_code[4]); // compare arrays and return false if not equal

    if (compare == true) {//in case arrays are equal
      Serial.println("System UNLOCKED!");
      digitalWrite(led_pin, true);
    }

    else if (compare == false) {//in case arrays arent equal
      Serial.println("Wrong Passcode. Try Again");
    }
  }

  if (compare == false) {
    Serial.println("System LOCKED");
    while (1) {
      Lock_Interval = Lock_Interval * 2;
      delay(Lock_Interval);
      return;
    }
  }
  delay(100);
}

the issue is that the arr_user_code isnt actually filling with the correct sensor values but a value between 20000 and 30000. Thank you in advance.

How do you know the values? I don't see you printing them anywhere.

please proofread your post

you have no code that prints tthe value of GS_Value ........... why are you comparing arrays?


text:
ESP32-CAM rst:0x8 TG1WDT_SYS_RESET bootloop
I have ESP32-CAM that I plan to use as a simple security camera. I tested the software and it was working perfectly. I programmed it using FTDI programming board with 5V. After testing everything I decided to power it with an old adapter (5V 160mA) I had for some time but when I powered with adapter the power started flickering. When I noticed it I immediately unplugged the adapter but since then I started getting stuck in bootloop. Here is the output I get:
12:56:10.663 -> ets Jul 29 2019 12:21:46
12:56:10.667 ->
12:56:10.667 -> rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
12:56:10.667 -> waiting for download
12:56:49.327 -> ets Jul 29 2019 12:21:46
12:56:49.327 ->
12:56:49.327 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
12:56:49.327 -> configsip: 0, SPIWP:0xee
12:56:49.327 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
12:56:49.327 -> mode:DIO, clock div:2
12:56:49.327 -> load:0x3fff0030,len:1344
12:56:49.327 -> load:0x40078000,len:13836
12:56:49.327 -> load:0x40080400,len:3608
12:56:49.327 -> entry 0x400805f0
12:56:50.707 -> ets Jul 29 2019 12:21:46
12:56:50.707 ->
12:56:50.707 -> rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
12:56:50.707 -> configsip: 0, SPIWP:0xee
12:56:50.707 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
12:56:50.707 -> mode:DIO, clock div:2
12:56:50.707 -> load:0x3fff0030,len:1344
12:56:50.707 -> load:0x40078000,len:13836
12:56:50.707 -> load:0x40080400,len:3608
12:56:50.707 -> entry 0x400805f0
12:56:52.086 -> ets Jul 29 2019 12:21:46
12:56:52.086 ->
12:56:52.086 -> rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
12:56:52.086 -> configsip: 0, SPIWP:0xee
12:56:52.086 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
12:56:52.086 -> mode:DIO, clock div:2
12:56:52.086 -> load:0x3fff0030,len:1344
12:56:52.086 -> load:0x40078000,len:13836
12:56:52.086 -> load:0x40080400,len:3608
12:56:52.086 -> entry 0x400805f0

It keeps going like this. I can upload new code without any problems but every code I upload gets stuck in this exact bootloop. Load and entry adresses does not change. I also tried programming with arduino nano instead of ftdi but nothing changed.
I am using Arduino IDE 2.0.0 on Linux Mint 21 OS. I also tried it on Windows 10 but the results didn't change. I am quite new to ESP32 so I don't know how to debug it either.
Thanks in advance.
##############
UPDATE 25/10/2022
After timemage's comment I tried a few more codes and one of arduino ide's example codes ran once with error. I couldn't get the error log but there was something like "PSRAM ID Read error 0xffffff" and another log pointing to a corrupted address.
After that I tried uploading another sketch without PSRAM with following settings:

Board: ESP32 Dev Module
CPU frequency: 240MHz(WiFi/BT)
Events run on: Core 1
Flash frequency: 80MHz
Flash mode: QIO
Flash size: 4MB(32Mb)
Arduino runs on: Core 1
PSRAM: Disabled
Partition scheme: Huge
APP(3MB No OTA/1MB SPIFFS)
Upload speed: 115200

and it worked. But I need PSRAM for my project. So my question is: can it be a hardware problem ? If not, how can I fix it ?
Thanks again.

"every code I upload gets stuck in this exact bootloop" This holds true if that new code is just a blink sketch or hello world on serial?

@timemage It holded true for every sketch I tried so far. But after your comment I tried more sketches and made some more progress and edited my question, so thanks.

Selecting "AI Thinker ESP32-CAM" doesn't expose the menu option called "PSRAM". You say "tried uploading another sketch without PSRAM"  This makes me wonder: What board have you been selecting? If not the AI Thinker ESP32-CAM, what happens when you switch to it? Were you using AI Thinker board and then switched to a generic option just so that you'd be able to test with PSRAM set to "Disabled"?

@timemage I selected "ESP32 Dev Module". Added details about configurations to question.

It is starting to look like damage. I took your custom settings and tested them on a ESP32-CAM with nothing attached and did not get your boot loop. The PSRAM chip is not under the RF shield, which makes it comparatively replaceable.  If it were me, I might consider probing the PSRAM chip from another board, but it's not clear how to do that with the the ESP32 in reset, because the SPI FLASH chip on the same bus is not pulled to inactive and that contact is not exposed. Hopefully someone else has a better idea of what if anything to try next.

Is your esp32_cam comes with PSRAM?  I had a program running on esp32 wrover with PSRAM, the same code could not run on esp32 wroom.  After checking, the esp32 wroom does not come with PSRAM.

Say that the esp32_cam does come with PSRAM, how do you initilize it?

My code has ISR to force shutdown after 15min of wakeup from deep sleep, I will get the same error with reset when there is a while loop or for loop, and i missed these 2 line of codes.
vTaskDelay( 3 / portTICK_PERIOD_MS );
esp_task_wdt_reset();

hopefully, this helps.

From my personal experience working with the ESP-CAM's ESP32-s3 chip, the particular error is the result of an invalid line of code.
The best way to address this is to look very closely at the code that you've written, for some of the errors you may introduce through the arduino ide may not be caught in the compilation process.
For example, I was building out a UART shell using the same processor.
My code was producing the same error because of this code here:
private:
    size_t commandsLen = 1;
    string commands[1]{
        "lcdcam"
    };

I was able to fix the reset loop by correcting the syntax in my string array. Which was missing an equals sign.
The following modification fixed my particular issue, and odds are that your problem is syntax related like mine.
private:
    size_t commandsLen = 1;
    string commands[1] = {
        "lcdcam"
    };

Edit:
Upon further inspection, there was an additional issue that also caused this error.
Take the following code into consideration:
public:
    bool commandSwitch(Uart uart, BosCommand cmd){
        if(cmd.getCommandLength() <= 0){
            sendOutput(uart, "Failed to find commands.\n\r");
            return false;
        }
        string target = cmd.getCommandArg(0);

        if(target == "lcdcam"){
            BosCommandSwitch targetCmd;
            targetCmd.init(uart, cmd);
            return targetCmd.process();
        }else{
           // removed
        }
        return false;
    }

The issue is that the processor doesn't like it when I declare the BosCommandSwitch class inside the if logic. Not only did fixing the string array correct the reset bug, but moving the declaration of the class object up into the private section of my class allowed all my code to run without the automated reset.
private:
    BosCommandSwitch targetCmd;
public:
    bool commandSwitch(Uart uart, BosCommand cmd){
        if(cmd.getCommandLength() <= 0){
            sendOutput(uart, "Failed to find commands.\n\r");
            return false;
        }
        string target = cmd.getCommandArg(0);

        if(target == "lcdcam"){
            targetCmd.init(uart, cmd);
            return targetCmd.process();
        }else{
           // removed
        }
        return false;
    }

I believe that the issue is related to memory allocation. Once you get deep into logic, you reduce the amount of available memory in a particular region. Though this is just speculation on my part.

I got the same "rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)" and crash when using the M5stack-Timer-Camera after doing a "SerialM.setDebugOutput(true);" then starting the camera with "camera_init()" and then doing an "EEPROM.commit".
When I remove the "SerialM.setDebugOutput(true);" the error/crash goes away and instead I just get a (Serial-Terminal) warning of "cam_hal: EV-EOF-OVF" when doing an "EEPROM.commit".
So in my case I suspect that the "SerialM.setDebugOutput(true)" was causing the "cam_hal: EV-EOF-OVF" error message to crash during the "EEPROM.commit".

I had a similar problem when running test code for a data input module based on the NodeMCU-32s board. The board would reset about once per second with that same error. That turned out to be my error. I had confused the physical pin number of the board with the GPIO number. I am assuming that trying to read GPIO pins that are not routed to the chip pins was still accessing internal registers, and was enough to initialize the watchdog timer. Since I was otherwise doing nothing to the watchdog, (like resetting it frequently,) the watchdog was properly doing its job and resetting the part.
This wasn't obvious to me. In the Arduino environment, setting Tools->Core Debug Level to Verbose gave some clues. Turning off some of my use of GPIO inputs also got me to a point where the watchdog error stopped, and from there I was able to proceed. So long story shorter, I recommend checking your pin assignments for IO!


text:
Continous Rotation Servo not changing directions
I have coded a robot to be controlled by a ps3 Controller. I am using continous rotation servos but unfortunately I can not figure out how to get them to change direction. My input for my if statements is correct, but for some reason even if the input from the PS3 controller shows to do the reverse direction, the continuous rotation servo still rotates forward.
Here is my Code:
  #include <PS3BT.h>
  #include <usbhub.h>

  // Satisfy the IDE, which needs to see the include statment in the ino too.
  #ifdef dobogusinclude
  #include <spi4teensy3.h>
  #endif
  #include <SPI.h>

  #include <Servo.h>

  USB Usb;
  //USBHub Hub1(&Usb); // Some dongles have a hub inside

  BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
  /* You can create the instance of the class in two ways */
  PS3BT PS3(&Btd); // This will just create the instance
  //PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch

  bool printTemperature, printAngle;

  // identifying servos
  Servo LeftServo;
  Servo RightServo;

  void setup() {
    Serial.begin(115200);
    #if !defined(__MIPSEL__)
    while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  #endif
    if (Usb.Init() == -1) {
      Serial.print(F("\r\nOSC did not start"));
      while (1); //halt
     }
    Serial.print(F("\r\nPS3 Bluetooth Library Started"));

  // Attaching Pins to Servos
    LeftServo.attach(2);
    RightServo.attach(3);

  }
  void loop() {
    Usb.Task();

    if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
    if (PS3.getAnalogHat(LeftHatY) < 117){
Serial.print(F("\tLeftHatY: "));
Serial.print(PS3.getAnalogHat(LeftHatY));
  LeftServo.attach(2);
LeftServo.write(180);

}
else if (PS3.getAnalogHat(LeftHatY) > 140) {
     Serial.print(F("\tLeftHatY: "));
Serial.print(PS3.getAnalogHat(LeftHatY));
    LeftServo.attach(2);
  LeftServo.write(0);
  }
else {
LeftServo.detach();
   }
   }
    }

I added the rest of my code, I thought to only post the relevant section but this has changed.

forget about your code for now ... write a simple program that runs the motor in one direction for two seconds, stops the motor,  then runs the motor in the opposite direction

please, format your code properly ... it is a mess that is difficult to read

What are the specific servos that you’re using?

Are you able to add a schematic showing how you’re connecting and powering the servos?

Is this related to your other question yesterday? https://arduino.stackexchange.com/questions/91238/different-code-needed-for-continuous-rotation-servo

im new in Arduino projects but i think this might work, try changing some things in your else sttement, you should try and change this
LeftServo.attach(2);
  LeftServo.write(0);

Try changing it to this
LeftServo.attach(2);
  LeftServo.write(180*(-1));
// or, LeftServo.write(-180);
/* if you use (180*(-1), the servo might go the opposite direction continuously until
(PS3.getAnalogHat(LeftHatY) is less than 117 */