text:
ESP32 CAM : How to send good quality images via MQTT
Has anyone here ever used a ESP32 CAM to send an image via MQTT? I'd like to know what are the parameters to initialize the camera with (resolution, jpeg quality, etc.), because once I receive the camera on the other side, it's highly compressed and to be frank really ugly.
I'm using FRAMESIZE_SVGA with jpeg quality of 12. I want the best of both worlds actually: I want a good quality image and I don't want to overload the MQTT packet as I want to be able to receive the image faster. If resolution is high, it usually takes a few minutes to receive anything.
Here's my camera's config:
void initCamera()
{
  // https://github.com/botabotlab/ESP32CAM-MQTT/blob/master/ESP32_Cam_MQTT/ESP32_Cam_MQTT.ino (initCamera and capturePicture)
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer   = LEDC_TIMER_0;
  config.pin_d0       = 5;
  config.pin_d1       = 18;
  config.pin_d2       = 19;
  config.pin_d3       = 21;
  config.pin_d4       = 36;
  config.pin_d5       = 39;
  config.pin_d6       = 34;
  config.pin_d7       = 35;
  config.pin_xclk     = 0;
  config.pin_pclk     = 22;
  config.pin_vsync    = 25;
  config.pin_href     = 23;
  config.pin_sscb_sda = 26;
  config.pin_sscb_scl = 27;
  config.pin_pwdn     = 32;
  config.pin_reset    = -1;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  // QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
  // Change resolution of image here
  config.frame_size = FRAMESIZE_SVGA;
  config.jpeg_quality = 10;
  config.fb_count     = 1;

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
}

This question is not really answerable without knowing what is an acceptable compression and resolution. This is really up to you and what you will be using the images for, the update frequency of the images and what bandwidth you have available. As an example, some of my ESP32 cameras are controlled with MQTT but upload via HTTPS at 1280x1024 with quality 8, at around 150KB per uploaded image. But YMMV.

@StarCat Thank you. When you say you upload your images via HTTPS and you send MQTT commands. Do you mean you have a webserver running on the esp32 that posts the image and the MQTT commands are to activate that post?

Good question. I’m using MQTT for controlling the camera (resolution, quality, brightness, contrast, timing of the images etc) and I run a HTTPS client on the ESP32 that uploads each image to my web server that runs a PHP script to receive, store and show the images.

Interesting! Thank you!


text:
Morse encoder code not working as expected on Arduino UNO
I'll start saying that I don't have much experience working with Arduino and programming in C. I have an Elegoo Arduino UNO clone.
Recently I was trying to build a morse encode which converts a text to morse and then flashes a LED to communicate the morse code. The code is as follows
#define OUT_PIN 8
#define END_PIN 7

const short dot_time = 200; // Time LED is ON for dot
const short dash_time = dot_time*3; // Time LED is ON for dash
const short same_letter_space = dot_time; // Time LED is OFF between dots/dashes of the same letter
const short letter_space = dot_time*3; // Time LED is OFF between letters
const short word_space = dot_time*5; // Time LED is OFF between words
const char letter_separator[] = "_";
const char word_separator[] = "/";

typedef struct {
  char * morse;
  char letter;
}morse_pair;

morse_pair morse_table_letters[] = {{".-", 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-..", 'D'}, {".", 'E'}, {"..-.", 'F'}, {"--.", 'G'}, {"....", 'H'}, {"..", 'I'}, {".---", 'J'},//
{"-.-", 'K'}, {".-..", 'L'}, {"--", 'M'}, {"-.", 'N'}, {"---", 'O'}, {".--.", 'P'}, {"--.-", 'Q'}, {".-.", 'R'}, {"...", 'S'}, {"-", 'T'}, {"..-", 'U'}, {"...-", 'V'},
{".--", 'W'}, {"-..-", 'X'}, {"-.--", 'Y'}, {"--..", 'Z'}};
morse_pair morse_table_digits[] = {{"-----", '0'}, {".----", '1'}, {"..---", '2'}, {"...--", '3'}, {"....-", '4'}, {".....", '5'}, {"-....", '6'}, {"--...", '7'}, {"---..", '8'},//
{"----.", '9'}};

char test_text[] = "aaa";

morse_pair letter_encoder(char letter){
  int letter_value = (int) letter;
  if(letter_value >= 97){
    //lowercase
    return morse_table_letters[letter_value-97];
  }
  else if (letter_value>=65){
    //uppercase
    return morse_table_letters[letter_value-65];
  }
  else {
    //digits
    return morse_table_digits[letter_value];
  }
}

char* word_to_morse(char* word, size_t len){
  Serial.print("Encoding word: ");
  Serial.println(word);
  size_t len_morse = 0;
  char* letters[len];
  for(size_t l=0;l<len;l++){
    letters[l] = letter_encoder(word[l]).morse;
    len_morse += strlen(letters[l])+1;
  }
  char* morse_string = malloc(len_morse*sizeof(char));
  for(size_t l=0;l<len;l++){
    strcat(morse_string, letters[l]);
    if(l<len-1){
      strcat(morse_string, letter_separator);
    }
  }
  strcat(morse_string, word_separator);
  Serial.print("Result: ");
  Serial.println(morse_string);
  return morse_string;
}

char* text_to_morse(char* text){
  Serial.print("Encoding text: ");
  Serial.println(text);
  size_t len = strlen(text);
  char* text_morse = malloc((4*len+len)*sizeof(char));
  char* swp = text;
  for(char* ewp = text;ewp!=(text+len);ewp++){
    if(*(ewp+1)==' ' || *(ewp+1) == '\0'){
      char * wtm = word_to_morse(swp, ewp-swp+1);
      strcat(text_morse, wtm);
      swp=ewp+2;
      free(wtm);
    }
  }
  Serial.print("Result: ");
  Serial.println(text_morse);
  return text_morse;
}

void morse_to_pin(char* text_morse){
  Serial.println("Playing with pins");
  size_t len = strlen(text_morse);
  for(size_t l=0;l<len;l++){
    char letter = text_morse[l];
    Serial.println(letter);
    if(letter == '.'){
      digitalWrite(OUT_PIN, HIGH);
      delay(dot_time);
    }
    else if(letter=='-'){
      digitalWrite(OUT_PIN, HIGH);
      delay(dash_time);
    }
    else if(letter=='_'){
      digitalWrite(OUT_PIN, LOW);
      delay(letter_space);
    }
    else if(letter=='/'){
      digitalWrite(OUT_PIN, LOW);
      delay(word_space);
    }
    else {
      digitalWrite(OUT_PIN, LOW);
      delay(same_letter_space);
    }
  }
}

void start_comm(){
  Serial.println("Start comm.");
  digitalWrite(END_PIN, HIGH);
  delay(2000);
  digitalWrite(END_PIN, LOW);
}

void end_comm(){
  Serial.println("End comm.");
  digitalWrite(END_PIN, HIGH);
  delay(500);
  digitalWrite(END_PIN, LOW);
  delay(500);
  digitalWrite(END_PIN, HIGH);
  delay(500);
  digitalWrite(END_PIN, LOW);
}

void setup(){
  Serial.begin(9600);
  pinMode(OUT_PIN, OUTPUT);
  pinMode(END_PIN, OUTPUT);
}

void loop ()
{
  start_comm();
  delay(1000);
  char* ttm = text_to_morse(test_text);
  morse_to_pin(ttm);
  free(ttm);
  delay(1000);
  end_comm();
  delay(1000);
}

The part of the code that converts text to a morse string behaves correctly when run on my laptop, but when I upload it to my Arduino UNO behaves weirdly and the morse LED doesn't flashes at all.

Edit:
the Arduino UNO just seems to run only the start_comm and end_comm functions, as if there's nothing inbetween. It changed behaviour and doesn't behaves always the same, before it printed some garbage to the serial monitor, but now it just skips the whole code inbetween the two functions mentioned above.

So how exactly is the text_to_morse() function behaving on the Uno? Is it printing the correct morse text? If not: What is it actually printing? We need to narrow down the error source here

@chrisl you're right, I'll update as soon as I can with and example

"behaves correctly when run on my laptop, but" not on "my Arduino UNO". you use malloc(), it works on your laptop because your laptop have plenty of memory, but only has 2k RAM in Arduino. You should check whether your malloc() allocated memory successfully in the heap with if (text_morse != NULL) { // rest of your code };, or better off, not to use static allocated memory than dynamic allocated memory.

I kind of solved it, I was using malloc incorrectly and was accessing uninitialized bits, thus causing undefined behaviour. The code below should work correctly
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define OUT_PIN 8
#define END_PIN 7

const short dot_time = 200; // Time LED is ON for dot
const short dash_time = dot_time * 3; // Time LED is ON for dash
const short same_letter_space = dot_time; // Time LED is OFF between dots/dashes of the same letter
const short letter_space = dot_time * 3; // Time LED is OFF between letters
const short word_space = dot_time * 5; // Time LED is OFF between words
const char letter_separator[] = "_";
const char word_separator[] = "/";
const char unkown_letter[] = "?";

typedef struct {
  char * morse;
  char letter;
} morse_pair;

const morse_pair morse_table_letters[] = {{".-", 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-..", 'D'}, {".", 'E'}, {"..-.", 'F'}, {"--.", 'G'}, {"....", 'H'}, {"..", 'I'}, {".---", 'J'},//
  {"-.-", 'K'}, {".-..", 'L'}, {"--", 'M'}, {"-.", 'N'}, {"---", 'O'}, {".--.", 'P'}, {"--.-", 'Q'}, {".-.", 'R'}, {"...", 'S'}, {"-", 'T'}, {"..-", 'U'}, {"...-", 'V'},
  {".--", 'W'}, {"-..-", 'X'}, {"-.--", 'Y'}, {"--..", 'Z'}
};
const morse_pair morse_table_digits[] = {{"-----", '0'}, {".----", '1'}, {"..---", '2'}, {"...--", '3'}, {"....-", '4'}, {".....", '5'}, {"-....", '6'}, {"--...", '7'}, {"---..", '8'},//
  {"----.", '9'}
};

const char* letter_encoder(char letter) {
  int letter_value = (int) letter;
  if (letter_value >= 97 && letter_value <= 122) {
    //lowercase
    return morse_table_letters[letter_value - 97].morse;
  }
  else if (letter_value >= 65 && letter_value <= 90) {
    //uppercase
    return morse_table_letters[letter_value - 65].morse;
  }
  else if (letter_value>=48 && letter_value<=57) {
    //digits
    return morse_table_digits[letter_value].morse;
  }
  else {
    //Boh
    return unkown_letter;
  }
}

void word_to_morse(char* morse_word, char* word, int len) {
  Serial.print("Encoding word: ");
  Serial.println(word);
  for (int l = 0; l < len; l++) {
    strcat(morse_word, letter_encoder(word[l]));
    if (l < len - 1) {
      strcat(morse_word, letter_separator);
    }
  }
  strcat(morse_word, word_separator);
  Serial.print("Word result: ");
  Serial.println(morse_word);
}

void text_to_morse(char* morse_text, char* text, int len) {
  Serial.print("Encoding text: ");
  Serial.println(text);
  char* swp = text;
  int morse_len = 0;
  for (char* ewp = text; ewp != (text + len); ewp++) {
    if (*(ewp + 1) == ' ' || *(ewp + 1) == '\0') {
      int w_len = ewp - swp + 1;
      char * morse_word = (char*) malloc((5*w_len+w_len)*sizeof(char));
      strcpy(morse_word, "");
      word_to_morse(morse_word, swp, w_len);
      morse_len += strlen(morse_word);
      Serial.print("Word result: ");
      Serial.println(morse_word);
      Serial.print("Word len: ");
      Serial.println(morse_len);

      strcat(morse_text, morse_word);
      swp = ewp + 2;
      free(morse_word);
    }
  }
  morse_text = (char*) realloc(morse_text, ++morse_len*sizeof(char));
  Serial.print("Text result: ");
  Serial.println(morse_text);
}

void morse_to_led(const char* text_morse, int len) {
  Serial.println("Flashing morse with pins");
  for (int l = 0; l < len; l++) {
    char letter = text_morse[l];
    Serial.println(letter);
    switch(letter){
      case '.':
        digitalWrite(OUT_PIN, HIGH);
        delay(dot_time);
        break;
      case '-':
        digitalWrite(OUT_PIN, HIGH);
        delay(dash_time);
        break;
      case '_':
        digitalWrite(OUT_PIN, LOW);
        delay(letter_space);
        break;
      case '/':
        digitalWrite(OUT_PIN, LOW);
        delay(word_space);
        break;
      default:
        digitalWrite(OUT_PIN, LOW);
        delay(same_letter_space);
        break;
    }
  }
}

void start_comm() {
  Serial.println("Start comm.");
  digitalWrite(END_PIN, HIGH);
  delay(dash_time);
  digitalWrite(END_PIN, LOW);
}

void end_comm() {
  Serial.println("End comm.");
  digitalWrite(END_PIN, HIGH);
  delay(dot_time);
  digitalWrite(END_PIN, LOW);
  delay(dot_time);
  digitalWrite(END_PIN, HIGH);
  delay(dot_time);
  digitalWrite(END_PIN, LOW);
}

void setup() {
  Serial.begin(9600);
  pinMode(OUT_PIN, OUTPUT);
  pinMode(END_PIN, OUTPUT);
}

void loop ()
{
  //Start
  start_comm();
  delay(2000);

  //Convert
  char test_text[] = "test";
  int len = strlen(test_text);
  char * morse_text = (char*) malloc((5*len+len)*sizeof(char));
  strcpy(morse_text, "");
  text_to_morse(morse_text, test_text, len);
  morse_to_led(morse_text, strlen(morse_text));
  free(morse_text);
  delay(2000);

  //End
  end_comm();
  delay(2000);
}

source: Stack Exchange

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

sort: votes


text:
ESP32 Bluetooth Master does not connect
I want to connect an ESP32 to a SMA Sunny Boy SB5000-TL Solar convertor over Bluetooth, but I cannot establish a connection and I'm kind of stuck.
I use the internal bluetooth module of the ESP32.
What I've done:

I started with this project: https://github.com/delhatch/ESP32_to_SMA but I did not get past the connection. I tried to locate the problem area:

I tried using an Android app (Oxley Solar) to connect to the SB5000-TL Solar convertor, and that works great. The pin code of the convertor is set to 0000.

I tried using two ESP32 modules, one as master, one as slave and that works as well, though I do not need to set a pin. So the bluetooth module of my ESP32 works properly.

So the problem must be in my code, I guess.
This is the code I use to connect to the convertor:
#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;
boolean confirmRequestPending = true;

// uint8_t ESP32Slave[6]  = {0x84, 0xCC, 0xA8, 0x2C, 0x70, 0x1E}; // Address of Slave.
uint8_t SMA[6]  = {0x00, 0x40, 0x65, 0x12, 0x4B, 0x3E}; // Address of my SMA inverter.
const char *pin = "0000"; //<- standard pin

void setup() {
  Serial.begin(115200);
  SerialBT.enableSSP();
  SerialBT.onConfirmRequest(BTConfirmRequestCallback);
  SerialBT.onAuthComplete(BTAuthCompleteCallback);
  SerialBT.begin("ESP32master", true); //Bluetooth device name
  SerialBT.register_callback(callback);
  SerialBT.setPin("0000");
  Serial.println("Connecting...");
  bool connected = SerialBT.connect(SMA);
  if (connected) {
    Serial.println("Connected!");
  } else {
    Serial.println("NOT Connected!");
  }
  delay(500);
  SerialBT.end();
  Serial.println("Bye!");
}

void loop() {

}

void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
  Serial.print("Got event!");  Serial.println(event);
}

void BTConfirmRequestCallback(uint32_t numVal)
{
  confirmRequestPending = true;
  Serial.println(numVal);
}

void BTAuthCompleteCallback(boolean success)
{
  confirmRequestPending = false;
  if (success)
  {
    Serial.println("Pairing success!!");
  }
  else
  {
    Serial.println("Pairing failed, rejected by user!!");
  }
}

This is the result in the Serial console:
Connecting...
Got event!0
Got event!8
NOT Connected!
Got event!1
Bye!

I tried to replace the Mac Address with the name of the Convertor,
I tried with and without pin.
I'm kind of stuck.
Any idea's of how I can check what is wrong?
Is there any kind of scanner I can use to see what is happening with the app that works and what is (not) happening with my code?
Other ways to get more info/leads?
Could I use a Bluetooth sniffer or so (no experience) to find out what happens?
Any advice would be greatly appreciated!

I have searched the net for a solution for this issue for esp32 trying to connect as a serial master . All i can find is that there is a connection success reporting issue with BluetoothSerial.h while using the correct address or name of the slave .latest version 1.4 i think reports as connection successful, when it is not. version 1.3 reports connection failed. Very frustrating with no updated fix at github. You have probably noticed that all examples of BLE classic use an esp32 as slave and an android phone connecting as a master to switch relays on and off on a BLE board . But there are no

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


text:
Sunfounder IR remote controller issue
I've been making a hoverboard using arduino, tinkercad and c++ (pic included). When I wired it up irl, I wired it exactly as I did in the picture (arduino UNO)
However, when I tested it out, it didn't work. The IR sensor got signal from my Sunfounder IR remote, but the fans didn't turn like I expected it to. The entire thing works fine with tinkercad.
I'm really sure it's not my wiring, since I took extra extra care to wire it properly.
This leads me to believe that it's a problem with my remote code
The IR remote control used was a random one in tinkercad. I'm using sunfounder ir remote irl.
Starting line 37, I've put code that uses the remote in the tinkercad to control the motors.
Is it possible that I need to recode specifically with the cases of the sunfounder IR remote? If so, where can I find a list of what buttons are what cases/code. so that I can rewire the entire thing?
I hope you all can help me. Thank you! :)

Did you check what codes the real remote sends fpr each button? They are most likely not the same as in tinkercad. Have you tried printing the received values to Serial so that you can see them in the Serial Monitor?

why would you need a list of codes?

You're saying that your remote is SunFounder's so I assume this is the one?

If it is then this should be the equivalent codes:

Try if it works for you.


text:
How to use HC-SR04 sensor to make a flowmeter?
I am somewhat familiar with Arduino and am trying to use two ultrasonic HC-SR04 modules to measure the direction of water flow inside a pipe. The sensors are kept as in the image below.
The direction is determined by emitting a signal from one sensor and receiving it in the other, noting down the time and repeating with the other set(See image below). This is called an ultrasonic time of flight flowmeter.
We then use the obtained values to determine the direction by seeing which one is greater. Further details on how it works can be found here: https://www.youtube.com/watch?v=rqJ9snaqYiY

I used the below code to collect the data to determine direction for this but it doesn't seem to be working, as only the first value is displayed and the second is always 0.
long firstduration = 0;
long secondduration = 0;

void setup() {
  // put your setup code here, to run once:
pinMode(13, OUTPUT);
pinMode(12, INPUT);
pinMode(11, INPUT);
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(13,LOW);
delayMicroseconds(2);
digitalWrite(13,HIGH);
delayMicroseconds(10);
digitalWrite(13,LOW);
firstduration = pulseIn(12,HIGH);
secondduration = pulseIn(11, HIGH);
Serial.print(firstduration);
Serial.print(", ");
Serial.println(secondduration);
}

Updated code:
long firstduration;
long secondduration;

void setup() {
  // put your setup code here, to run once:
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
pinMode(12, INPUT);
pinMode(11, INPUT);
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(13,LOW);
delayMicroseconds(2);
digitalWrite(13,HIGH);
delayMicroseconds(10);
digitalWrite(13,LOW);
firstduration = pulseIn(12,HIGH);

digitalWrite(10,LOW);
delayMicroseconds(2);
digitalWrite(10,HIGH);
delayMicroseconds(10);
digitalWrite(10,LOW);
secondduration = pulseIn(11,HIGH);

Serial.print(firstduration);
Serial.print(", ");
Serial.println(secondduration);
}

What would the issue be?
I am using an Arduino Uno board.
I have ruled out wiring issues...
Thanks!

To which sensors trigger is pin 13 connected? The one with the echo pin 12 or 11?

pin 13 is used to trigger both sensors at the same time.

@chrisl I changed the code like you said in your answer but it didn't work...

The updated code has been shown above.

I don't think this will work with HC-SR04 sensors. They are not just ultrasonic transducers. They incorporate extra electronics for the sole purpose of measuring the time difference between the sended and received signal. They just don't provide the needed control on the ultrasonic transducers. To change their function to suite you you will need to fully understand their circuitry (I surely don't). Or build your own support circuitry. Additionally you need to think about how to transmit the ultrasonic wave into the fluid. It isn't enough to just tag a standard transducer to the pipe. The small transducers on the HC-SR04 sensors are made for transmitting through air, so the actual transducer is hidden behind the grill inside the capsule. I thin you need to at least bring the transducer itswlf directly to the pipe, if not directly to the water. You will need to buy fizting ultrasonic transducers.
Also you have a problem due to the workings of pulseIn().
If you want to read a HIGH pulse it will wait for the pin to go LOW, then to go HIGH again, and then counting the time until it goes LOW again. This means it blocks from the moment it is called until the pulse is finished (or the 1s timeout hits).
I will assume that you trigger the sensor which has its echo pin on pin 12, though a similar problem arises when you trigger the other sensor.
With the HC-SR04 the HIGH pulse will start at a specific time after the trigger pulse. Lets assume the pulse starts at the same time on both sensors (despite the described problems above). Directly after the trigger pulse you call pulseIn() on the sending sensor. It will block until it receives the each. Since this needs about twice as long as the other sensor to receive the signal (signal needs to go to the second sensor and then back to its source) the end of the echo pulse from the receiving sensor will be inside this time, thus putting its echo pin low again. The sending snsor receives its echo, the pulseIn() function ends. Now you call pulseIn() on the receiving sensor. But its pulse already ended, so the function waits and waits for the pulse to start and finally reaches its timeout. In this case it returns zero.
You would need to check the pins in a non-blocking way. Maybe even an Input Capture Interrupt would be fitting (depending on the requirements on the resolution).

Thanks @chrisl . So should I update the code to check first sensor one and then trigger sensor two and check it?

And I also need to change the sensors used so that the transmitter diaphragm touches the pipe itself right?

Actually you don't want to trigger both sensors as they are. When they both only receive their respective echo they will have the same value (as in both cases the sound wave needs to go one time with the flow and the second time against it). You would need to split up each sensor so that the receiver of each sensor sits on the other side of the pipe than the sender. The  you can do these two measurements (one with thw flow, one against it)


text:
How do I create a code that lets me use an array of 10 thermistors on one arduino?
I am new to programming and am trying to create an array of 10 thermistors on one arduino. So far I have found a code for Temperature Sensor Using NTC Thermistor that is only for one thermistor. How do I fix this code for 10 thermistors?
Here is the link where I found the code.
https://thecustomizewindows.com/2020/10/temperature-sensor-using-ntc-thermistor-arduino-ntc/
The code below has been changed a little for the thermistor I am using.
Thank you.
#define RT0 10000   // Ω
#define B 3470      // K
#define VCC 5       //Supply voltage
#define R 10000     // R=10kΩ

float RT, VR, ln, TX, T0, VRT;

void setup() {
  Serial.begin(9600);
  T0 = 25 + 273.15;                 //Temperature, Celsius to Kelvin
}

void loop() {
  VRT = analogRead(A0);              //Acquisition analog value of VRT
  VRT = (5.00 / 1023.00) * VRT;      //Conversion to voltage
  VR = VCC - VRT;
  RT = VRT / (VR / R);               //Resistance of RT

  ln = log(RT / RT0);
  TX = (1 / ((ln / B) + (1 / T0))); //Temperature from NTC thermistor

  TX = TX - 273.15;                 //Conversion to Celsius

  Serial.print("Temperature:");
  Serial.print("\t");
  Serial.print(TX);
  Serial.print("C\t\t");
  Serial.print((TX * 1.8) + 32);    //Conversion to Fahrenheit
  Serial.println("F");
  delay(500);
}

the answer depends on how you intend to connect 10 thermistors to an arduino

You haven't said which (of the many kinds) of "Arduino" you plan to use, but Uno being the most common, I'll assume that. You also haven't said why/whether you must use a particular temperature sensor, but if you can be flexible about that, there will more choices of solution.
First, thermistors: You read a thermistors with an an A/D converter. Uno has an A/D converter but it has only 6 channels available - not enough for your spec of 10 sensors.

You could add an external A/D multiplexer with 5 channels fed into one of your on-board channels plus the remaining 5 on-board channels.
Or add a 10-channel multiplexer for all 10 sensors and feed it to one of the on-board A/D channels. This is better because it's simpler - all of the sensor signals will be processed identically, and all accessed the same way in the code.
Add an external 10-channel A/D. It will cost a little more but will be even easier to work with.

If you don't require thermistors, I'd suggest the Dallas/Maxim DS18b20 "1-wire" sensors. The "1-Wire" bus is a proprietary protocol developed by Dallas Semiconductor on which these sensors depend. You use one, simple, twisted-pair bus to access all of them, needing only 1 Arduino pin (and ground) to provide both power and communication to/from the sensors. Libraries are available to manage the bus and the communication. The 1-wire bus can be in a linear or a branched configuration, to suit your installation. You can use 2 wires (ground and power+data) or 3 wires (ground, power, data). Here's a link to the DS18b20 data sheet for the details.
Update:
I didn't really answer your question about coding for 10 thermistors (since you can't directly connect 10 thermistors to an Uno), I'll try to address that now without getting into any more detail about what kind of sensors you use or how you connect them.
You'll need to read 10 sensors, compute the sensor data to temperature and store it, and do whatever you plan to do with the temperature value. Your present code prints it (as both degC and degF, but let's just describe that part as printing the value).
You'll need a for( ) loop that executes 10 times, once for each sensor, where the loop index tells which sensor (0-9) you'll be processing. In time the loop executes, read a sensor, compute the temperature from what the sensor gives you, if it isn't already in the units you need, and print the value. So structuring that as if it were code (but I won't be writing it out in full C++) it would look like:
tell all 10 sensors to take a measurement; // if necessary
for( i = 0; i < 10; ++i ){
   read data from sensor[i];
   convert it to temperature;      // depends on the sensor
   print the temperature value;
}

If that is all you want to do, code this loop in your setup() function. Each time you reset the Arduino, it will measure and print all 10 temperatures and stop (actually, loop forever, doing nothing, until you power it down). If you want it to do this periodically, code this loop in your loop() function, with a delay(5000); statement after it. Now it will print the 10 temperatures every 5 seconds. You can change the 5000 (it's in milliseconds) to whatever period you want.
But it's the details that get you. You've got code to read and convert thermistors but your Arduino can't directly connect to 10 thermistors. If you use an external multiplexer, then you'll have to include code for that. If you use DS18b20 1-Wire sensors, you'll need to download and use the code library for those, as well as converting their 1/16-degC units to the units of your choice.
I'd recommend you start with 2 or 3 thermistors since you have the code for them, and write the loop for those. Once that's working, you'll have the answer to your title question. Then you'll have to decide how to connect 10 sensors of some kind, as I wrote about earlier. That will involve some additional coding, for an analog multiplexer, or for 1-Wire sensors, or whatever solution you choose. Just expand your experiment by small steps at a time and get each step working before you move on.

https://arduino.stackexchange.com/questions/14702/issue-with-cd74hc4067-mux-on-high-values has code for a 16-channel multiplexer attached to A0


text:
Selenoid motor not responding to NodeMCU instructions
I just start a project migrating from Arduino Uno to NodeMCU, basically this projects control some selenoid motors triggered by a website instructions. For example: if website returns 2, the motor #2 start work.
I hace everything ready, fetching from the website but, the motors are not working. In Arduino Uno works but in NodeMCU did not.
The selenoid motor is this one from AliExpress: the 3v --> https://es.aliexpress.com/item/4000807560712.html
The circuit I made is like this:
NodeMCU / Motor
D2 -> Positive motor wire (red wire).
3.3V -> Positive motor wire (red wire).
GND -> Negative motor wire (black wire).
All this is attached to a protoboard for easy my work, but those are the connections of the circuit.
At otherwise, the code looks something like this:
void setup() {
  Serial.begin(115200);
  pinMode(D2, OUTPUT);

}

void loop() {
  digitalWrite(D2, LOW);
  delay(3000);
  digitalWrite(D2, HIGH);
  delay(3000);

}

I also tried instead of pin name D2 use 4 corresponding of the GPIO number. Didn't work.
The wired part is in Arduino Uno the same code and same circuit works perfectly, but in NodeMCU not.

Do you mean you have connected 3.3V AND D2 to the positive motor wire? Don't you use any kind of motor driver?

@chrisl When I plug the 3.3V wire from NodeMCU to the motor, the motor react, but when the loop start and pass digitalWrite(D2, LOW) the motor still works. The same code/circuit on the Arduino Uno works, the motor go HIGH/LOW when the codes indicates. Thanks!

So basically you are shorting the output pin by setting it to LOW while it is directly connected to 3.3V?

So you connected 3.3V and pin D2 both to the positive motor wire. When the pin is high the motor runs and gets its current from the 3.3V pin. When you set the pin to LOW you essentially short the 3.3V pin to ground through the output hardware of the pin. That is highly risky. The output hardware of the pin only can withstand a certain amount of current (around 20mA, 40mA absolute max). Since you have nothing that would limit the current in this path you can easily fry the output hardware of the pin. Don't do that! The same is valid for driving a motor directly only from the digital output pin.
The correct way of controlling a motor with an Arduino or ESP is by using a fitting driver. For just turning it on and off a simple transistor or MOSFET is sufficient (depending on the current draw of the motor a MOSFET is better than a bipolar transistor). Google something like "MOSFET as switch" and you will get many tutorials on that. You can also add the term "Arduino" and you will get tutorials specifically for Arduinos.
Why it worked for the Uno but not for the NodeMCU? You didn't describe how exactly you connected it on the Uno (to the 3.3V pin or the 5V pin?). Probably the digital output pin on the NodeMCU cannot sink enough current so that it is not able to lower the voltage enough. Though if it would be able to do this it would also cause a power failure for the whole microcontroller. Maybe that also happened with your Uno difficult to say without more information.

Thanks @chrisl!


text:
Do you actually NEED external resistors for switch connecting IO pin to ground?
Years ago, I encountered a fairly long debate at AVRfreaks.net about whether or not it's OK to directly connect AVR pins that are configured as inputs with internal pullup enabled directly to ground through a button or switch.
From what I recall, the consensus at the time was that it's not (at least, for switches likely to be closed and conducting at reset), because at least some AVR MCUs weren't absolutely guaranteed to have their pins in high-impedance state at reset (at least, not if the chip reset while in brownout state, or something like that).
Thinking back, I'm not sure whether the warnings even applied to the chips I was introduced to at the time (ATtiny2313, ATtiny13, and ATmega162)... I just remember that the others on the site were pretty adamant that I was courting disaster, and I took their word for it.
Fast forward ~15 years.
The current datasheet for the ATmega2560 (at https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega640-1280-1281-2560-2561-Datasheet-DS40002211A.pdf ) does seem to guarantee (on pages 7-9) that the pins used by ports A through L are tri-state high-impedance input pins at reset under all conditions, including when the clock is halted (obviously, any pin Arduino's bootloader subsequently makes use of could behave differently if I tried to hijack it for double-duty reading a button/switch... but the Mega2560 has so many pins, there really isn't any reason to reuse pins Arduino uses for its own purposes).
Offhand, I can think of three potential remaining concerns:

If I screw up and accidentally execute code that configures a pin connected directly to ground through a closed switch as a high output, the pin (and probably the whole chip) is likely to go up in smoke. I can deal with this risk.

If I were powering it with batteries, I might care about the constant power drain wasting battery life. I'm not, and I don't.

I'm not quite sure whether "OK to connect directly to ground through a momentary pushbutton" necessarily equates to "OK to connect directly to ground through a switch that might conceivably be closed and continuously conducting current for the life of the circuit.

So... have I missed anything? And is #3 a legitimate concern, or is it something that's not worth caring about if you're talking about something like 8 pins connected through a DIP switch?
Illustrative circuit:
Ground <-- [switch] --> IO pin (configured for input, internal pullup enabled)

The internal pullup is like 50k. Not much of a current there to be concerned about

I think your analysis is correct.

If I screw up and accidentally execute code that configures a pin connected directly to ground through a closed switch as a high output, the pin (and probably the whole chip) is likely to go up in smoke. I can deal with this risk.

In addition to “there is an obvious bug”, there could also be a bug that is only triggered in very rare conditions, or a “cosmic ray” event which causes the processor to mis-execute instructions.
Or, maybe a metal tool or piece of debris fell across two of the processor pins and the other pin is an output that's currently high. (This is impossible to protect against in all cases, of course.)
In any of these cases, the hazard is that you're turning a situation where the device misbehaves temporarily into a situation where the device is permanently damaged.
Will this happen? Likely not. Is it worth protecting against? Depends on your application, on hard-to-quantify risk probabilities, and how much of a bother it would be to replace the processor.

The main problem is, I'm stuck working with an Arduino Mega2560 protoshield board that only has a sea of isolated ringed pads. If it were breadboard-like, with 2 or more adjacent pads connected (so I could just solder the DIP switch along the boundary between two sets of pads, then solder the resistors into the next pads over), I wouldn't have even bothered to contemplate the need for the resistors. But in this case, soldering even AWG30 WIRES to the DIP switch contacts was a major pain, and resistors would have had me in tears.

It is usually better to use a resistor when connecting to either +5V or ground. This protects the uP against software bugs, particularly during a hectic debug effort. Even moving on to the next project while forgetting the existing wiring can be a source of trouble.


text:
Proteus potentiometer value always highest

#include <Servo.h>

#define potpin A0
int savebutton=2;
int button1=3;
int button2=4;
int button3=5;

Servo servo1;
Servo servo2;
Servo servo3;

int servo1ipos=90;
int servo2ipos=90;
int servo3ipos=90;

int val=0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(savebutton,INPUT);
  pinMode(button1,INPUT);
  pinMode(button2,INPUT);
  pinMode(button3,INPUT);

  servo1.attach(6);
  servo2.attach(7);
  servo3.attach(8);
  servo1.write(servo1ipos);
  servo2.write(servo2ipos);
  servo3.write(servo3ipos);

}

void loop() {
  // put your main code here, to run repeatedly:
  servocontrol();

}

int servocontrol(){
  if(digitalRead(button1)==LOW){
    potvalue();
    Serial.println(val);
    servo1.write(val);
    delay(200);
  }
}
int potvalue(){
    val=analogRead(potpin);
}

Basicly I only read 1023 value instead of potentiometer value I couldnt figure it out need help.
Update:
I came up solution by connecting 5V into Arduino's VCC pin.

I don't know Proteus - does it automagically connect the VCC and GND pins of the Uno to sensible nets?

@Mat yes also you can see from voltmeter I can change voltage with potentiometer.

@Mat I dont  know you mentioned about VCC on arduino but yeah I solve the problem with connecting 5V into Arduino's VCC pin. Thanks.

Please take the [tour] to learn how this site works. Especially, please don't mark a question with "[SOLVED]", this is not a forum. Instead, write an own answer and mark, after you are allowed to do it. Visitors select answered question after the number of answers and the green mark, not by the title.

Oh, you put your solution as the comment on your edit--that makes it very difficult to see. You should write up your work as an answer, and give yourself a green checkmark for solving your own problem.  Or at the very least, copy your edit summary message into your question.

@DaveX I added on my post thanks for information.

I came up solution by connecting 5V into Arduino's VCC pin.


text:
"Simple" code...but what have I done wrong?
This code  compiles without problem, but doesn't work at all... The switch does not set the LED low and the while loop doesn't work, plus the serial print doesn't print....
Until I put the while loop in pressing either button would change the LED state. I wanted to make the sequence "button one, LED change, THEN button two"
I'm certain to have missed something...
const int buttonPin1 = 2;     // the number of the pushbutton 1 pin 2
const int buttonPin2 = 7;     // the number of the pushbutton 2 pin 7
const int ledPin = 13;      // the number of the LED pin

// variables will change:
int buttonState1 = 0;         // variable for reading the pushbutton status
int buttonState2 = 0;
int i = 0;

void setup() {
// initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin 1 as an input:
  pinMode(buttonPin1, INPUT);
// initialize the pushbutton pin 2 as an input:
  pinMode(buttonPin2, INPUT);
  Serial.begin(9600);
}

void loop() {

  digitalWrite(ledPin, HIGH);

// read the state of the pushbutton value:
  buttonState1 = digitalRead(buttonPin1);

// check whether a  pushbutton is pressed.
// if it is, the buttonState is HIGH:

  if (buttonState1 == HIGH) {
// turn LED off:   //
    digitalWrite(ledPin, LOW);
    while (1) {
      (buttonState1 == LOW);
      if (buttonState1 == LOW) {
        Serial.println("1");
      }
      {
        break;
      }
    }

    delay[1000];

    digitalWrite(ledPin, HIGH);

// read the state of the pushbutton 2 value:
    buttonState2 = digitalRead(buttonPin2);
    if (buttonState2 == HIGH) {
// turn LED off:
      while (1) {
        if (buttonState2 == LOW) {
          break;
        }
      }
      digitalWrite(ledPin, LOW);

      delay(10000);
      digitalWrite(ledPin, HIGH);

    }
  }
}

Your code is only reading the real state of buttonPin1 once, and copies the value as it is at that moment to the variable buttonState1, which will no longer change or reflect the real button status after that (the value of buttonState1 will not automagically change when you push or release button 1). If you want to continue to check the current button status, you have to continuously read the I/O port, by using digitalRead() statements where appropriate. The same goes for buttonPin2.

I guess as the function "name" is basically pointer, it really is possible to write delay[1000]; :D Luckily it wasn't called, so it doesn't do anything :D

@KIIV, I didn’t spot that one, good catch!

I think there’s a misunderstanding of how variables work.
Your code is only reading the real state of buttonPin1 once (before the first if () statement) and copies the value read from the I/O port as it is at that moment to the variable buttonState1, by executing buttonState1 = digitalRead(buttonPin1);.
After you’ve copied the value read from the buttonPin1 port to the buttonState1 variable, this variable will no longer change or reflect the actual button status. I.e. the value of the variable buttonState1 will not automagically change when you push or release button 1. buttonState1 is a normal program variable and not coupled to the I/O port.
If you want to continue to check the current button status, you have to continuously read the I/O port, by using digitalRead() statements where appropriate.
The same goes for buttonPin2 and buttonState2.


text:
get data from arduino using python
I am trying to read potential meter data from Arduino using python, with the program on Arduino as follows :
#include <cvzone.h>

SerialData serialData;
int sendVals[2];

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

void loop() {
  int potVal = analogRead(A0);
  sendVals[0]= potVal;
  serialData.Send(sendVals);
}

the program on the arduino side is running fine
and program in python as follows
from cvzone.SerialModule import SerialObject

arduino = SerialObject("COM7")

while True:
   data = arduino.getData()
   print(data[0])

but I get this error:
Traceback (most recent call last):
    data = arduino.getData()
  File "C:...\site-packages\cvzone\SerialModule.py", line 68, in getData
    data = data.decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf7 in position 0: invalid start byte

How to solve it?

the new USB connection resets the Mega and it spends some time in bootloader waiting for upload.

Maybe add some delay on the Arduino after initializing the serialData in startup()  before it starts sending data in the loop().

I would embed the call to .getData() into a try block and handle this specific exception with except UnicodeDecodeError. There can always be a transmission error, especially when the script is started.
However, I would do it differently:
void loop() {
  Serial.println(analogRead(A0));
}

...and on the python side use serial.readline() from pyserial instead.
But I don't know cvzone and you might have a reason to use this instead of the commonly used pyserial.

thank you very much, this really helped me :)

There seems that there may be an issue with the implementation of getData() in SerialModule.py.
From line 62
    def getData(self):
        """
        :param numOfVals: number of vals to retrieve
        :return: list of data received
        """
        data = self.ser.readline()
        data = data.decode("utf-8")
        data = data.split('#')
        dataList = []
        [dataList.append(d) for d in data]
        return dataList[:-1]

The block of code containing the readLine() should probably be with in a try...except block, like so:
    def getData(self):
        """
        :param numOfVals: number of vals to retrieve
        :return: list of data received
        """
        try:
            data = self.ser.readline()
            data = data.decode("utf-8")
            data = data.split('#')
            dataList = []
            [dataList.append(d) for d in data]
            return dataList[:-1]
        except Exception as e:
            print(e)
            self.ser.close

An issue has been raised on Github: SerialModule.py - readLine() should be within try block. #49


text:
I have been having a lot of trouble adding a countdown to a piece of code
This is the code. The /// are where I added the countdown. Unfortunately the countdown only goes down 9 seconds. What I want it to do is go down the full 24 hours. I have been trying to fix this error for months with no luck.
int beeper_pin      = 2; //Naming buzzer pin
int resetGarden_pin = 3; //Naming the warning led pin
int pump_pin        = 6; //Naming the pump pin

#include <LiquidCrystal_I2C.h> // Driver Library for the LCD Module

LiquidCrystal_I2C lcd(0x27, A4, A5);

void clearLCDLine(int line)
{
  lcd.setCursor(0, line);
  for (int n = 0; n < 20; n++) // 20 indicates symbols in line. For 2x16 LCD write - 16
  {
    lcd.print(" ");
  }
}

void beepWarning() {            //Makes beeping a subroutine

  lcd.setCursor(0, 0);
  lcd.print("WARNING");
  delay(100);
  lcd.setCursor(0, 1);
  for (int x = 0; x < 3; x++) {

    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE.");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE..");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE...");
    delay(100);
    clearLCDLine(1);
  }

  lcd.setCursor(0, 1);
  lcd.print("WATER PUMP ACTIVE...");

  for (int x = 0; x < 3; x++) {   //Repeats 3 times

    digitalWrite(beeper_pin, HIGH); //Turn on buzzer
    delay(100);                     //Delay of 400 milliseconds
    digitalWrite(beeper_pin, LOW);  //Turns off buzzer
    delay(100);                     //Delay of 400 milliseconds

  }
}

void SOSWarning() {            //Makes SOS a subroutine

  clearLCDLine(1);
  lcd.setCursor(0, 0);
  lcd.print("WPA Reset Aerogarden");

  for (int x = 0; x < 3; x++) {   //Repeats 3 times

    for (int d = 0; d < 3; d++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(200);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(200);                     //Delay of 400 milliseconds
    }

    for (int a = 0; a < 3; a++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(400);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(400);                     //Delay of 400 milliseconds
    }

    for (int d = 0; d < 3; d++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(200);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(200);                     //Delay of 400 milliseconds
    }

    delay(500);                     //Delay of 500 milliseconds
  }
}

void weekDelay() { //Makes waiting for a week a subroutine
  clearLCDLine(1);
  lcd.setCursor(0, 0);
  lcd.print("Waiting One Week");

long hour = 23, minute = 59, second = 59;//second //////////////////////////
long countdown_time = (hour * 3600) + (minute * 60) + second; ///////////////////////////////////////////////////////////////////////////

  long countdowntime_seconds = countdown_time - (millis() / 1000); /////////

  if (countdowntime_seconds >= 0) {   ///////////////////////////////////////////////
    long countdown_hour = countdowntime_seconds / 3600;
    long countdown_minute = ((countdowntime_seconds / 60) % 60);
    long countdown_sec = countdowntime_seconds % 60;
    lcd.setCursor(4, 1);
    if (countdown_hour < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_hour);
    lcd.print(":");
    if (countdown_minute < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_minute);
    lcd.print(":");
    if (countdown_sec < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_sec);
  }
  delay(500);///////////////////////////////////////////////////////////////

  delay(500);

  delay(86400000);
  clearLCDLine(0);
  lcd.setCursor(0, 0);
  lcd.print("Waiting Six Days");
  delay(86400000);
  clearLCDLine(0);
  lcd.setCursor(0, 0);
  lcd.print("Waiting Five Days");
}

void pumpOn() {               //Makes turning on the pump a subroutine
  clearLCDLine(1);
  lcd.setCursor(0, 1);
  lcd.print("PUMPING");
  delay(100);
  digitalWrite(pump_pin, HIGH); //Turning on the pump
}

void pumpOff() {              //Makes turning off the pump a subroutine
  digitalWrite(pump_pin, LOW);  //Turning off the pump
  clearLCDLine(1);
  lcd.setCursor(0, 1);
  lcd.print("WATER PUMP OFF");
  delay(100);
}

void setup() {
  //run once:
  lcd.backlight();
  lcd.init();

  lcd.setCursor(4, 0);//////////////////////////////////////////////////////
  lcd.print("HH:MM:SS"); //////////////////////////////////////////////////

  lcd.clear(); // Clear the screen
  lcd.setCursor(0, 0);
  lcd.print("Aero_Pump V3");
  delay(1000);
  lcd.setCursor(0, 1);
  lcd.print("By Alex");
  delay(1000);
  pinMode (beeper_pin,      OUTPUT); //Setting outputs
  pinMode (resetGarden_pin, OUTPUT); //Setting outputs
  pinMode (pump_pin,       OUTPUT); //Setting outputs
  lcd.clear(); // Clear the screen

  digitalWrite(resetGarden_pin, LOW); //Turning off the reset garden light

  beepWarning(); //Beeps a warning
  pumpOn();      //Turns on the pump
  delay(3000);  //Adds a delay of 24000 milliseconds
  pumpOff();     //Turns off the pump
  weekDelay();   //Waits a week

  beepWarning(); //Beeps a warning
  pumpOn();      //Turns on the pump
  delay(135000);  //Adds a delay of 48000 milliseconds
  pumpOff();     //Turns off the pump
  weekDelay();   //Waits a week
}

void loop() {

  SOSWarning(); //Beeps an SOS warning
  pumpOn();      //Turns on the pump
  delay(48000);  //Adds a delay of 48000 milliseconds
  pumpOff();     //Turns off the pump

  for (int x = 0; x < 3024000; x++) {
    lcd.backlight(); // turn on backlight.
    delay(100);
    lcd.noBacklight(); // turn off backlight
    delay(100);
  }
  lcd.backlight(); // turn on backlight.
}

This is more specifically what needs to be fixed:
long hour = 23, minute = 59, second = 49;//second //////////////////////////
long countdown_time = (hour * 3600) + (minute * 60) + second; ///////////////////////////////////////////////////////////////////////////

  long countdowntime_seconds = countdown_time - (millis() / 1000); /////////

  if (countdowntime_seconds >= 0) {
    long countdown_hour = countdowntime_seconds / 3600;
    long countdown_minute = ((countdowntime_seconds / 60) % 60);
    long countdown_sec = countdowntime_seconds % 60;
    lcd.setCursor(4, 1);
    if (countdown_hour < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_hour);
    lcd.print(":");
    if (countdown_minute < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_minute);
    lcd.print(":");
    if (countdown_sec < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_sec);
  }

This is some edited code that I have tried but might have made a mistake on because it does 0 days instead of 7 and (Hours/Min/Sec) 04:09:36.
void weekDelay() { //Makes waiting for a week a subroutine
  clearLCDLine(1);
  clearLCDLine(0);
  lcd.setCursor(0, 0);
  lcd.print("Waiting One Week");

  unsigned long start = millis();
  unsigned long week_secs = 7 * 24 * 3600;
  unsigned long countdowntime_seconds;

  while (countdowntime_seconds = week_secs - (millis() - start)/1000){
     char buff[80];
     unsigned long countdown_day = countdowntime_seconds / 3600 / 24;
     int countdown_hour = (countdowntime_seconds / 3600) % 24;
     int countdown_minute = ((countdowntime_seconds / 60) % 60);
     int countdown_sec = countdowntime_seconds % 60;
     sprintf(buff,"%1d days, %02d:%02d:%02d",
            (int) countdown_day,
            countdown_hour,
            countdown_minute,
            countdown_sec
            );
     Serial.print(buff);
     clearLCDLine(1);
     lcd.setCursor(2, 1);
     lcd.print(buff);
     delay(1000);
     }
}

You sure have a lot of delay()s in your code. Here's a simple millis based count down timer if you are interested. https://arduino.stackexchange.com/a/82217/37523

It seems like the countdown is just skipped for some reason.

I would be happy to help you. Before writing any code, it's better to write the user manual first. Can you give me a description of your project, what it does, when it does it, etc.?

Your code is in the middle of the weekDelay() function, which looks like it has several problems.  What do you expect weekDelay() to do?

The project is for an Aerogarden. It pumps water into the garden every week from information based on my collected data. It writes on the LCD information like if it is pumping, waiting (it should have the timer here), and it can show when it is going to pump with a beep warning. After beeping, pumping, and waiting for a few times I run out of information and do a loop and show a warning message, blinking the LCD and pumping a set amount.

WeekDelay() should be a delay for a week. It clears the LCD, Sets the cursor to 0,0 and prints "Waiting one week". It should then have a countdown of 24 hours on the screen and then just how many days it is waiting. It does that through clearing the LCD, Setting the cursor, printing days and waiting.

Is it supposed to wait a week? As is, weekDelay looks like it only does two day-long   delay(86400000); pauses.  You could replace lots of its code with char buff[80]; sprintf(buff,"%02d:%02d:%02d",countdowntime_hour,countdowntime_minute,countdowntime_secs); lcd.print(buff);
It also doesn't seem to have any countdown logic--From this code I see no loops in weekDelay() that could count down even 9 seconds, let alone the 604800 seconds in a week.

The answer is very good and seems to work. I do have a question though. How would I make it count down? Sorry for the extra time this will take you. I will give you the checkmark anyways for all the work you did.

I rolled back your edit because it changed the question too much.

I'd try something with a while(){} loop and a sprintf(), like:
void weekDelay() { //Makes waiting for a week a subroutine
  unsigned long start = millis();
  unsigned long week_secs = 7 * 24 * 3600;
  unsigned long countdowntime_seconds;

  while (countdowntime_seconds = week_secs - (millis() - start)/1000){
     char buff[80];
     unsigned long countdown_day = countdowntime_seconds / 3600 / 24;
     // or maybe
     //int  countdown_day = (int)(countdowntime_seconds / 3600UL / 24UL);

     int countdown_hour = (countdowntime_seconds / 3600) % 24;
     int countdown_minute = ((countdowntime_seconds / 60) % 60);
     int countdown_sec = countdowntime_seconds % 60;
     sprintf(buff,"%1d days, %02d:%02d:%02d",
            (int) countdown_day,
            countdown_hour,
            countdown_minute,
            countdown_sec
            );
     clearLCDLine(1);
     lcd.setCursor(0, 0);
     lcd.print(buff);
     delay(1000);
     }
}

Or make it more general and start it off like:
void coundownDelay(unsigned long seconds) { //Makes waiting for a week a subroutine
  unsigned long start = millis();
  unsigned long countdowntime_seconds;

  while (countdowntime_seconds = seconds - (millis() - start)/1000){

     ...

}

and call like:
  ...
  countdownDelay(7 * 24 * 3600);   //Waits a week
  ...

It is incredibly close and I thank you a lot for your contribution.

Sorry -- I had the sense of direction wrong.   I edited the math.  For debugging, you might want to try smaller delays so you can see if and where things go wrong in less than 9 hours.

Ah, it is the integer math interacting with the size of days.  04:09:36 = 43600+960+36 = 14976  which happens to be equal to  7243600 % 32768.     See https://www.gammon.com.au/forum/?id=12146 and https://wiki.sei.cmu.edu/confluence/display/c/INT35-C.+Use+correct+integer+precisions  for what's happening.   I added some casting and types to the day= line.  Alternately, one could define days as unsigned long days and then print it with sprintf(buff,"%1d days, %02lu:%02d:%02d",

I changed my code to int countdown_day =  countdowntime_seconds / 3600 / 24;   to have two divides instead of a multiply and divide.  I don't have an arduino available, so it is still untested there.  In C, the several versions worked.

That particular number, 04:09:36 is special, it is 14976 seconds, which is what a week work of seconds (7243600=604800) forced into a signed int that can only hold numbers in −32768, +32767.  This indicating problems doing the math with 16 bit ints.  Right now I can only test code bits with gcc on a Mac, where default math is done with 32 bit ints.  I added two options to the code, one doing the math with unsigned longs all the way through (and casting it to an int for the sprintf) an another attempting to keep the math in ULs and casting it into an int for storage.

I edited the code at the bottom. This had the same issue unfortunately. I firstly tried to just use the 24UL code and it said that the "countdown day" was not defined. It fixed the issue when I added both pieces of code but that might not have been what you meant when you made the code. Do you want me to define days? Also, I will check the code on a C emulator.

What emulator do you use? And what was the code you were using for it?


text:
Arduino Nano: Send a few bytes over Serial with as little delay as possible
My scenario is the following:
I have a few buttons connected to an Arduino Nano, which is connected to my PC over Serial. Now I want to send a few bytes whenever a button is pressed, to be interpreted by my Computer. However, I noticed a significant, unregular delay (feels like something between almost instantaneous transmission up to a delay of easily ~300 milliseconds), until the message is received by my computer, and I want to get rid of that.
I understand that Arduinos make use of a Serial Buffer, and only send over data once the buffer is full (or some sort of timeout probably), and I think that is the culprit - however I don't see a way of forcing the Arduino to send the data ASAP. I tried just sending over exactly 64 bytes (which, according to what I read, should be the buffer size), but that doesn't help as well (can I however decrease the buffer size or is there a way to send bytes exactly until the buffer is full?)
I don't think baudrate changes anything either, as I'm experiencing problems with the "ping" rather than with the bandwidth (and I also tried anything from 9600 to 115200).
Maybe I'm also completely wrong and the delay happens on the side of my computer, but I don't know if there is anything to change that - I'm looking at the Serial Monitor or at a small pyserial script, both of which have the delay:
arduino = serial.Serial(serial_port}, 115200, timeout=.1)
while True:
    data = arduino.readline().decode("UTF-8").strip()
    if data:
        print(data)

The code on the Arduino-side boils down to:
#include <digitalWriteFast.h>

#define button1_pin 2

int button1_state = 0;
int last_button1_state = 0;

void setup() {
  Serial.begin(115200);
  pinMode(button1_pin, INPUT_PULLUP);
  while (!Serial) { delay(50); }
  Serial.println("Started");
}

void loop() {
  button1_state = digitalReadFast(button1_pin);

  if (button1_state != last_button1_state) {
    if (button1_state == LOW) {
      Serial.write("d\n");
    } else {
      Serial.write("u\n");
    }
    last_button1_state = button1_state;
    delay(20);
  }
}

Then there's also the weirdest thing which I noticed but am not sure about if it's at all plausible:
When the window of the Serial Monitor (the one that ships with the Arduino IDE) is not completely full (meaning there are only some 1-20 rows and the window doesn't need to scroll), I notice the aforementioned delay, but if the Serial Monitor is full (so new content will be on the last line and the window automatically scrolls a bit), I don't. As soon as I clear the output of the window, it's there again. I don't know what to make of this observation, because I definitely don't have any reasonable clue why that may be the case, so maybe it's also just my imagination :shrug:. Using the python-code there is no such behaviour, and the transimission always seems to have a ping of at least 200-300ms.
I hope my problem is understandable, and like I said I am really unsure what even is the culprit (and I see that it's also highly likely that it's on the side of my computer), but does anybody have any idea how I can decrease this delay? Thanks a lot!

"only send over data once the buffer is full" - You are thinking wrong here. As soon as any byte is in the send buffer (put there by Serial.write() or its siblings) the transmission begins in the background (orchestrated through interrupts). The baudrate also defines how long the transmission of a byte needs, so it also correlates to the "ping" in a way. Have you tried changing the timeout value in the python code? At the moment you have 0.1 (I guess this is seconds). Does this change anything in the outcome?

Ohh, that's good to know, thanks! But that only confuses me more tbh ^^ And no, changing the timeout doesn't change anything. Because of @hcheung 's answer I tried other timeout-values, but as mentioned, the timeout is only maximal time one call of readline() waits until it returns, and neither increasing nor decreasing changes something.
Note however that I see the same issues in the Arduino IDE's Serial Monitor, so I don't think this problem is on the side of pyserial.

My question is resolved, thanks for your contribution :)

"Slowing down to speed up". -   a Chinese proverb

The problem is with your python code. Not sure what your computer's operating system is, but if you are using Mac or Linux, if you run top on command line, you will see you have a high CPU utilization causing by your python script. This is because your your python while True loop constantly looping without giving the chances for other processes on your computer to use the CPU, bear in mind that Linux, MacOS or Windows are not designed as a real-time operating system.
So how to solve the problem? put your while True loop to sleep for a short period of time, this allows other processes on your computer to have chance to run and you will see the CPU utilization go down significantly and everything will running smoothly.
import time
arduino = serial.Serial(serial_port}, 115200, timeout=.1)
while True:
    data = arduino.readline().decode("UTF-8").strip()
    if data:
        print(data)
    time.sleep(0.01)

With this slight delay, I've seen some CPU utilisation drop from 90% to 3.5%. This is quite a common mistake that many python programmers made, including some quite experienced programmers who are not familiar with network programming.
Try it out and let me know.

Interesting suggestion! First of all, I'm using Linux.
Second, I know the difference between active and passive waiting, but I as far as I understand, when I have a Serial connection with a timeout, is passive waiting - as far as I understand pyserial's documentation @ https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial , readline() returns either if it receives something, or it times out (0.1secs in my case) - which means the time.sleep(0.01) is superflous, as it already waits 0.1 seconds per iteration. I also only have maximally 1% CPU utilization by this script.

Also, I see the same issues on the Arduino IDE's Serial Monitor, which made me think the problem is on the Arduino side in the first place

Haha now to the big BUT:
Because I didn't trust what I saw in the serial Monitor/python's print I also wrote another test script which reacts to the click by sending a serial message back to the Arduino triggering an LED, and as far as I could judge, this LED had the same delay as the prints... however in the thread that reacts to the button-click, my code was while True: if not led_queue.empty(): serial.write(led_queue.get()), which is very ACTIVELY waiting, and as soon as I added a time.sleep(0.1) in THAT method, the LED reacted instantaneously!!! So you're right after all!

Timeout is different, it is for breaking out from constant polling Serial. Arduino is an MCU which is architecturally different from CPU, and  is designed for running a super loop without much of the background processes running like Linux.

But fact is, when I set the timeout of the Serial connection to, say, two seconds, and add a print in the loop body (not conditional on if there is data or not) the print is only executed every two seconds (or whenever there is data sent from the Arduino) - so the timeout acts the same way an added time.sleep would do

Answering my own question in case anybody experiences the same problem eventually: @hcheung's answer was almost correct after all - see the comments to that question.
Important take-away however:
don't trust the Serial Monitor or Python's print to check how quickly the arduino and your computer communicate!
When ponging back to the Arduino to let it trigger an LED, I noticed that the actual transmission is definitely faster than my eye, far from the 200ms delay I mentioned in the question.
So the problems for me were
a) the other code I used to test the connection but didn't post here was faulty
b) The delay I saw in the Serial Monitor/python's print is not the delay of the serial communication but apparently somewhere later in the printing of the respective content.
Serial communication is definitely faster than the human eye :)

TL;DR: Any time there is an OS, windowing system, etc. involved that isn’t explicitly hard real-time, results are non-deterministic by definition.


text:
My arduino gives me several avrdude erros
For school we program an arduino with visual studio and micro visio. Since a few days ago my arduino wont run the code of the arduino. At first it didnt give any errors until i tried to upload a code with arduino ide itself.
avrdude: ser_open(): can't set com-state for "\.\COM3"
Or saying that the acces is denied. I confirmed that my arduino is the COM3 port. The weird part is that on another pc it works fine. On the laptop where my arduino isnt working i did a loopback test following. https://support.arduino.cc/hc/en-us/articles/360020366520.
This went without a problem. I reinstalled the IDE and drivers but sadly this didnt help either. If i try a class mates his arduino it wont work either. If some one has information on how to fix this problem that would be nice. If there is some extra information needed that wont be a problem either.

The COM port can only be used by one program at a time. Typically, the above error happens if either program (Visual Studio or the Arduino IDE) have the serial console open and you try to program the Arduino using the other.

Thanks for the tip. I will admit at first i didn't do this but after a few times i did close the other and i still got the same problems.

If you connect and disconnect your Uno, the COM3 shows up and disappears, respectively? Also, when you are using Arduino IDE, the visual studio is not running? Check this link if you want to find out if some other process is using your COM port.


text:
Arduino websockets send id in connection
I am creating home automation using esp's and little home server. Idea is to connect arduinos to server, add each of them id and let them talk via websockets with server and server will forward (by some logic inside) messages to different arduinos. Pretty simple.
What I found, is that I cannot tell, what websocket client I am talking to. I use simple example from lib: https://github.com/gilmaimon/ArduinoWebsockets
client.onMessage(onMessageCallback);
client.onEvent(onEventsCallback);
client.connect(websockets_server_host, websockets_server_port, "/");
client.ping();

My idea is to send id of arduino with connection handshake. Is it even possible?

This is a websocket client code. The client is not talking to other clients, but the server. He doesn't need to differentiate clients.

Exactly. Server will forward messages from one client to antoher. Problem is, that on server side I have multiple clients, that I cannot distinguish so I need each client to identify itself when it connect

You can even add your device id with every message you send to the server.

I like to pass a an identifying GET param in the websocket URL (eg. system_get_chip_id()), then the PC-based server socket lib has a (sometimes roundabout) way of getting the request URL to id who's asking.


text:
increment or decrement the values of an array
I wanted to simulate the Dawn light with my arduino Uno using array implementation.
I desired to change the brightness of the LEDs using fade effect( Smoothly and keep it unchanged until the next function called out) from 0 brightness to specific values in array ( it means specific brightness for each LED).
I wrote my code and compiled it but unfortunately nothing happens when I upload it to my device.
The device is already connected and I have tested some other on/off led codes.
Here is my pre-code:
//Dawn Light Simulation
int LEDArray[] = {3, 5, 6, 9, 10, 11};
int LedNum = 6;
int i;
int j;

int Dawn[] = {30, 20, 20, 20, 100, 0};

int Current[] = {0, 0, 0, 0, 0, 0};
unsigned long time_for_fadestep;
#define Fade_Interval 1200;

void setup() {

  for (int i = 0; i < LedNum; i++)
    pinMode(LEDArray[i], OUTPUT);

}

void DawnMode()
{
  if (millis() > time_for_fadestep) {
    time_for_fadestep = millis() + Fade_Interval;
    for (int j = 0; j < LedNum; j++){
        if (Dawn[j] > Current[j]) Current[j++];
        if (Dawn[j] < Current[j]) Current[j--];
          analogWrite(LEDArray[j], Current[j]);

    }
  }
}
void loop() {
  DawnMode();
  delay(5000);
}

I think you actually meant Current[j]++ not Current[j++], and the same with the Current[j--]

Also you should watch your method of delaying - you will fall afoul of the millis() integer wrap around problem. Instead you should be working with a past timestamp and a delay length (if (millis() - last > delaytime)) to combat it.

Hey Majenko,
Regarding of  ''Current[j++]'', I have made so many changes and got nothing in return,
relaed to your explanation about milis() , could you please explain more.....

Dear @Majenko ,here is a topic for my source to use milis() ,
link

time_for_fadestep was never initialized!

Also you are using 5s delay but your Fade_Interval is 1.2second. Your first led will take 5*30=180s to get to the 30% brightness. Get rid of that delay.

@HadiMirdamadi That source is not good. You should use the official BlinkWithoutDelay example to base your time code on.

@HadiMirdamadi The second code with micros() has been done right. I don't know why he did the first one wrong.

@Fahad Actually, that's not true. time_for_fadestep is in the global scope, thus it gets placed in the BSS. The BSS is cleared during startup, so time_for_fadestep will always be initialized to 0. It's good for readability to be explicit though and assign it manually.

Hey Guys, The code has been executed fine, I made some updates with milis() and also could do the smooth transition between the array's values.... tnx for your comments


text:
avrdude: ser_open(): can't set com-state for "\\.\COM4"
My Arduino code is not getting uploaded. It gives me "avrdude: ser_open(): can't set com-state for "\.\COM4" error. It worked literally 5 mins ago. now it doesn't work. I updated the drivers and stuff. I have a new Arduino and my code worked 5 mins ago. when i made some changes to the code It stopped working. I am using an (unofficial) Arduino Uno R3. the USB to UART chip's name is ATMEL Mega 16U2 2048 TW which I'm pretty sure is the Arduino mega chip?? my Arduino uses the ATMEL ATMEGA328P U. Please help
Thanks in advance, Paradox

maybe you installed the wrong driver ... what is and stuff?

Is another program open which uses the COM port? Did you try to reboot?


text:
POST ESP32 image buffer using HTTPClient to Node.JS API
I'm trying to post the buffer generated by the ESP32 camera to my personal API service I have built with Node.JS. The post gets sent successfully. I have yet to test it on large image (higher resolution).
I'm using a FRAMESIZE_HQVGA,    // 240x176 for my images
void postImage(uint8_t* buf, size_t len)
{
  // prepare JSON document
  DynamicJsonDocument doc(len);
  doc["buffer"] = buf;

  HTTPClient http;

  // Serialize JSON document
  String json;
  serializeJson(doc, json);

  http.begin("http://192.168.0.147:3001/api/pictures");
  http.addHeader("Content-Type", "application/json");

  int httpResponseCode = http.POST(json);

  if (httpResponseCode > 0) {
    // response
    String response = http.getString();
    Serial.println(httpResponseCode);
    Serial.println(response);
  } else {
    Serial.print("Error sending POST: ");
    Serial.println(httpResponseCode);
  }

  // disconnect
  http.end();
}

In my Node.JSside, I receive the buffer but I'm unable to de serialize it to an image. This i smy body:
{ buffer: '����' }

I'm wondering what I'm doing wrong here. Should the image buffer be sent in base64, and if so, how? I want to be able to transform the image buffer into a proper image on the API side.
Here's my how I try to transform the image buffer to a proper image (in my API controller):
    const imageBuffer = Buffer.from(req.body.buffer);
    const filename = `./resources/pictures/image_${Date.now()}.jpg`;

    fs.writeFile(filename, imageBuffer,function(err) {
        if (err) {
            console.log(err);
        } else {
            console.log(`Writing ${filename}`);
        }
    });

is there a specific reason to use JSON?

@Juraj No specific reason. Am I better off without it?

for JSON you would have to encode it as text (base64 is common). but you can upload it as any other classic file upload in the history of the www

JSON is a poor choice for large binary blobs. You would be better off just sending the raw buffer, with appropriate Content-Type (application/octet-stream if no other type is suitable) and Content-Length (the len parameter of postImage()).

@EdgarBonet Tried what you said. The body is empty when I receive the request in the API :/

@Johnnyboy: In that case you should debug the problem. Is the body sent? Did you look at it with a packet sniffer? Is the Node.js server discarding that body?

I'm currently looking at it with a packet sniffer, thank you for the idea! The request does get sent (I console log the request when i receive it, but the body is empty). So it's safe to say the api does see the request

@EdgarBonet Just to confirm. In wireshark, I do see the buffer in the body. For some reason the express API only accepts JSON

@EdgarBonet It works now. Thank you very much for the help! Really appreciate it!

would be better to send it to nodejs as a form file upload to avoid all the extra encoding.

@dandavis, but we are already talking about a binary upload


text:
Can arduino show the power drawn from its output pin on serial monitor? If yes, what code should I use?
I want to know is it possible that arduino can show how much power my prototype is drawing from arduino and if it can what would be the code for that.

You cannot directly measure the power, no. But it's simple enough to arrange using a very small amount of extra hardware.
Depending on what the device is you want to monitor there are two ways of creating the circuit that you need. Both require just a single small resistor, and either one or two analog pins.
The simplest arrangement is the "low-side current shunt" and is simply a small resistor between the ground of your device and the ground of the Arduino. This causes a small voltage drop which raises the ground potential of your device slightly, so could have an effect on communication if you're not careful (see the alternative below). Then a connection from the "top" of that resistor to an analog input will allow you to monitor the voltage drop across that resistor. From that, using Ohm's Law, you can calculate the current. That then can give you the power.
Here's a schematic:

simulate this circuit – Schematic created using CircuitLab
This arrangement does have the benefit that it will work for any power supply voltage, not just the 5V supply pin (for example powering from the VIN pin or 3.3V pin).
If you are powering your device from no more than 5V you can place the resistor in the 5V feed and avoid the offset to the ground voltage. The idea is just the same: use an analog input to monitor the voltage drop across the resistor to calculate the current and hence the power:

simulate this circuit
If you want to measure the current being drawn out of a GPIO pin, though, there is an extra step you need to consider. The GPIO has a MOSFET within it which imposes a small resistance of its own on the output. This resistance will of course cause a variation in the output voltage depending on the current drawn from the output pin. So it is important to know what the actual output voltage is rather than assuming that it would be 5V.  For that a second analog input is needed:

simulate this circuit
Now the voltage drop is calculated as the difference between the voltages measured by A0 and A1. Then all the other calculations are the same.

No, it cannot do power measurement. With an Arduino (and most other microcontrollers) you only have voltage measurement (on the analog input pins).
Though this is half of the power measurement, since power is voltage multiplied by current. Measure the voltage on that pin with an analog pin. Then you need a way to measure the current. For that you need extra hardware. There are current sensors made for Arduino, which measure the current flowing through its pins and giving out a corresponding analog voltage, which you can then measure on an analog pin. Make sure that the current sensor is rated for the correct current range to not overload it or loose resolution (by having a way bigger range in the sensor than with the actual current). For a digital output pin of an Arduino Uno/Nano the max. current should be 20mA.
You can also google for something like "Arduino current sensor". A short search gave me some promising results.
Then when you have measured the voltage and current you can multiply them to get the power.


text:
Add library to CLion project
I have a new project created with PlatformIO in CLion.  I've copied the Servo-1.1.8 library into the include directory.
#include <Arduino.h>
#include "Servo-1.1.8/src/Servo.h"

Servo servo;

void setup() {
}

void loop() {
}

I'm getting a compilation error though:
====================[ Build | Production | uno ]================================
C:\Users\USER_NAME\AppData\Local\JetBrains\Toolbox\apps\CLion\ch-0\213.5744.254\bin\cmake\win\bin\cmake.exe --build C:\Users\USER_NAME\Documents\Arduino\MultiServoCallibration\cmake-build-uno --target Production
[1/1] cmd.exe /C "cd /D C:\Users\USER_NAME\Documents\Arduino\MultiServoCallibration && platformio -c clion run -euno"
FAILED: CMakeFiles/Production C:/Users/USER_NAME/Documents/Arduino/MultiServoCallibration/cmake-build-uno/CMakeFiles/Production
cmd.exe /C "cd /D C:\Users\USER_NAME\Documents\Arduino\MultiServoCallibration && platformio -c clion run -euno"
Processing uno (platform: atmelavr; board: uno; framework: arduino)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/uno.html
PLATFORM: Atmel AVR (3.4.0) > Arduino Uno
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 31.50KB Flash
DEBUG: Current (avr-stub) On-board (avr-stub, simavr)
PACKAGES:
 - framework-arduino-avr 5.1.0
 - toolchain-atmelavr 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio\build\uno\src\main.cpp.o
Linking .pio\build\uno\firmware.elf
C:\Users\USER_NAME\AppData\Local\Temp\ccmN7v6f.ltrans0.ltrans.o: In function `_GLOBAL__sub_I_servo':
<artificial>:(.text.startup+0x98): undefined reference to `Servo::Servo()'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\uno\firmware.elf] Error 1
========================== [FAILED] Took 1.18 seconds ==========================
ninja: build stopped: subcommand failed.

I've never used CMake before, so it might well be something super simple like adding a line to some config to include that library.

the Servo.cpp file is not compiled

@Juraj Aye.  If I comment out the Servo servo; line then it compiles.  It's not very useful without it though.

For what it's worth, I asked a similar question on StackOverflow, on the chance that the slightly different crowd might include someone who uses CLion + PlatformIO for non-Arduino embedded work and has a more authoritative opinion on the topic.
I have no idea whether it's actually safe or a good idea, but for what it's worth, I was able to add an Arduino library to my project by doing the following:

Install PlatformIO with bundled VS Code, install CLion, then configure CLion to use PlatformIO.
Using CLion, create a new PlatformIO Arduino sketch. Let CLion spin its wheels, do some things that might or might not have ultimately made a difference, and make sure it's in a state where it can build and deploy successfully using CLion. I personally just called Serial.start(9600) and Serial.println("something") to output to serial, then verified it actually worked.
Exit CLion, and launch VS Code. Add the folder containing the sketch created in step 2 to its workspace.
Use VS Code to add the library. Wait for it to finish downloading, and exit VS Code.
Relaunch CLion, and try to use the new library.

Be warned, I have absolutely no idea yet whether or not this is actually kosher. I'm under the impression that when you're using PlatformIO with CLion, 100% of everything is actually managed by PlatformIO, and all CLion itself does is stub through the call to launch CMake. Assuming VS Code is the same way, this should theoretically be OK... but until someone intimately familiar with PlatformIO and the way it integrates with both CLion and VS Code reassures me that it is, I'm a little bit nervous about it.
That said... if it actually is safe to do, it's probably the best way to add an Arduino library to a CLion-PlatformIO project since (AFAIK) CLion itself has absolutely no comparable functionality (via the PlatformIO plugin or otherwise), and I've encountered a few libraries for SSD1306 OLED use that are a major pain to copy into a project by hand from their Github repo (because the OLED library has dependencies on somebody else's graphics library, which itself has dependencies on somebody else's math library and menu library, the menu library has dependencies on one or two more libraries... well, you get the idea. Pain. The exact reason things like Gradle and Maven exist for Android & Java, and CMake theoretically now exists for C(++), even though it still seems to be pretty useless in Arduino-land. ;-)


text:
Arduino controlled 25A 12V DC relay
I have an air compressor that I often give difficult tasks, where the compressor needs to run longer than it was designed for.  So it gets close to overheating, which requires periodically giving the compressor some "cool down" time, turned off.
Rather than walk into my garage every couple of minutes to turn the compressor on or off, I'd like to automate the process with a little arduino board.
The problem is the compressor is run by a 25A 12V DC line.  Most relays I can find that are Arduino compatible (3.3v DC control) max out at 10A.
I'm curious if there is a smart way to do this efficiently.  Two solutions that come to mind are:

Control 3 or 4 10A relays with the Arduino, and parallelize the current heading to the compressor across multiple relays.

Use one relay controlled by the Arduino, and use that relay to control a secondary big relay, that could control the 25A line.

Neither seems like a very efficient approach to the problem.  I don't know for certain but I worry that perhaps with (1), one relay might be a better conductor than the others, so perhaps one might eventually see a cascade of overheating relays.
Perhaps someone here that's more familiar with circuit design could suggest a better approach.
edit: After a little digging it looks like option (2) is the standard route most often traveled.

This is an OMRON relay that is powered by a 12VDC supply (0.167A), and can switch a 28VDC 30A line.   So I will double relay it, using an Adafruit featherwing to switch the 12VDC supply, which will then switch this big OMRON relay.   In my pile of old AC/DC converters I found a 1A 12V supply that's sufficient to run the OMRON relay.  Provided I haven't overlooked anything this is likely a decent solution.

(3) use some power mosfet + it's protection (but it might need some gate driver circut also)

The problem with (1) is actually that you will not be able to make all the relays close at the precise same moment, so one 10A relay will get the full 25A through it before the rest turn on. Baaaaaaaad! As KIIV says: use a MOSFET (or bank of MOSFETs).

Some folks sell a 30A logic level MOSFET RFP30N06LE or FQP30N06L for $0.95.

@DaveX: What is the role of the MOSFET?  I'm guessing you are suggesting that it would effectively replace the intermediate relay.  i.e. the arduino would trigger the MOSFET that would produce the 12V 0.167A signal to the big relay?   If so, I think maybe a different MOSFET is in order.

A MOSFET is an electronic switch that can replace a relay.  The  RFP30N06LE can replace a 30A 60V relay and be driven by the logic level produced by an arduino.  The 'logic level' feature is important, because normal MOSFETs might only be partially on with a 5V or 3.3V output, while logic-level MOSFETs are fully on.  Depending on the load, it might need a heatsink.  Better MOSFETs have lower Rd_on, wasting lower heat.

@DaveX: I can't find the RFP30N06LE, apparently it's discontinued.   The IRLB8721PBF seems similar.

Yes, the IRLB8721PBF is an good logic-level 30V 60A MOSFET, but it might struggle at 3.3v  Per the datasheet at https://www.infineon.com/dgdl/irlb8721pbf.pdf?fileId=5546d462533600a40153566056732591 Fig 1 & 2 it looks like a V_GS of 3V might not fully open for 25A 12V -- With it you might need a bit of driver like https://electronics.stackexchange.com/a/321880/30711 to get the gate voltage up to cover 20-30A.  Maybe the diode-resistor divider trick would be enough to push the 0-3.3V gate voltage to 0.7-4.0 and 40A?

Do not double relay it (at least not parallel aka Option 1).  Relays have a tendancy to bounce or take time.  This exposes you to a potential for only one relay to be connected for a time.  Worse, if someone decides to use the relays as high, low instead of closed, open it will short high to low for a time.
The series relay solution is sound but not efficient.  Relays are almost never the efficient approach (there are cases where infrequent switching occurs where a relay simply holding a position without power for long durations can be efficient).  A relay module is essentially a mosfet and a relay.  Mosfet controls the coil, and if you will have one of those, might as well go for a 12V mosfet of appropriate amperage.  I used to have some arduino compatible 3D printer heat bed mosfets that went up to 25A (on paper) so I can't imagine they're impossible to obtain.
You also mention digging power supplies for your relay.  If you are going so far as to need a 12V power supply, is there one providing for the compressor itself?  If so, could you just control the wall outlet AC that powers the supply?  Amperage would be a lot lower and AC can allow use of some rather nifty "Solid State Relay" devices (as well as relay modules, smart outlets, etc).

Thanks.  I'll have to learn how to use mosfets.  I think I knew more about circuits maybe 20-25 years ago.  Re-learning things in my 40's.   I find with little electronic devices like mosfets and transistors, it takes me a while to learn what the jargon means.  There is the "signal" current, and the other current, I'm not sure what it's name is.  But I'm slowly relearning the jargon.

Now searching on Digi-Key I'm confronted with yet more jargon. "Drain to source" voltage and "Drive voltage" ... and N-channel and P-channel.

Perhaps I could use a TIP120 to trip the 12V, 0.167A relay from my Arduino?

Regarding "do not double relay it", that's exactly what I've been doing.   As I mentioned, I'm using this to power an electric motor (4500 psi air pump).  It was working great until my air tank got to about the 4200 psi range. At this point the pictured OMRON relay started turning on and off rapidly.  Not certain what's going on there, but the current demand of the compressor was getting so high that I think there was some sort of feedback loop on the circuit, perhaps causing the smaller relay (connected to the arduino) to  cut out.

The rapid on-off cycles appear to be connected to the air compressor motor cycles.

keep it simple.  instead of buying the FET individually and having to size and mount a heat sink and cooling, just buy a module (search "arduino heat bed mosfet 12V 24V 30A" and look for one with a decent looking heat sink and naturally also the right specs).  cooling is often the limiting factor for current limits on these things.

I went with the solid state relay.  Seems to be working perfectly.


text:
Rfid Mfrc522 not working using long cable
I am doing a project using Arduino and a Rfid Mfrc522 module that consists of reading a card to unlock/lock a door. The Arduino is 3 meters far away from the Rfid Mfrc522 module and I used 7 cables to connect it, according to the schematic of the Mfrc522 Arduino library. When I previously tested the system everything was working fine but after I connect the Arduino to the module with the 3 meters cable I get this output and I can not read any card.
Firmware Version: = (unknown)
Scan PICC to see UID, SAK, type, and data blocks...

When I try to run the firmware check example for the library I get the following output
*****************************
MFRC522 Digital self test
*****************************
Firmware Version: = (unknown)
-----------------------------
Only known versions supported
-----------------------------
Performing test...
-----------------------------
Result: DEFECT or UNKNOWN

Is it possible that 3 meters away from Arduino the module is unable to communicate with it? If so what can be a possible solution to extend the "communication range" between both of them?
Thanks for the help,
Enzo

You are using 7 individual wires? That sounds bad, because that's 7 antennas. While I can't say that it will work, I'd at least try a shielded cable (you can try a standard CAT-5 cable)

Try slowing down your SPI communication. Also quadruple-check your wiring.

@PMF Thanks for the answer I will try to do that. So the issue is that each cable interferes with each other or the noise outside in air interfere with the 7 cables? Because my cat 5 cable I have at home is shielded between the 8 wires and the surroundings, not between each other. Thanks

@Majenko Thanks that could also help, do you know how I can do this in the Arduino code editor?

Depends on what library you are using. Read this: https://www.arduino.cc/en/Reference/SPISetClockDivider

@Enzo Both could be an issue. That's why good CAT-5 cables use twisted pairs, which filters interferences between two wires. I can't say which ones to put together for an SPI connection, though.

Don't use the SPISetClockDivider() as it is a deprecated method since 2014. Using the SPISettings() object to setup SPI configuration. If you are using this library it allows you to define a variable to set the clock speed and pass it in to the SPISettings object. By default, the SPI clock is set at 4MHz, I would suggest you try change it to 1MHz.