text:
Programming Questions / Capacitive Soil Moisture Sensor
Good day All,
This is my first time posting to this forum and kind off my last resort as I would've liked to figure it out myself. I am trying to create a soil moisture probe which can be used on farms to determine soil moisture at different depths. The project consists of a Arduino Nano, a DIY capacitive moisture reading setup (schematic attached- My setup is the same except for the LED moisture indicator)) and an LCD screen to display the required value.
My initial setup was a Arduino Nano (328P Old Bootloader) with a resistive soil moisture sensor. However, these sensors (as they are resistive) do not give reliable readings when measuring at different spots in a field. I believe it is largely influenced by pH, salt content etc.
My next approach was to build a DIY capacitive soil moisture sensor. After searching the web I came across a setup on hackster.io ( https://www.hackster.io/Pedro52/arduino-capacitive-soil-moisture-sensor-diy-with-esp32-d7ad72 ) where a signal is sent via a ESP 32 microcontroller to a probe in the soil and a signal is returned. I implemented the same setup with the same components however I only used optimization of the timers on the Nano to generate the PWM wave (Once again this code was also obtained from another website and I am still a bit confused on how the code works).
I seem to get a reading from the sensor but the zero value seems to very volatile. Even if the wire is only picked up, the output reading changes. Is there a way to get around this and can someone please help me to get my system working optimally.
It would be highly appreciated.

 /

    /The setup uses a Chinese Arduino Nano, a 10M ohm, a 10k ohm, a 1N4007 diode and a 1 microfarrad capacitor as shown in the schematic.
    //The LED moisture indicator in the schematic can be ignored

    //#include <LiquidCrystal_I2C.h>
    //#include <LcdBarGraphRobojax.h>
    #include <Wire.h>

    //LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
    //LcdBarGraphRobojax lbg(&lcd, 16, 0, 0);

    float Moistlevel = 0;
    float Moistpin = A1;
    float Moisture = 0;
    float RESET;
    float factor;
    const byte CLOCKOUT = 9;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  TCCR1A = bit (COM1A0);                  //Code which I obtained to initiate the onboard timer 1 to give a signal through D9
  TCCR1B = bit (WGM12) | bit (CS10);
  OCR1A =  0;                             // Apparently this should be changed for prescaling. Is it necessary?

  RESET = analogRead(Moistpin);           // Take a initial reading to zero the setup

  for (int j = 1; j < 5 ; j++)            // Take another 5 readings of which the average will be determined
  {
    RESET = RESET + analogRead(Moistpin);
    delay(200);
  };

  RESET = RESET / 6;

  Serial.print(RESET);
  Serial.println();

  Serial.print("Moistlevel");
  Serial.print("\t");
  Serial.print("\t");
  Serial.print("Moisture");
  Serial.println();
}

void loop() {

  Moistlevel = analogRead(Moistpin);                  //Take an average reading every second

  for (int i = 1; i < 5 ; i++)
  {
    Moistlevel = Moistlevel + analogRead(Moistpin);
    delay(200);
  };

  Moistlevel = Moistlevel / 6;
  Moisture = (RESET - Moistlevel) / (RESET / 100);    //Conversion to go from a voltage reading to a percentage reading

  if (Moisture < 0)                                   //Moves the initial if a negative moisture is obtained.
  {
    RESET = Moistlevel;
  };

  Moisture = (RESET - Moistlevel) / (RESET / 100);    //Obtains the new moisture value and prints it.

  Serial.println(Moistlevel);
  Serial.print("\t");
  Serial.print("\t");
  Serial.print("\t");
  Serial.print(Moisture);
  Serial.println();
  delay (500);
}

https://arduino.stackexchange.com/tour

Touching a capacitive sensor will change its readings, that's normal. Are you sure your code is sending the right frequency to the right pin?

I have tried different signals, all without any success...

Thanks to all for the advice,
I have chosen to divert the whole system and rather make use of a 555 timer to sent a frequency to the measuring pins. It has been tested and seems to resolve the issue completely.

Calling this a capacitive sensor may be inaccurate. And that could be the least of its problems. The "fritzing" schematic is unclear, and seems to be at odds with the explanation in Step 4 of the description. Fortunately, a legible schematic was derived here.
The author of the hackster.io article cites Andreas Speiss' well-known YouTube video on "Why Most Moisture Sensors Suck"... and then proceeds to design a moisture sensor that... sucks! This design seems to "miss the point": dc current causes an electrolytic reaction when the conductor is in direct contact with an electrolyte (like water and damp soil).
Wrt the OP's comment that touching the wire changes the output reading: It's almost certain that there is more capacitance in the lead wire than there is in the "fondue forks". According to the article, audio cable was the author's choice for transfer of a 600 kHz signal from his breadboard to the sensor. The long-ish lead wires to the sensor strike me as an odd choice.
I've been more than a little critical of this hackster.io project. But of course I may have overlooked something important - I make mistakes each and every day. If someone cares to point out any mistakes I've made here, I'll be glad to revise or delete this post. Until then, my proposed answer is to find a better DIY project.
Nevertheless - you are on the right track by deciding to build a capacitive moisture sensor. Unless the "fondue forks" are insulated to render them non-conductive when immersed in the soil/water electrolyte, this is not a capacitive sensor - it is resistive. And its flaws may go even deeper. Another DIY guide may yield better results.
For anyone interested, an LTspice simulation of the sensor circuitry may provide insights into its operation. In one case, the sensor is modeled as a purely capacitive device (i.e. the "Fondue Forks" are insulated to prevent dc current from flowing through the soil), and in the second case as an R-C circuit (i.e. the "Fondue Forks" are un-insulated, and dc current flows through the soil). The values for Rw2 and C2/C1 were based on measurements I made with a similar sensor:

I made the following observations using this model of the sensor:

the time constant for the RC filter on the sensor output may be substantially longer than necessary.

Note the dc current flow through Rw2 averages ~ 0.18mA. Knowledge of this value will allow use of Faraday's Law of Electrolysis to estimate how much of the chrome plating will be dissolved in your soil over time.

The value of Rw2 largely determines the value of the output voltage; the value of the capacitance plays a much smaller role. Thus, this sensor is mostly resistive rather than capacitive.

The LTspice .asc file follows; all feedback welcomed:
Version 4
SHEET 1 908 720
WIRE 336 32 288 32
WIRE 352 32 336 32
WIRE 512 32 432 32
WIRE 288 80 288 32
WIRE 336 80 336 32
WIRE 416 80 336 80
WIRE 512 80 512 32
WIRE 512 80 480 80
WIRE 512 96 512 80
WIRE 160 208 128 208
WIRE 288 208 288 144
WIRE 288 208 240 208
WIRE 480 208 288 208
WIRE 288 288 288 272
WIRE 288 288 128 288
WIRE 480 288 288 288
WIRE 288 304 288 288
WIRE 320 368 272 368
WIRE 336 368 320 368
WIRE 512 368 416 368
WIRE 272 400 272 368
WIRE 320 416 320 368
WIRE 416 416 320 416
WIRE 512 416 512 368
WIRE 512 416 480 416
WIRE 512 432 512 416
WIRE 160 528 128 528
WIRE 272 528 272 464
WIRE 272 528 240 528
WIRE 384 528 272 528
WIRE 464 528 384 528
WIRE 272 608 272 592
WIRE 272 608 128 608
WIRE 384 608 272 608
WIRE 464 608 384 608
WIRE 272 624 272 608
FLAG 288 304 0
FLAG 272 624 0
FLAG 480 208 Vsensor1
FLAG 464 528 Vsensor2
FLAG 512 96 0
FLAG 512 432 0
FLAG 288 32 Vout-insul
FLAG 272 368 Vout-unins
SYMBOL voltage 128 192 M0
WINDOW 3 -172 139 Left 0
SYMATTR Value PULSE(0 3.3 0 20n 20n 833.5n 1667.0n)
SYMATTR InstName V1
SYMBOL voltage 128 512 M0
WINDOW 3 -140 138 Left 0
SYMATTR Value PULSE(0 3.3 0 20n 20n 833.5n 1667.0n)
SYMATTR InstName V2
SYMBOL cap 256 528 R0
SYMATTR InstName C2
SYMATTR Value 80.0p
SYMBOL res 368 512 R0
SYMATTR InstName Rw2
SYMATTR Value 5000
SYMBOL res 256 192 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName Rs1
SYMATTR Value 10k
SYMBOL res 256 512 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName Rs2
SYMATTR Value 10k
SYMBOL cap 272 208 R0
SYMATTR InstName C1
SYMATTR Value 80.0p
SYMBOL diode 304 144 R180
WINDOW 0 24 64 Left 2
WINDOW 3 24 0 Left 2
SYMATTR InstName D1
SYMATTR Value 1N4007
SYMBOL diode 288 464 R180
WINDOW 0 24 64 Left 2
WINDOW 3 24 0 Left 2
SYMATTR InstName D2
SYMATTR Value 1N4007
SYMBOL res 448 16 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R1
SYMATTR Value 1Meg
SYMBOL res 432 352 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R2
SYMATTR Value 1Meg
SYMBOL cap 480 64 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C3
SYMATTR Value 10.0n
SYMBOL cap 480 400 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C4
SYMATTR Value 10.0n
TEXT 96 696 Left 1 !* .tran 0 2m 1.99m\n.tran 0 50.0m 49.99m
TEXT 312 168 Left 2 ;Insulated "Fondue Forks"
TEXT 288 488 Left 2 ;Non-insulated "Fondue Forks"
RECTANGLE Normal 256 184 640 316 2
RECTANGLE Normal 256 508 640 628 2

Seems the OP cross-posted this question here & got some answers.


text:
How can we know the status of the DC Motor whether it is ON or OFF
A DC motor is operated using an L298n driver and Arduino UNO. How can I get to know whether the Motor is ON or OFF? Using a code in Arduino.

You control the motor via the Arduino. Thus you already know if it is on or not. Or do you want to find out, whether it actually turns?

There's nothing on the L298N that returns that status there's nothing you can read. So you have to assume if your code correctly sets the enable pin that the motor is running.

Like @chrisl said. If you're trying to detect a stall condition, you can put that into the question.

use a sensor to detect the motor shaft rotation

Unfortunately, the L298N does not return a status, so you are going to have to add sensors to detect motor movement.
Here are a few options you can try:

Current sense. Add a small resistor to the output of the L298N and measure the voltage differential across that resistor. If there is current being supplied to the motor then you will have a voltage differential.
Rotation sensor. This can be in the form of a quadrature encoder wheel, tooth sensor or Hall effect sensor detecting a magnet on the shaft. If you see pulses from the sensor then you know the motor is spinning.
Optical sensor. A camera system or other optical sensor to detect motor movement. Probably too complex for a simple application. There are however off the shelf sensors that will turn on an output if they see movement in their field of view. Alternatively you could use a PIR sensor from a home alarm system if the movement is course enough.

This may be too simple, but for completeness: You can read back the state of the output bit, in case your code doesn't save its current state. That will tell you if the motor is literally "on" or "off". Not rotating despite being "on" is another matter; an error.
If you need error detection then you need additional hardware support.
Some possibilities:

Sense rotation with a cam and a micro-switch or an optical sensor and a slotted disk;
Sense the motor current - a stalled motor will draw a high current;
Sense vibration in the motor platform;
(apply imagination here...  ;-)

source: Stack Exchange

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

sort: votes


text:
NodeMCU unable to communicate with MFRC522 RFID reader even though the nodeMCU is successfully connected to a mobile hotspot
I am replicating a project that will read the RFID card or tag data, store that into a mysql database and display the data via PHP.
I am using NodeMCU, RC522 RFID reader and Ardunio IDE to do that.
Below is the Arduino code. It successfully connects with WiFi (that I can see via serial monitor) but gives no response when I touch the RFID card to the reader and there is no display of the card UID in the PHP web app.
I can't find the error.
The owner of the project suggested that the nodeMCU might be faulty which isn't the case and now i am at loss. Please help.
//NodeMCU and RFID libraries--------------------------
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN  D2  //D2
#define RST_PIN D1  //D1

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

/* Set these to your desired credentials. */
const char *ssid = "TECNO CAMON 15";
const char *password = "d6364e300f59";
const char* device_token  = " 4c9fc9995e7f9c6d ";

String URL = "http://192.168.43.40/school_project/getdata.php"; //computer IP or the server domain
String getData, Link;
String OldCardID = "";
unsigned long previousMillis = 0;

void setup() {
  Serial.begin(115200);
  SPI.begin();  // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card
  WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
    delay(1000);
    WiFi.mode(WIFI_STA);
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);

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

    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());  //IP address assigned to your ESP

    delay(1000);
}
//************************************************************************
void loop() {

  if (millis() - previousMillis >= 15000) {
    previousMillis = millis();
    OldCardID="";
  }
  delay(50);
  //---------------------------------------------
  //look for new card
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;//got to start of loop if there is no card present
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;//if read card serial(0) returns 1, the uid struct contians the ID of the read card.
  }
  String CardID ="";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    CardID += mfrc522.uid.uidByte[i];
  }
  //---------------------------------------------
  if( CardID == OldCardID ){
    return;
  }
  else{
    OldCardID = CardID;
  }
  //---------------------------------------------
//  Serial.println(CardID);
  SendCardID(CardID);
  delay(1000);
}
//************send the Card UID to the website*************
void SendCardID( String Card_uid ){
  Serial.println("Sending the Card ID");
  if(WiFi.isConnected()){
    HTTPClient http;    //Declare object of class HTTPClient
    //GET Data
    getData = "?card_uid=" + String(Card_uid) + "&device_token=" + String(device_token); // Add the Card ID to the GET array in order to send it
    //GET methode
    Link = URL + getData;
    http.begin(Link); //initiate HTTP request   //Specify content-type header

    int httpCode = http.GET();   //Send the request
    String payload = http.getString();    //Get the response payload

//    Serial.println(Link);   //Print HTTP return code
    Serial.println(httpCode);   //Print HTTP return code
    Serial.println(Card_uid);     //Print Card ID
    Serial.println(payload);    //Print request response payload

    if (httpCode == 200) {
      if (payload.substring(0, 5) == "login") {
        String user_name = payload.substring(5);
    //  Serial.println(user_name);

      }
      else if (payload.substring(0, 6) == "logout") {
        String user_name = payload.substring(6);
    //  Serial.println(user_name);

      }
      else if (payload == "succesful") {

      }
      else if (payload == "available") {

      }
      delay(100);
      http.end();  //Close connection
    }
  }
  }
//=======================================================================`

Can you get RFID to work without all the Wifi stuff? If you haven't tried, simplify everything down to a "blink"-like sketch for RFID, and debug that.

I have done the blink sketch and it works. The problem is when I connect it to the NODEMCU and want to scan the rfid card so that it registers on the php web app, nothing happens

@Wayne254 please add the serial monitor messages to your post

@jsotola I have added the serial monitor showing the connected network

thanks  ... no picture of text please ... some of us cannot see the picture ... add the actual text

In tutorial of developer i remember a mistake in descrition wiring mosi miso sck on mcu. Verify wiring schema with standards

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


text:
Generate 1khz square signal with Arduino Mega
I want to generate a 1khz square signal with an Arduino Mega.
I have read the MCU contains several timers.
What i want to do is to configure one of this timers.
My first question is: Is there a way to automatically control an output pin from the timer, without having to execute any line of code in my arduino program ? Look at my code: i need to write a line in ISR(TIMER1_OVF_vect). Some MCU can do that but i did not find any information about it on documentation. (Some pins are connected on timer outputs, by hardware conception).
My second question is: What is wrong on my calculation on my code ?
I want 1khz and i get 990Hz
Here is what i've done:

Arduino Mega runs at 16Mhz = 16000Khz
I have set a /8 prescaler, so timer's frequency is 8000Khz
The frequency should by divide by two because i have 2 states (HIGH and LOW): 4000Khz
The interupt is fired when the counter reach 65536. So if i load 65536-1000 in TCNT1, the timer should count 1000 times in order to fire the interupt. So my frequency is 4000khz/1000 = 1khz.

What is wrong ?
Thanks a lot
void setup() {
  pinMode(14,OUTPUT);

  noInterrupts();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 65536 - 1000;
  TCCR1B |= (1 << CS11);    // Prescaler clock / 8
  TIMSK1 |= (1 << TOIE1);
  interrupts();
}

ISR(TIMER1_OVF_vect)
{
  TCNT1 = 65536 - 1000;
  digitalWrite(14, digitalRead(14) ^ 1);
}

void loop() {

}

This does not really answer your question, but actually there really is a way to let the timer automatically control an output pin. You can use the timer in output compare mode. You write a value in the corresponding OCR (the register) and let the timer run from 0 to this value. When reaching that, the corresponding pin gets automatically toggled and the timer resets. That way you can do this a lot more accurate

You shouldn't set TCNT1, but you need to set the TOP value. This depends on which PWM/timer mode you use (see table in datasheet). I know it's ICR1 or OCR1A on the UNO. Not sure about the Mega.

As explained in the previous answer, you forgot to account for the time
taken by the CPU to handle the interrupt prologue. As a general rule, if
you want consistent timing, you should never reset the timer by
software after the initialization.
If you want to run the timer in normal mode, and use it to schedule
interrupts at a period that is not the timer's own period, it is
possible, but you should not use the overflow interrupt for this
purpose. You should instead use any of the “compare match” interrupts,
and adjust the compare register in the IRS in order to schedule the next
interrupt. For example:
void setup() {
    pinMode(14,OUTPUT);

    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS11);    // clock @ F_CPU/8
    TCNT1  = 0;            // clear timer
    OCR1A  = 1000;         // first COMPA match in 1000 cycles
    TIFR1  = _BV(OCF1A);   // clear interrupt flag
    TIMSK1 = _BV(OCIE1A);  // enable TIMER1_COMPA interrupt
}

ISR(TIMER1_COMPA_vect) {
    OCR1A += 1000;      // schedule next interrupt
    PINJ   = _BV(PJ1);  // toggle PJ1 = digital 14
}

Note that the line OCR1A += 1000; can cause a wrap around, but this is
no problem, as the addition wraps around in exactly the same way as the
timer itself.
The advantage of this technique is that you can schedule up to three
different tasks, having different periods, with only one timer. And you
can even schedule tasks in a non-periodic fashion.
That being said, if you do not need the timer for anything else other
than scheduling a single periodic task (or up to four tasks sharing the
same period), then a better solution is to let the timer handle the
period all by itself. Configure the timer in mode 12 or 14 (CTC or fast
PWM, with TOP = ICR1), and set the period with ICR1 = 999;. Then the
ISR is reduced to:
ISR(TIMER1_COMPA_vect) { PINJ = _BV(PJ1); }

and you save a few cycles. This would be my preferred solution if I
absolutely had to output the signal on pin 14.
Note that this solution should give you the right average frequency,
but you will still have some jitter, because the interrupt can
occasionally be delayed by other interrupts. If you are free to choose
the output pin, then the best solution is to let the timer handle the
PWM generation all by itself. Set the timer to any PWM mode (fast PWM is
the simplest) and use one of the waveform generators in order to
generate the PWM signal. Only the PWM-capable pins (those marked with a
“~” symbol) can be used this way. For example, Timer 1 can output to
pins 11 (OC1A), 12 (OC1B) and 13 (OC1C).
Edit answering the question:

what is the goal of TIFR1 = _BV(OCF1A); // clear interrupt flag?

Whenever the timer value matches the contents of the compare register
OCR1A, the interrupt flag OCF1A (Output Compare Flag of timer 1,
channel A) is raised. This flag controls the interrupt request when the
OCIE1A bit (Output Compare Interrupt Enable 1A) is set. The flag is
automatically cleared when the ISR runs, and can be manually cleared by
writing a logic 1 to it (yes, it is kind of backwards).
It is quite likely that the flag raises early in the start process,
while the Arduino library is initializing. If the flag is up when you
enable the interrupt, an interrupt request is immediately triggered. In
order to avoid that, the common practice is to clear the flag before
enabling the interrupt.

Thanks but what is the goal of "TIFR1  = _BV(OCF1A);   // clear interrupt flag" ?

pin 14 is an example, i can do it on any pin

@Bob5421: See amended answer.

About your answer on "TIFR1 = _BV(OCF1A)": Is it necessary if i put noInterrupts() / interrupts() in my setup function ? Thanks a lot

@Bob5421: Yes. noInterrupts() does not prevent the interrupt request from being triggered. The interrupt would then fire as soon as you call interrupts().

That OCR1A  = -1000; is interesting -- why the negative?  Wouldn't it be equivalent to OCR1A = 65536 -1000; or First COMPA match in 64536 cycles?

@DaveX: OCR1A  = -1000; is indeed equivalent to OCR1A = 65536-1000;. That was an error of mine. I was mixing this up with the idea that TCNT1 = -1000; ensures the overflow fires in 1000 cycles.

My first question is: Is there a way to automatically control an output pin from the timer, without having to execute any line of code in my arduino program ?

Yes. It's called PWM with a 50% duty cycle.
You need to read up on 19. Output Compare Modulator (OCM1C0A) in the datasheet.

My second question is: What is wrong on my calculation on my code ? I want 1khz and i get 990Hz

You have to take into account the number of CPU cycles it takes to start executing your ISR. There's a short bit of code before your code is run that preserves any used registers on the stack and allocates any room needed for local variables. That takes time, and must be calculated into your timing factor.

The 19. Output Compare Modulator (OCM1C0A) feature seems like overkill for a 1KHz square wave.  That modulates timer 1 and timer 2 together based on OCR1C OCR0A and puts an output on B7.  An unmodulated 1kHz square wave could be done without overhead by using Timer 1 in one of the WGM modes with TOP as ICR1 or OCR1A.


text:
How can I interface, received HC-12 data and transmit the received data using sx-1278 RF-module in arduino-UNO?
I am currently working on a project, where I need to send data from first unit to the second unit which is a few km apart, so I decided to go with hc-12 RF module as it covers upto 5km. Then the data received in the second unit is again to be transmitted to the last unit which is several km apart from each other, so I decided to go with sx-1278 RF module which can easily transmit data up to 30kms. I am trying to get the received data to print on the serial monitor. So, how do I transmit the received HC-12 data in the second unit using the sx-1278 RF module to the third unit? Is this operation even possible? Are these two boards compatible with each other?
If the answer is yes, please do help me out with the coding part on how to interface these two RF-modules.
Thanks in advance

what kind of I/O do the two RF modules use?

For the input parts, I am using a temp sensor (LM-35), a pulse senor (RC-A-4015), and a GPS sensor (neo-6m) and for the output part, as of now, I'm just trying to print it on the serial monitor.

i asked about the RF modules ... let me rephrase that ... how do the RF modules communicate with an arduino?

The RF module consists of a 433 MHz RF transmitter and receiver modules. These are ASK or FSK type RF modules....The transmitter and receiver are needed to be interfaced with arduino for data transfer...The data is sent serially from the transmitter and is received by the receiver on the other end... the RF transmitter receives serial data from arduino and transmits it to the receiver through an antenna connected to the transmitter. The receiver receives the data through an antenna and gives the data to the microcontroller connected to it.

i did not ask how the RF modules communicate with other RF modules

I have used the digital pins of the Arduino...i.e.(4,5) ..as the transmitter and the receiver part of the RF module.

is it I2C? ....

No....its UART.

the one in the middle will have to use at least one hardware serial ... an arduino cannot use two software serial ports

oh..ohk. But is there any other way to send the data? or should I simply use an other arduino to perform this operation...by this I mean...collect the data received from hc-12 and store it in some storage device, and then send the data that is there on the storage device using sx-1278? is this method efficient? Or is there any other method to do this work? Please suggest.

it is unclear how data collection relates to the transmission of data ... the two functions are not really related ... you have three arduinos ... connect the RF module to software serial at the endpoint arduinos ... at the middle arduino, connect one RF module to software serial and the second one to the hardware serial

Ohk..I get it now. Thank you so much for the help.

it may be possible to run without an arduino in the middle ... just connect the RF module data pins together

is that so?...I'll try that out then....One more thing, instead of using the hardware serial..could I just stick with two two software serial? Please check out this link where it demonstrates..on how to use to software serial .. https://www.arduino.cc/en/Tutorial/LibraryExamples/TwoPortReceive

if you can make it work, then go for it

Ohk...Thank you so much for the help.


text:
2 SPI Slaves with 2 different SPI modes on one Arduino Mega
I am working on a project where I read 8 MAX31856 thermocouple sensors using the Adafruit Library. This works just fine and prints the read outs to serial.
I want to also save the readings to a microSD card. And this is where I hit a snag.
I am trying to use the SdFat.h library. I can loop through my MAX31856 thermocouples, and write once to my SD card, but after that it hangs the SPI bus.
the MAX31856 works on SPI_MODE1 (as per Adafruit Library) and the microSD card works on SPI_MODE0, I believe. I am trying to switch SPI bus modes before and after writing to the SD card but I think there is something wrong after first successful write to the SD card. After the first loop iteration, it seems like all data is basically noise on the SPI bus.
I am using the Adafruit ADA254 microSD breakout Board, which has a card detect pin, so I first check to see if an SD card is inserted, and then write to the file.
Question: Is there another or better way to switch SPI_MODES on each loop? is there anything more I need to consider so I end up back to SPI_MODE1 appropriately for the MAX31856 thermocouples?
Below is the pertinent code for what I have going on...
void setup(){
   int sdCard = 36;
   char filename[10] = "test.txt";
}

void loop(){
....code to read thermocouples ...

///THEN THIS

  //lets confirm SD card is still in socket before writing
  CardDetect = digitalRead(37);
  if(CardDetect == HIGH){

     SPI.setDataMode(SPI_MODE0);
     SPI.setClockDivider(SPI_CLOCK_DIV4);
     SPI.setBitOrder(LSBFIRST);
     digitalWrite(sdCard, LOW);
     sd.begin(sdCard, SD_SCK_MHZ(1));
    //LETS START SAVING DATA
          myFile.open(filename, O_WRONLY | O_CREAT | O_EXCL);
          myFile.write(now.unixtime());
          myFile.write(",");
            for(int i = 0; i<8; i++){
              myFile.print(TEMP[i]);
              myFile.write(",");
            }
          myFile.println();
          myFile.close();
          digitalWrite(sdCard, HIGH);
          SPI.setDataMode(SPI_MODE1);
          SPI.setClockDivider(SPI_CLOCK_DIV16);
          SPI.setBitOrder(MSBFIRST);
          delay(200);
    }

}

what is your question?

if your question is how do I debug the code?, then remove all sensor code and see if file is written without crashing

@jsotola - the file is writing no problem on first iteration. However, after the first loop of the code, the SPI bus 'glitches' and I does not read sensors correctly

This is more likely the SD card or level translator itself interfering with the SPI bus. I never share an SPI bus with an SD card - always have it on its own dedicated bus.

@Majenko I feared this... I needed all the digital pins, hence why the project is built around the arduino Mega - any way to add a second SPI bus (software maybe)?
Wait - are you the author of: https://github.com/MajenkoLibraries/SoftSPI ?

I might be. Been so long I have no idea how well it works. I've become so used to working with chips with 6 SPI busses built in I've had no cause to use it for a number of years...

the Adafruit's library has built in software SPI. use the constructor with pin numbers Instantiate MAX31856 object and use software SPI pins

@Juraj I have done that, each MAX31856 thermocouple object is built by their software SPI pins, eg: Adafruit_MAX31856(22,50,51,52)
Again - my code works fine until I get to the SD card logic. If I remove the SD card logic, code works too. It has something to do with the SPI bus after I read/write to SD card

In case you are using a 'cheap' SD reader, the SPI bus cannot be shared. I had more luck with a SD data logger card. It is related to thri-stating.

@Michel im using the Adafruit breakout board... not cheap. I believe it has something to do with different SPI_MODES between my spi devices

@NRav ok then it's probably not the issue I had long time ago.

don't use the hardware SPI pins for software SPI

@Juraj I was under the impression that declaring the pins was just redundant... or am I misinterpreting that? In which case, any 3 digital pins can be SPI bus pins?

those are the pins which software SPI will use. by using this constructor you activate software SPI on selected pins

For anyone who has a similar issue with the SPI Bus, SdFat library has a Software SPI option built in (example here).
You need to modify your SdFat/SdFatConfig.h file, but that is minimal. Once you have the microSD card module on a separate bus, it will not corrupt the main SPI Bus.
Switching the SD Card module to it's own bus rectified the issue. Keep in mind that Software SPI comes with a speed penalty.


text:
Use Android on Arduino TFT
I don't know whether this is possible or not but is there any way that I can run something similar to Android on a normal TFT. I want to make complex graphics but can't program those complex programs using the Adafruit TFT library.
Arduino Mega 2560 with Elegoo TFT 2.8"

a TFT is just a display ... it does not run code

start at the begining ... write a sketch that displays a full screen image on the TFT  ..

As jsotola says, start simple. Learn to draw lines and rectangles and such. Then learn how to combine those into the graphics that you want. The problem with "fancy" graphics is that they are generally big - based around bitmap images, which the Arduino can't handle well. You need some extra storage (flash chip, SD card, etc) to store them. Maybe learn how to display bitmap images from SD card would be a good step.

No. Not even remotely. Android runs on a powerful computer not a tiny embedded microcontroller.


text:
Pass Color to a function without using a specific Adafruit_NeoPixel
I'm initializing my strips as an array:
// Declare NeoPixel strip array:
Adafruit_NeoPixel strip[] = {
  Adafruit_NeoPixel(LED_COUNT[0], LED_PIN[0], NEO_RGBW + NEO_KHZ800),
  Adafruit_NeoPixel(LED_COUNT[1], LED_PIN[1], NEO_RGBW + NEO_KHZ800),
  Adafruit_NeoPixel(LED_COUNT[2], LED_PIN[2], NEO_RGBW + NEO_KHZ800),
  Adafruit_NeoPixel(LED_COUNT[3], LED_PIN[3], NEO_RGBW + NEO_KHZ800),
  Adafruit_NeoPixel(LED_COUNT[4], LED_PIN[4], NEO_RGBW + NEO_KHZ800)
};

and when I pass Color to a function, I'm arbitrarily using my first strip to create the Color:
  everyother( strip[0].Color( 0, 255, 0), strip[0].Color( 255, 0, 0), 500);

but in the subroutine I use those colors to set pixels to every strip of the array in a loop:
// set every other color to color1 or color2
void everyother( uint32_t color1, uint32_t color2, int wait) {
  for(int k=0; k<NUM_STRIPS; k++) {
    for( int j=0; j<LED_COUNT[k]; j++) {
      if( j%2 == 0) strip[k].setPixelColor(j, color1);
      else strip[k].setPixelColor(j, color2);
    }
  }
  for(int k=0; k<NUM_STRIPS; k++) strip[k].show();
  delay(wait);
}

Is there another way to define Color that isn't using a real Adafruit_NeoPixel? Yes, it works this way but it feels sloppy.

Looking at the library at https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.h, you can see that the Color method is static (see line 307):
static uint32_t   Color(uint8_t r, uint8_t g, uint8_t b) {
  return ((uint32_t)r << 16) | ((uint32_t)g <<  8) | b;

This means instead of
strip[0].Color( 0, 255, 0)

You can use:
Adafruit_NeoPixel::Color( 0, 255, 0)

Your call to everyother will be:
everyother(Adafruit_NeoPixel::Color( 0, 255, 0),
           Adafruit_NeoPixel::Color( 255, 0, 0),
           500);

And since everyother is now not a good name, you can think of a better one, e.g. fillLeds (always start a method name with a verb).
Offtopic:

A subroutine is barely used anymore, I think the last time I heard it, is from the Basic programming language
A function is now used instead
But when a function is inside a class, it's not called a function, but called method.

Thanks for the response. I knew it was gonna be something simple that I was missing. And thanks for the tips. If you need help writing assembly for a VAX, hit me up.

@JohnnyRollerfeet ... you're welcome... I don't have a VAX at hand lol, but in case I see one, I know who to call. Now I also know why you used the term subroutine. Good luck with your project.


text:
ESP8266 occasionally stops receiving data
So I have an ESP8266 board that I am using to control some LED lights. I wasn't a fan of the needing to reflash my board everytime I wanted to try a new light pattern, so I decided to send the light data over wifi (UDP), and that works for certain light patterns, but any pattern that has leds that turn on/off starts to stutter and stop after a while. If every light is on, there's no problem with the speed I'm sending data, but if there are some that are on and some off, without fail it will always stop receiving data at a certain point. I've got a couple points of failure and this is my first time messing with an arduino so I'm not sure whether the problem could be on my local program, on the program for the board, the data, my wifi, or something else.

You should probably describe how the board and leds are powered and how many leds.  In short, it sounds ultimately like a power problem this is being revealed when you request a change.

do you have a question?  ... you described the problem, but there is nothing that can be answered

does it stop until reboot, or does it just pause? You might want to try dumping system_get_free_heap_size() to see if you have a mem leak.

It was a memory leak! The data I was sending was slowly growing due to some poor math on my end; fixed that up and it worked great.

dandavis helped me find the answer! Turns out it was a memory leak, due to some poor math on my end. All I had to do was fix that up and it worked fine.


text:
Reading JSON from Arduino over serial in python and writing to a JSON file on computer
I'm fairly new to Arduino so I used a sample code before integrating this into my main code. I'm printing my value in a JSON format over serial. My Arduino outputs this and the python receives this and prints it in the same format
{

"value" : 5

}

but when I use python to try writing to a JSON file on my computer, I'm not getting the same JSON format. Can anyone figure out what's wrong? I need to write to my JSON file in JSON format, but instead, I'm getting this format written in my JSON file "  \"value\": 5\r\n" instead of {"value: 5"}. Another problem I'm getting is that sometimes the values I get in my JSON get cut off so sometimes I end up with \r\n" or other parts of the current output. My goal is to get the python code to overwrite the JSON file in real-time, so whenever I open the JSON file, the entire output should be there in the correct JSON format. Any help is appreciated, thank you.
Arduino Code:
#include <ArduinoJson.h>

int analogPin = 3;
int data = 0;
char userInput;

StaticJsonDocument<100> testDocument;
char buffer[100];

void setup(){

  Serial.begin(9600);          //  setup serial

  StaticJsonDocument<100> testDocument;

  testDocument["sensorType"] = "Temperature";
  testDocument["value"] = 10;

  char buffer[100];

  serializeJsonPretty(testDocument, buffer);

  Serial.println(buffer);

}
int(i)=1;
void loop(){

    testDocument["value"] = i;

    serializeJsonPretty(testDocument, buffer);

    Serial.println(buffer);

    i=i+1;
 }

Python Code:
import serial
import json
import time

ser = serial.Serial('COM4', baudrate = 9600, timeout=1)

while 1:

    data = (ser.readline().decode('ascii')) #split('\r\n')

    #j = json.loads(data)

    file = "C:/Users/Mike/Desktop/test.json"

    my_data_file = open(file, 'w')

    with open(file1, "w") as my_data_file :
        json.dump(data, my_data_file)

    print(data)

Is the JSON correctly send via serial? Please look at the output of the Serial Monitor, to check that. Having backslashes in there suggest, that the ASCII characters don't get escaped correctly. The python code is not really our territory (as here is Arduino SE). Though: you have commented out the json.loads(data) line. Currently you are trying to json dump a string, which should be a data structure. if you want to dump the json, you first need to load it. Or you could completely ditch the python json and just write the received json string to the file

Yes, when I print the data I'm receiving the same output as my serial monitor, just not in the JSON file. I'll take a look at the code again and look at what you suggested. I'll try posting to a more suitable group for the python as well. Thank you for your help.

@chrisl I looked at what you said and so every time I run the code, I get a JSON output in the serial monitor and when I print the data in python. However, when I write the data to the JSON file it's in that weird format with the quotations on the outside and backslash symbol in between. I couldn't find a way to write it in the JSON format. I used a different arduino code to try it and I'm still getting the same thing, no luck.

I don't know, what you are doing with your python code. But in the above code, you should do the following: Read all available data, until you have all you need, not just one line at a time. Then use the line j = json.loads(data) to get the data as python data structure (data must be a string with the complete json string). Then you can dump j to the file. You are getting the masking backslashes, because you are currently trying to dump a string instead of the data structure. And when saving a string in json, the json module must escape the special characters like "

okay, I think that's where I'm getting my errors with the special characters. I'll take a look. Thank you for helping out.


text:
TFMini Sensors with Arduino
I have three TFMini sensors I need all of them to detect. I only got one to work , pins 4,5 . My info in coding is basic . I really appreciate your help . Thanks in advance.
I think the problem is with Library I can't add TFMini_1.
Here is my code,
#include <SoftwareSerial.h>
#include "TFMini.h"
TFMini tfmini;
TFMini tfmini1;

//Declaring variables and constants
TFMini TFFront;
TFMini TFRight;
TFMini TFLeft;
SoftwareSerial SerialTFMini (4,5);    //(RX, TX)
SoftwareSerial SerialTFMini_1 (6,7);    //(RX, TX)
SoftwareSerial SerialTFMini_2(8,9);     //(RX, TX)

void getTFminiData(int* distance, int* strength) {
  static char i = 0;
  char j = 0;
  int checksum = 0;
  static int rx[9];
  if(SerialTFMini.available())

  {
    // Serial.println( "tfmini serial available" );
    rx[i] = SerialTFMini.read();

    if(rx[0] != 0x59) {
      i = 0;
    } else if(i == 1 && rx[1] != 0x59) {
      i = 0;
    } else if(i == 8) {
      for(j = 0; j < 8; j++) {
        checksum += rx[j];
      }
      if(rx[8] == (checksum % 256)) {
        *distance = rx[2] + rx[3] * 256;
        *strength = rx[4] + rx[5] * 256;
      }
      i = 0;
    } else
    {
      i++;
    }
  }
}

       //Threshold distance in "cm"; speak only when any object is nearer than this distance

void setup()
{

  //Initializing Baud Rates
  Serial.begin (115200);
  while(!Serial);                     //Wait for USB Serial Port to connect
  Serial.println("Initializing...");
  SerialTFMini.begin (TFMINI_BAUDRATE);

  //Initializing TFMini Sensors
tfmini.begin(&SerialTFMini);
}

void loop()
{
   int distance = 0;
  int strength = 0;

  getTFminiData(&distance, &strength);
  while(!distance) {
    getTFminiData(&distance, &strength);
    if(distance) {
      Serial.print(distance);
      Serial.print("cm\t");
      Serial.print("strength: ");
      Serial.println(strength);
    }
   }

delay(100);

}

First: Why are you including, declaring and initializing the library's tfmini object, if you then don't use it for reading the sensor?
Your problem will be, that you can only listen to exactly 1 SoftwareSerial interface at a time. If you listen to the first interface and the sensor on the second interface is sending something, you will miss that data.
I suggest, you switch the Uno for a board with more hardware Serial interfaces (which work via hardware, thus can work in parallel). The Arduino Mega for example has a total of 4 hardware Serial interfaces.
Though you might get away with the Uno when working with the external trigger mode. The TFMini library has an example named SingleReading. It sets the SingleScanMode in setup(). Then it issues an external trigger and then reads the sensor. I suggest trying the following: In your code you initiate all 3 TFMini objects with their respective SoftwareSerial object. Then in loop() you go through these 3 items, first calling listen() on the corresponding SoftwareSerial object. Then you issue the external trigger on the corresponding TFMini object and read the data from it. Then you go to the next SoftwareSerial interface and call listen() on it, and so on. The idea is, that with an external trigger you can control, when you will get a valid data frame. I'm not sure, if the sensor will also send some data between the triggers, but that data should just be discarded without any problem.
Note: I cannot test this idea, because I don't have the corresponding hardware. You will have to test that yourself.

I did try to use the Mega but I didn't even get one sensor to work .

@Soul Then you must have done something else wrong. You didn't show your code for the Mega, so I cannot say, what is the problem there. But of course you can try the external trigger mode with the Uno, as described above

I basically used the some code .

@Soul Then that is your problem. You cannot listen to multiple SoftwareSerial at a time, as described above. You need to change the code for the Mega, so that you use the Hardware Serial interfaces Serial1 to Serial4 and connect the TFMinis to the respective pins


text:
MKR ZERO is not detected in IDE / MKR ZERO not showing up in windows 8.1/
I m connect it with my IDE software and its work perfectly yesterday, but today morning I'm connected it to software to upload another sketch but its didn't detect the port and the charge led is not on yesterday but today is on. I tried every resolution which is given on website but its didn't work. please help me through this I'm new to this board.

Does this answer your question? Why is the IDE not able to find the board despite it being clearly seen and selected?

A few possibilities come to mind:

Your USB cable is bad.  Try a known good one.
Your USB port has failed.  Try a different port or try plugging something else into this one to verify that it's still OK.
Your MKR ZERO has become damaged somehow.


text:
How to use an Arduino Speaker module with DFPlayer Mini?
I've bought an Arduino speaker module. How should I connect the module, if I want to use it with DFPlayer Mini? The problem is that the speaker module has 3 pins: GND, VCC, and IN; though the DFPlayer Mini has 2 pins for connecting a speaker: SPEAKER + and SPEAKER -.

The DFPlayer already has an amplifier on it, so you can connect the speaker directly.
You can just leave out the board you bought from AliExpress, and only use the speaker.

Can I use the board with the DFPlayer? The DFPlayer has no filtering condensers, I'd like to use the ones bundled with the Speaker Module.

In that case you can use the DAC_R or DAC_L output of the DFPlayer, and connect that to the IN pin of your speaker amplifier board.

so I need to connect the board's GND to the player's GND, the board's VCC with the player's VCC, and the board`s IN with the player's DAC_R?

Yes. Though I'm still a bit puzzle why you'd want to go that route.

Gerben, do I need to run the startDAC command in my sketch?

I don't know. I don't think you have to change anything.


text:
Writing a 1Mb bitmap to an SDcard with only 96kB RAM
My goal is to have an Arduino Due (96 KB RAM) write a +-1MB bitmap to an SD card.
I have an array of a several coordinates on my Arduino Due and I would like to generate the bitmap where all the coordinates have a certain color and all the other pixels/background have another color.
I do have code to write a bitmap to an SD card (see below) but the problem is that the bitmap is dynamically generated and allocated in ram and then written to the SD card. So as soon as the bitmap I do want to write to the SDcard becomes bigger than the RAM available I get an error:
"xx.elf section '.bss' is not within region 'ram'.
Could anyone advice me on how to put parts of the bitmap in ram and write them to the sdcard one after another. Or would there maybe be another better approach?
#include <SPI.h>
#include <SD.h>

const int chipSelect = 10;

char name[] = "9px_0000.bmp";       // filename convention (will auto-increment)
const int w = 800;                   // image width in pixels
const int h = 400;                    // " height
const boolean debugPrint = true;    // print details of process over serial?

const uint32_t imgSize = w*h;
int px[w*h];                        // actual pixel data (grayscale - added programatically below)

File file;

const int amount_CT_samples = 20;
int Yarr[amount_CT_samples];
int Xarr[amount_CT_samples];

void setup() {

  // SD setup
    SerialUSB.begin(9600);
  while (!SerialUSB) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  SerialUSB.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    SerialUSB.println("initialization failed!");
    return;
  }
  SerialUSB.println("initialization done.");

  // if name exists, create new filename
  for (int i=0; i<10000; i++) {
    name[4] = (i/1000)%10 + '0';    // thousands place
    name[5] = (i/100)%10 + '0';     // hundreds
    name[6] = (i/10)%10 + '0';      // tens
    name[7] = i%10 + '0';           // ones
    file = SD.open(name, O_CREAT | O_EXCL | O_WRITE);
    if (file) {
      break;
    }
  }

  // set fileSize (used in bmp header)
  int rowSize = 4 * ((3*w + 3)/4);      // how many bytes in the row (used to create padding)
  int fileSize = 54 + h*rowSize;        // headers (54 bytes) + pixel data

  // create image data; heavily modified version via:
  // http://stackoverflow.com/a/2654860
  unsigned char *img = NULL;            // image data
  if (img) {                            // if there's already data in the array, clear it
    free(img);
  }
  img = (unsigned char *)malloc(3*imgSize);

  for (int y=0; y<h; y++) {
    for (int x=0; x<w; x++) {
      int colorVal = px[y*w + x];                        // classic formula for px listed in line
      img[(y*w + x)*3+0] = (unsigned char)(colorVal);    // R
      img[(y*w + x)*3+1] = (unsigned char)(colorVal);    // G
      img[(y*w + x)*3+2] = (unsigned char)(colorVal);    // B
      // padding (the 4th byte) will be added later as needed...
    }
  }

  // create padding (based on the number of pixels in a row
  unsigned char bmpPad[rowSize - 3*w];
  for (int i=0; i<sizeof(bmpPad); i++) {         // fill with 0s
    bmpPad[i] = 0;
  }

  // create file headers (also taken from StackOverflow example)
  unsigned char bmpFileHeader[14] = {            // file header (always starts with BM!)
    'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0   };
  unsigned char bmpInfoHeader[40] = {            // info about the file (size, etc)
    40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0   };

  bmpFileHeader[ 2] = (unsigned char)(fileSize      );
  bmpFileHeader[ 3] = (unsigned char)(fileSize >>  8);
  bmpFileHeader[ 4] = (unsigned char)(fileSize >> 16);
  bmpFileHeader[ 5] = (unsigned char)(fileSize >> 24);

  bmpInfoHeader[ 4] = (unsigned char)(       w      );
  bmpInfoHeader[ 5] = (unsigned char)(       w >>  8);
  bmpInfoHeader[ 6] = (unsigned char)(       w >> 16);
  bmpInfoHeader[ 7] = (unsigned char)(       w >> 24);
  bmpInfoHeader[ 8] = (unsigned char)(       h      );
  bmpInfoHeader[ 9] = (unsigned char)(       h >>  8);
  bmpInfoHeader[10] = (unsigned char)(       h >> 16);
  bmpInfoHeader[11] = (unsigned char)(       h >> 24);

  // write the file (thanks forum!)
  file.write(bmpFileHeader, sizeof(bmpFileHeader));    // write file header

}

void loop() { }

UPDATE
With the following code my problem was solved.
Credits to those who answered my question below!
#include <SPI.h>
#include <SD.h>
const int chipSelect = 10;

struct Pixel {
    uint8_t r, g, b;
};

char name[] = "CT_0000.bmp";       // filename convention (will auto-increment)
const int w = 800;                   // image width in pixels
const int h = 400;                    // " height
const boolean debugPrint = true;    // print details of process over serial?

const uint32_t imgSize = w*h;
int px[w*h];                        // actual pixel data (grayscale - added programatically below)

File file;

const int amount_CT_samples = 50;
int Xarr[amount_CT_samples];
int Yarr[amount_CT_samples];

Pixel getPixel(int x, int y) {
    const Pixel black = {0, 0, 0},
                green = {0, 255, 0};

    for(int i=0; i < amount_CT_samples; i++){
      if(Xarr[i] == x && Yarr[i] == (h - y))return green;
    }
    return black;
}

void writeBitmap(File &file, int w, int h) {
    size_t rowSize = 4 * ((3*w + 3)/4);  // padded to multiple of 4
    size_t fileSize = 54 + h*rowSize;    // includes header

    // Write image header.
    uint8_t header[54] = {
        // File header.
        'B','M',
        (uint8_t)(fileSize >>  0),
        (uint8_t)(fileSize >>  8),
        (uint8_t)(fileSize >> 16),
        (uint8_t)(fileSize >> 24),
        0,0, 0,0, 54,0,0,0,

        // Image info header.
        40,0,0,0,
        (uint8_t)(w >>  0),
        (uint8_t)(w >>  8),
        (uint8_t)(w >> 16),
        (uint8_t)(w >> 24),
        (uint8_t)(h >>  0),
        (uint8_t)(h >>  8),
        (uint8_t)(h >> 16),
        (uint8_t)(h >> 24),
        1,0, 24,0
    };
    file.write(header, sizeof header);

    // Write image data.
    uint8_t row[rowSize];
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            Pixel pix = getPixel(x, y);
            row[3*x + 0] = pix.b;
            row[3*x + 1] = pix.g;
            row[3*x + 2] = pix.r;
        }
        file.write(row, sizeof row);
    }

    file.close();
}

void setup() {
    Serial.begin(9600);
    Serial.print("Initializing SD card...");

    //create dummy X and Y points
    for(int i = 0; i < amount_CT_samples; i++){
        Xarr[i] = i;
        Yarr[i] = i;
    }

    if (!SD.begin(chipSelect)) {
      Serial.println("initialization failed!");
      return;
    }
    Serial.println("initialization done.");

  // if name exists, create new filename
  for (int i=0; i<10000; i++) {
    name[3] = (i/1000)%10 + '0';    // thousands place
    name[4] = (i/100)%10 + '0';     // hundreds
    name[5] = (i/10)%10 + '0';      // tens
    name[6] = i%10 + '0';           // ones
    file = SD.open(name, O_CREAT | O_EXCL | O_WRITE);
    if (file) {
      break;
    }
  }

  Serial.println("start writing bitmap.");
  writeBitmap(file, w, h);
  Serial.println("done writing bitmap.");

}

void loop() { }

Would it be doable to create and write the headers first, and then generate the image row by row, and save each row to to the SD card before generating the next one? Should be under 3kB/row. The for loops suggest this could be doable. Don't know where the padding goes, though. Also, maybe you could generate directly to the flash memory instead of to the RAM, but I don't know what can be done there on the Due.

@ocrdu, thanks for your comment. Indeed a line by line write or a direct write to flash would solve my problem. But I don't know how I could practically implement this.

Well, roughly, you would use a int px[] the size of one row, fill it in the inner for loop, so for one value of h, then write it to the SD card at the end of the outer for loop, and then do the same for the next row i.e. the next h in the outer loop. Grofweg.

Thanks this is indeed a good idea!

You can write the file in chunks. As suggested by ocrdu in a comment,
writing line by line is a good strategy. In order to keep the complexity
of the code manageable, I would put the logic of deciding the color of a
pixel in its own function, and use another function for managing writing
the bitmap. For example:
struct Pixel {
    uint8_t r, g, b;
};

// Dummy example. Replace with your own logic.
Pixel getPixel(int x, int y) {
    const Pixel black = {0, 0, 0},
                green = {0, 255, 0};
    if (((x - y) & 0x0f) == 0) return green;
    return black;
}

void writeBitmap(File &file, int w, int h) {
    size_t rowSize = 4 * ((3*w + 3)/4);  // padded to multiple of 4
    size_t fileSize = 54 + h*rowSize;    // includes header

    // Write image header.
    uint8_t header[54] = {
        // File header.
        'B','M',
        (uint8_t)(fileSize >>  0),
        (uint8_t)(fileSize >>  8),
        (uint8_t)(fileSize >> 16),
        (uint8_t)(fileSize >> 24),
        0,0, 0,0, 54,0,0,0,

        // Image info header.
        40,0,0,0,
        (uint8_t)(w >>  0),
        (uint8_t)(w >>  8),
        (uint8_t)(w >> 16),
        (uint8_t)(w >> 24),
        (uint8_t)(h >>  0),
        (uint8_t)(h >>  8),
        (uint8_t)(h >> 16),
        (uint8_t)(h >> 24),
        1,0, 24,0
    };
    file.write(header, sizeof header);

    // Write image data.
    uint8_t row[rowSize] = {0};
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            Pixel pix = getPixel(x, y);
            row[3*x + 0] = pix.b;
            row[3*x + 1] = pix.g;
            row[3*x + 2] = pix.r;
        }
        file.write(row, sizeof row);
    }
}

Then after opening the file, you just have to:
writeBitmap(file, 800, 400);

Note that the getPixel() function above is just a dummy example that
draws green diagonal lines across the image. See timemage's answer for
ideas on how to implement your own pixel-generating function.

@SvenOnderbeke, this is a good starting point for you.  Just so you're not caught off guard, I wanted to mention that the BMP format stores its images in a way that most of us would call up-side-down.  The rows appearing first in the file are content that appears at the bottom of the image when displayed.

Perfect, thanks a lot! This answer solved my problem, I also edit my question so it now contains the solution.

Normally I'd write this a differently, but I've kept in relatively simple just to illustrate the basic idea:
struct point {
  int x;
  int y;
};

const point points_of_interest[] = {
  { 7, 11},
  {23, 17},
  {13, 19},
  { 3,  5},
  {17,  3},
};

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

void loop() {
  delay(4000);
  Serial.println("\n\n\n");

  for (int i = 0; i < 24; ++i) {
    for (int j = 0; j < 24; ++j) {
      bool coordinate_of_interest = false;

      for (const auto poi: points_of_interest) {
        coordinate_of_interest = j == poi.x && i == poi.y;
        if (coordinate_of_interest) {
          break;
        }
      }

      if (coordinate_of_interest) {
        Serial.print("XX");
      } else {
        Serial.print("..");
      }
    }

    Serial.println();
  }
}

It's printing a 24x24 or 576 "pixel" grid.  But only five coordinates are stored.
It would matter if it were a 2400x2400 grid, but it would not print nicely on a maximized Serial Monitor for example purposes.
With your bitmap, you could get more sophisticated.  E.g. checking that distance (or more efficiently distance squared; no sqrt() operation) from the pixel under consideration (i, j) to any point in the list is less than or equal to some amount, and coloring based on that.  This would result in solid circles centered on your points in your bitmap.  Or color gradient around the point if you base the color on the distance.
If you have a lot of points you will need to do something like sort them by their vertical coordinates and advance an index that represents the points on or below your horizontal sweep line, etc.  That is, if you have a lot of points you don't want to have to be taking the distance to all of them for every pixel under consideration.

Thank you for that advice! The solutions given here really helped me to generate the code I needed. (I edited my question so it now contains the solution).

@SvenOnderbeke, Nice.  If this was actually helpful you can mark it up.  But as I understand it, it is fitting that you should mark Edgar's answer as "accepted" because you have described it as solving your problem.


text:
Is it possible to have long wire connections from an NodeMCU to a servo motor or button?
For my proyect, I need to conect my NodeMCU to a servo motor as well as a push button, the thing is, the distance from the NodeMCU and both components has to have a distance of around 6.10 meters (or 20.0131 feet), I dont know if it is possible to do this connection, I worry if the pwm signal or the voltage would drop by the time it reached either component. I havent been able to try this because I dont have long enough cables to do the connections. In the case that it would be possible, what type of cable should I use and should I add something extra to the circuit to make it work better? Thanks.

use the long wire for the pushbutton part of the circuit ... use it to activate the LED of an opto-isolator .... basically, pressing the button lights an LED at the arduino ... you can use a battery to run the opto-isolator or use power from the arduino ... adjust the LED series resistor to obtain a good signal

you could use additional nodeMCUs, they are cheap and wireless.

I would suggest a pull up resistor forcing at least 1 mA or more of current through the switch contact. This helps keep the switch contact clean if it is not rated for dry switching. Then from the junction of the pull up resistor put a 20 - 100K resistor in series with your input pin. You can also add a 100nF cap between the input and ground to kill noise. This forms a low pass filter and denounces some of the switch noise. The other wire to the switch will be ground.  I did this a lot with 12/24VDC control systems. If you do several inputs check your currents and be sure you do not over power the Arduino. This will forward bias the top input protection diode pushing current into the Arduino VCC. The inputs are typically rated at 20mA but check to be sure yours is rated properly.

A push button won't be a problem. That is a very simple change in resistance from open circuit to a few ohms. You just need a low enough resistance to force the voltage coming through weak internal pullup resistor down to ground. It looks like 22 gauge wire has about 52.7 ohms / 1000 meters.
I don't think 6 meters of 22 gauge wire will be a problem for a 5V PWM signal either. If it's a very electrically noisy environment you might want to use shielded or twisted pair cable, but it seems unlikely that would be needed.


text:
Arduino sketch uses too much memory storage space?
I've never used arduino before but am using one for a school project. I am using an arduino leonardo and I've uploaded the sample code below
#include "Adafruit_CCS811.h"
Adafruit_CCS811 ccs;

void setup() {
    Serial.begin(9600);
    Serial.println("CCS811 test");
    if(!ccs.begin()){
        Serial.println("Failed to start sensor! Please check your wiring.");
        while(1);
    }

    //calibrate temperature sensor
    while(!ccs.available());
    float temp = ccs.calculateTemperature();
    ccs.setTempOffset(temp - 25.0);
}

void loop() {
    if(ccs.available()){
        float temp = ccs.calculateTemperature();
        if(!ccs.readData()){
            Serial.print("CO2: ");
            Serial.print(ccs.geteCO2());
            Serial.print("ppm, TVOC: ");
            Serial.print(ccs.getTVOC());
            Serial.print("ppb Temp:");
            Serial.println(temp);
        } else {
            Serial.println("ERROR!");
            while(1);
        }
    }
    delay(500);
}

But when I upload it, all I see a message that states
Sketch uses 8830 bytes (30%) of program storage space. Maximum is 28672 bytes.
Global variables use 487 bytes (19%) of dynamic memory, leaving 2073 bytes for local variables. Maximum is 2560 bytes.

Does this mean there is not enough storage in my computer or is there not enough space in the arduino? This arduino was given to me second hand.
I'm unsure if it is now appropriate to be able to see results show up on the serial monitor? Because nothing is showing up.

Where it is a Leonardo, you may want to put while (!Serial) {} immediately following your Serial.begin.  This will essentially wait until the Serial monitor establishes a connection so that you are not losing any diagnostic messages.

Please read your problem carefully. It says that your program uses 30% of your space and 19% of dynamic memory. You are nowhere close to full. @jwh20 answered it perfectly.

There is no problem here, please read the message carefully!
It says you are ONLY using 30% of the available program memory and 19% of the dynamic memory.
You have a LOT more room left.

So is this not a real error message then? This should show up after every upload? I'm unsure whether to tell if it was successful because there are no data values that show in the serial monitor.

This is not an error message.  It's an informational message.  Yes, this will show up after every upload to the Arduino.

As far as nothing showing up in the serial monitor, that's another issue altogether.  Perhaps you should try one of the simpler examples as a starting point to help get yourself familiar with the Arduino and its toolchain?  The Blink Example is a good place to start.

@jwh20 your comment about the message showing after an upload is incorrect ... the message shows at the end of the code compile process .... the upload happens afterward

Thanks for the clarification.  It's too late to edit the comment.

What you are seeing there is not an error message, it is only for information. It shows how much memory you have left on the Arduino.

Sketch uses 8830 bytes (30%) of program storage space. Maximum is 28672 bytes.

This is about the program storage, also known as flash storage (which is the type of storage technology used here). It is, where the actual program is saved, and is non-volatile (which means, that it holds the data/your code even during power loss). The message tells you, that the Arduino Leonardo has a total of 28672 bytes of storage for your program. When you write bigger programs, you will also use more of the flash/program storage. That means, that the size of the flash/program storage (which is a hardware limit in the microcontroller) gives you an upper limit to the size of the compiled program, as it cannot be more than 100% of the maximum given there and still upload. Though note, that the compiler does a lot of optimization to your code, so there is no easy relation between C/C++ code size and compiled code size. You need to actually compile your code to see, what size it will be and if it fits onto your Arduino. And that is exactly, what this message is meant for.
The message tells you, that you are using 30% of the flash/program storage. Thus you are very well inside the limits.

Global variables use 487 bytes (19%) of dynamic memory, leaving 2073 bytes for local variables. Maximum is 2560 bytes.

The second line is about the memory, where variables are stored, aka dynamic memory aka RAM. Of course this means the RAM inside of the Arduino. The RAM is volatile, which means, that every data in it will vanish, when the Arduino is powered off or reset.
Every time, that you declare a variable in your code, this variable is put into the RAM. Calculating the maximum amount of RAM, that will be used in your code, is rather complex, as variables are created and destroyed very often, when calling functions or other programming constructs. But global variables (the ones declared outside of any function) are created right at the start of the program, thus the compiler can easily calculate their size.
This message gives you a hint, if you are going to run out of RAM with your program. It is only a hint. Because of that, the compiler will show a warning at that point, if you are going in the realm of 75% or higher of the available RAM, that this might not leave enough room for local variables and thus risks instability in the program. (Note, that I'm not sure about the exact limit, from which on the warning is displayed. You may try to research this detail).
When you program runs out of RAM, it will fail or producing instability. So you want to prevent that from happening. Currently you are at 19%. Also you are using few local variables, so you are save here.

I'm unsure if it is now appropriate to be able to see results show up on the serial monitor? Because nothing is showing up.

You should at least be able to see the message CCS811 test on the Serial monitor. If not, please make sure, that you really uploaded the code (by clicking on the upload button, not on the verify button). In the preferences you can turn on verbose output for compilation and upload, to find possible problem sources. Also make sure, that you chose the correct port and that your Serial Monitor is configured for the same baudrate as your sketch (in this case 9600 baud).
If that still doesn't give any output at all, try to upload the Blink example, that you can find in the Arduino IDE in the menu under examples -> Basics. If it uploads successfully, watch, if the buildin LED starts to blink. If yes, that code is working correctly.
If the init message is showing up, but the temperature values are not, you need to first check for your connections. Then you could try to upload the standard I2C scanner sketch, that shows you, what devices can be found on the I2C bus and what addresses they have.


text:
Error compiling for board NodeMCU 1.0
i tried compiling a program to upload sensor readings that i connected with my ESP8266 to cloud (in my case, Antares) but i keep getting this error message. Can anyone tell me where the problem is, and what do i need to do to get it fixed ?
At first i thought it was because come incompatibility with my older version of Arduino IDE, so i updated to the latest version of it, but nothing changed.
Im kinda new here, so any suggest might help. Thank you!
Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, 115200, 4M (3M SPIFFS)"
C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::get(String, String)':
C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:202:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'
 bool res = client.setCACert_P(caCert, caCertLen);

                   ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:222:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'
 if (client.verifyCertChain(_serverNoHttp)) {

            ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'String AntaresESP8266HTTP::getRaw(String, String)':
C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:274:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'
 bool res = client.setCACert_P(caCert, caCertLen);

                   ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:294:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'
 if (client.verifyCertChain(_serverNoHttp)) {

            ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::send(String, String)':
C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:439:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'
 bool res = client.setCACert_P(caCert, caCertLen);

                   ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:459:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'
 if (client.verifyCertChain(_serverNoHttp)) {

            ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::sendRaw(String, String, String)':
C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:512:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'
 bool res = client.setCACert_P(caCert, caCertLen);

                   ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:532:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'
 if (client.verifyCertChain(_serverNoHttp)) {

            ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::getLatestTest(String, String)':
C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:688:40: error: no matching function for call to 'WiFiClient::connect(String&, uint16_t&)'
 if(client.connect(_server, _portNum)) {

                                    ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:688:40: note: candidates are:
In file included from C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:39:0,
             from C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.h:5,

             from C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:1:

C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:47:15: note: virtual int WiFiClient::connect(IPAddress, uint16_t)
virtual int connect(IPAddress ip, uint16_t port);
           ^

C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:47:15: note:   no known conversion for argument 1 from 'String' to 'IPAddress'
C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:48:15: note: virtual int WiFiClient::connect(const char*, uint16_t)
virtual int connect(const char *host, uint16_t port);
           ^

C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:48:15: note:   no known conversion for argument 1 from 'String' to 'const char*'
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

please format the printout ... put these three symbols  ``` on a blank line before the printout ... same after the printout ... make sure that there is nothing else on the line

check the esp8266 core version in Boards Manager

As noted by @Jurajj, You’re working with an old ESP8266 Core version (2.3.0 is from 2016). Update it and try again (and it would be nice if you could report back here).

It turned out that the ESP8266 core version that i had installed is obsolete, so i installed the esp8266 core version 2.7.4 and the compiling works just fine. Thank you so much everyone for the help ! :D


text:
ESP32 feedback from NTP
The basic example for ESP32 NTP is very rough:
void setup() {
  Serial.begin(115200);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

But it tells nothing about the success of the operation.
I need to know if it was able to update the time from the NTP server. Is there a method to know that?
I can't rely on the time struct because I must init it manually at startup, say to 1st Jan 2020 00:00.

Out of curiosity: why is the time set manually at startup, when you will be updating it using NTP anyway?

Because if the NTP is not reachable (i.e. no WiFi connection) the system must begin anyway the operations. The user can set the default datetime value for this scenario.

Did you follow that manual?
https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/
The printLocalTime(); function does all you ask for.
void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

getLocalTimereturns false on failure. Let the printLocalTime do the same.
boolean printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return false;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
  return true;
}

Now the print function tells you if it failed (returns false) or not (returns true).

Please, look at the implementation of getLocalTime(). It just checks if the year if < 2016. But I said at power up I set the current time to a specific value (i.e. 1/1/2020). So I cannot rely on this. I need to know whether the NTP was ok or failed.

@Mark Sorry I completely misunderstood your problem. I also interpreted the code completely wrong. My answer does not fit to your question. I now have looked into the Arduino ESP code and probably there is a chance to find out if the time had formerly been set by a NTP Server call. But actually I have no time to evaluate that. I'll change my answer as soon as I could investigate a little bit. Hint: sntp_sync_status_t sntp_get_sync_status(void); in arduino-esp32/tools/sdk/include/lwip/sntp.h In any case the answer ocrdu gave is worth to try and should be the accepted answer if it works.

I'm not entirely sure there is a good solution for that with the normal ESP32 library, as it only checks to see if a valid year has been set, and the user has already set a valid year.
You could try using the NTPClient library or a similar one to get the time; its functions do a different check and actually return TRUE or FALSE.
On success, you can then use the newly retrieved time value to update the ESP32's RTC.

I'm going to try this solution, hoping the ESP32 framework is compatible with this library.

@Mark: I had a quick look at the code, and looks like it is compatible with all the Arduino-esk WiFi libraries. No guarantees, though 8-). I wonder why somebody downvoted my answer. Oh well. Please accept the answer so the question doesn't remain open. If it works and you actually do accept the answer, of course.

I upvoted your answer. To accept one of the answers I'm going to test them before.


text:
Standalone ATmega clock continuous lifetime
Here I have made a standalone ATmega328p clock without
any RTC module using the breadboard ATmega328p , LCD I2C , and some buttons which I would like to turn on for atleast an year (supposed to be without any reset or power-interrupts).
I am powering my ATmega using an old mobile charger (5v , 500mA) of a old broken Android.
However I am not using any millis() or something alike these in the clock code,
So how long will my clock run if is it supposed to be online 24/7
Should I reset it sometimes?
If yes , when, after how many days should I reset it?
And do I need a coolant system for it? (I guess not)
Thanks for your precious time .

I like to enable the watchdog timer inside the ATMega328, so that, if my code ever hangs, the mcu will reset itself.

@Gerben, can u please give me the board manager link for bootloading 8mhz internal clock in Atmega328p u

You can use the bootloader used for the 8Mhz 3.3V Arduino Pro mini, but alter the fuse settings so it uses the internal oscillator, instead of a crystal. I hope that helped. Otherwise, create a new question so everyone can help you, instead of just me.

So how long will my clock run if is it supposed to be online 24/7

Until you turn it off or a stray neutrino corrupts the flash memory, or the flash memory degrades (20-100 years or so depending on temperature).

Should I reset it sometimes? If yes , when, after how many days should I reset it?

No.

And do I need a coolant system for it? (I guess not)

No. Not unless it's in a sealed container with no ventilation and a hot environment.
However
Your RTC-less "clock" will probably not be particularly accurate, unless you have some external source of time (NTP, GPS, etc) as the Arduino's internal timing is not very accurate, and built on a breadboard it's even less so due to excess stray capacitance.

My standalone ATmega clock runs 1 min slower than original clock (till yet), I have used 5 buttons for fixing them manually. If I don't touch it for 5-7 days, will the time of ATmega run more slowly or will continue this 1 minute difference from RTC in future?

Yes. It will do one of those. That's as accurate as I can be. Only time will tell.

What do u mean by one of those? Please clear it to me

I can't be clear. There is no answer. The clock will either run fast (gain time), run slow (lose time) or run the same (keep time). It is impossible to know what until you actually run the clock and measure the time. It is far more likely to drift over time that be the real time, but will it run fast or slow? That's not possible to know without measuring it.

Thank you for your kind answer :)

Interesting. Atmel's flash-based "ATmega" microcontrollers typically promise retention times of 20 years at 85 °C (185 °F) and 100 years at 25 °C (77 °F). I didn't know that.

Two additional points if I may. First, don't expect two Arduinos to run at the same speed, particularly if they are clocked by a resonator rather than a crystal. Second, avoid all dynamic memory allocation since unless carefully organised you will eventually have a fragmented heap and things will no longer work as you intend.


text:
Recommendation for a projector module or approach?
I am looking to create a projector effect similar to one seen in projector alarm clocks like
https://www.amazon.com/Mooas-White-Projection-Alarm-Projector/dp/B07Q6W53LK/ref=asc_df_B07Q6W53LK/?tag=hyprod-20&linkCode=df0&hvadid=343191208006&hvpos=&hvnetw=g&hvrand=4354131467724049360&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9019795&hvtargid=pla-758051396522&psc=1&tag=&ref=&adgrpid=68752454603&hvpone=&hvptwo=&hvadid=343191208006&hvpos=&hvnetw=g&hvrand=4354131467724049360&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9019795&hvtargid=pla-758051396522
and I am looking for some module that would accomplish it
https://www.mouser.com/ProductDetail/Texas-Instruments/DLPDLCR2000EVM?qs=BZBei1rCqCAQetmBz0G1xQ%3D%3D&gclid=Cj0KCQiA-rj9BRCAARIsANB_4ABW01iyq1W96Kd3piCLku3MSKib7xc_TspaZIa364hTXtJ_kYPSg0AaAvSAEALw_wcB
This is the closest thing I can find to what I am looking for but it's very pricey I would think given how popular these sorts of alarm clocks are there would be something much cheaper and easy to get your hands on out there.

This isn't an Arduino question. It would be a better fit in one of the electronics forums.

Retail consumer products have economies of scale working for them. A designer can spend the money to configure a factory to build a consumer product, and then spread that setup cost over millions of units. My guess is that the projected alarm clock you show is a bright LCD or LED display and a simple lens to project it's image. A general-purpose DLP projector like the one you linked is a much more sophisticated product.

These alarm clocks often only have a bright 7 segment LED display, which is then projected by a simple lens. Or maybe a simple custom LCD display, which is then backlight by a bright LED. The linked product from mouser is a complete DLP display with 640x320 pixels. Thats just different technology in a different league

Buy the alarm clock and scavenge the parts you need from it.

Except that I bet those alarm clocks have custom LCD displays that can only display the time, plus a few custom graphics, and nothing else. I very much doubt if they are general-purpose raster displays. If you find an alarm clock that has the display you want, great.

"These alarm clocks often only have a bright 7 segment LED display, which is then projected by a simple lens. Or maybe a simple custom LCD display, which is then backlight by a bright LED." Ok well can you link to parts or explain how I would go about doing that?

As written in the comments, the linked projector is a DLP  projector with 640x320 pixels. Of course, that is expensive. It is a complete pixel display, which can display anything (with the max resolution of 640x320). That is way more, than the projector watches.
The watches often use one of two possibilities:

A bright 7 segment LED display, which is projected to the wall via a lens. The seven segment display needs to be bright enough, depending on the intended brightness of the projection and how big the projected image should be.

An LCD display, which is illuminated from behind by a bright LED. That is then also projected to the wall with a lens. I would guess, that this is, what the linked watch is doing.

How to build that yourself? You can always salvage one of these watches. But when building it yourself, you should also follow one of the above possibilities. Which one depends on your requirements.
Using a standard 7 segment display will be the easiest. Though that might be not bright enough. You could look for especially bright 7 segment displays and test, if that is enough for you.
The second possibility would be more hacky. Most LCD displays, that you can buy, have a LED lit plane in the back as a backlight. You would need to remove that plane, so that the display gets transparent. Also you most likely would need to rotate the polarizing filter on the top of the LCD, because as standard a driven segment of the LCD gets more opaque, while you want it to get transparent. A new filter (up to a few cm) can be salvaged from the passive 3D glasses from a movie theater.
In both cases you install the display inside a tube together with a fitting lens. Look, what you can get from your location and then experiment with it.

can you link to parts

No, we are not really doing that here, because that is really dependent on your location, on your price- and other requirements. Also such part suggestions are usually very fast outdated. But you can look at the electronics shops, that you have at your location and search there for the general description of the parts (for example "7 segment display").

What material are you salvaging from 3d glasses? What sort of lense would I want? I was mostly asking about links to parts as a reference not necessarily a shopping list. I don't know how meaningful of a conversation we can have about this with talking about specific parts.

As reference: search at amazon for "7 segment display" and for "convex lens". I have no other reference for you. What I described is only an idea for the general concept. You still have to design the project itself. Google for unterstanding simple optics with lenses and decide based on that, what lens you need. Similar with the display. There you can also choose beween ready to use modules or the pure displays, which you then would need to drive with extra chips.

For the 3D glasses: I mean the cheap 3D glasses, that you get at the movie theater for 1 or 2€. The ones with just a thin foil instead of glas lenses. Like this one These are polarizing filters, which you can cut out of the frame. But you can also buy polarizing filters.


text:
Joy-IT RS232 Shield and RS232 voltage levels
First of all, sorry if this is a dumb question, but I'm pretty new to the whole Serial RS232 concepts.
I do have an Arduino Board that, from what I read about, is not able to communicate via RS232 because of different levels.
My question now is: If the Joy-IT RS232 Shield will make up for that. So is this shield handling the RS232 level shift? I don't really know what to look for so I am asking here.
Thanks!

Yes, that shield will handle the level shifting for you. If you look closely at the images of the shield, you see the MAX232 chip, which is a commonly used chip for getting UART (which is the Serial interface of the Arduino) to speak over RS232.
And yes, RS232 uses different voltage levels. The UART on a microcontroller usually uses the voltages 0V and 5V (or 3.3V depending on  it's supply voltage), which is also called TTL levels (Transistor-Transistor Logic), while RS232 mostly works with +-10V (though different voltages are also inside the standard). You see, that this is a symmetrical voltage around ground (0V).

Wow thanks for the detailed answer! Then this shield is exactly what I need for my project.


text:
L298N regulated output is greated than 5V
A few months ago I used a L298N module (actually the Velleman VMA409) and I managed to make my motors working fine.
However now that I want to reuse it for another project something seems off: The regulated 5V output is always equal to the 16V VMS input.
To give more details:

I'm powering the board with 4x 3.7V 18650 batteries in series for an input of about 16V. This should be OK since according to the specs the range for VMS is 5V-35V
I'm reading the output value on the two pins I marked with an arrow in the following picture (using both of the GND pins) and in all cases I get about the same value as what I have on VMS.
This is when I have the 5V_EN jumper in place, if I remove it I get no output at all (Which I think is normal, since that disable the internal regulator)
For now I haven't connected my arduino because I want to understand what's going on before, so the Inx and EnX pins are connected to nothing.

So my questions are:

Is it indicating that I somehow fried my driver board?
Can I get back this 5V regulated output?

Does the LED go on with only VMS connected and the 5V_EN jumper in place?

your question is not about an arduino, so it is off topic here

It's more of an EE question, yes. If you ask it there, here is a link to the schematic: https://www.velleman.eu/downloads/29/infosheets/vma409-schematic.pdf

Sounds like the regulator has "failed short"

@ocrdu The LEDs do go on with only VMS connected and the jumper in place. But I'm not sure what that would mean? @ Majenko: What would be the consequences of the failing regulator: Is it still safe to use the module if I don't rely on the 5V output? Also how can I have fried this regulator?

The LED is fed by the 5V regulator in that configuration, if it were getting 16V it would probably fry, so the regulator could still be working. Just a check. Don't get why you are seeing 16V on the 5V out though. Can you measure the voltage on the 7805 output pin?

You are making an incorrect assumption, the L298N is an "H" bridge driver for small motors, not a 5V power supply. The 5 volt output is provided by a separate 78L05 regulator on the module.  This regulator cannot supply much power. Take a look at the schematic link given to you by ocrdu. Be sure all the grounds are connected.


text:
Sim800L-v2.0-network-problem
I am having trouble to get Sim800L-v2.0 to work. I believe that I am supplying the necessary amount of current (5.0V, 2.1A máx power source, using solid copper wires - circuit photo). The Net LED keeps blinking every second, meaning that it was unable to connect to the network.
Serial monitor readings:
15:57:32.630 -> AT
15:57:32.630 -> OK

16:02:15.391 -> at+cops=?
16:02:23.775 -> +COPS: ,(0-4),(0-2)
16:02:23.775 ->
16:02:23.775 -> OK

16:02:29.075 ->  AT+CPIN?
16:02:29.075 -> +CME ERROR: SIM not inserted

16:02:51.008 -> AT+CREG?
16:02:51.008 -> +CREG: 0,0
16:02:51.008 ->
16:02:51.008 -> OK

16:02:59.639 -> AT+CSQ
16:02:59.639 -> +CSQ: 0,0
16:02:59.639 ->
16:02:59.639 -> OK

16:08:09.354 -> +CFUN: 1
16:08:09.354 ->
16:08:09.354 -> OK

Inspecting the readings, it indicates that the sim card is not inserted at all, which is odd. While searching for some tips on the subject, I did encounter one or another claiming that the problem might be related to the incorrect capacitor used in the circuit module, not really sure though...
Any ideas to solve the issue? Is it a module problem, or am I missing some steps?
Thanks in advance!

#include <SoftwareSerial.h>

//Porta do Arduino onde o pino TX do Módulo GSM esta conectado
#define TX_PIN 10

//Porta do Arduino onde o pino RX do Módulo GSM esta conectado
#define RX_PIN 11

//Cria comunicacao serial via software nas portas digitais definidas acima
SoftwareSerial serialGSM(TX_PIN, RX_PIN);

void setup() {
  //Begin serial comunication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);
  while(!Serial);

  //Inicia comunicacao serial com o GSM
  serialGSM.listen();
  serialGSM.begin(9600);
  delay(1000);

  Serial.println("Setup Completo!");
}

void loop() {
  //Le as mensagens vindas do GSM para escrevê-las no monitor serial
  if(serialGSM.available()){
    Serial.write(serialGSM.read());
  }

  //Le as mensagens vindas do monitor serial para copiá-las para o GSM
  if(Serial.available()){
    serialGSM.write(Serial.read());
  }
}

Where are you and what network are you trying to use?

Europe, SIM card is 4g I guess, but some claim that it can switch to 2g and 3g

What network? Some networks no longer provide GSM.

I am not sure I understand, will you kindly explain? Where can I get the network you're refering to? Thanks

You should already know that information. Who did you get the SIM from? T-mobile? Vodafone? And which country specifically are you in, since the networks vary from country to country.

Ah sorry, We give it another name, that is why I got confused...I tried with Meo/Altice.Country: Portugal

Ok, that's all fine. MEO provides E-GSM (900MHz) and DCS (1800MHz) which the 800L works with. That rules that out.

Any idea why it does not work?

Not at the moment. You've exhausted my go-to answers so far...

Can you please add the code? This would make it a bit easier.

I added the code at the end of the topic, thanks.

Did you put the SIM in correctly? It will also seat on some of these boards when it is 180° off.


text:
Can't change pins in AM2320 code, types mismatch
I took a simple A2320 temperature sensor and connected it not to  A4/A5, but to A1/A0 pins. SDA => A1, SCL => A0. (In C code they are number 15 and 14). But I can't call the library to take these pins.
The basic example from the library uses the default values, probably from some tutorial.
I read the .h and .cpp files and see these definitions:
Adafruit_AM2320::Adafruit_AM2320(TwoWire *theI2C, int32_t tempSensorId,
                                 int32_t humiditySensorId)
    : _temp(this, tempSensorId), _humidity(this, humiditySensorId),
      _i2c(theI2C) {}

bool Adafruit_AM2320::begin() {
  _i2caddr = 0x5C; // fixed addr
  _i2c->begin();
  return true;
}

I just tried to make types match. Not even port number.
I declared a TwoWire instance and passed it to AM2320 constructor, but without success:
#include "Wire.h"
...
TwoWire mywire();
Adafruit_AM2320 am2320 = Adafruit_AM2320(mywire, -1, -1); // as the default values

Outputs in error log:
error: no matching function for call to 'Adafruit_AM2320::Adafruit_AM2320(TwoWire (*)(), int, int)'
    Adafruit_AM2320 am2320 = Adafruit_AM2320(&mywire, -1, -1);
In file included from testproj.ino:2:0:
...Adafruit_AM2320.h:52:3: note: candidate: Adafruit_AM2320::Adafruit_AM2320(TwoWire*, int32_t, int32_t)
   Adafruit_AM2320(TwoWire *theI2C = &Wire, int32_t tempSensorId = -1,
   ^~~~~~~~~~~~~~~
...Adafruit_AM2320.h:52:3: note:   no known conversion for argument 1 from 'TwoWire (*)()' to 'TwoWire*'

What am I doing wrong?

Two problems:

When you create an object instance with no parameters you must not have parentheses. You should construct thus:

TwoWire mywire;

The constructor expects a pointer to an object, not an object. Just take the address of the object with & and pass that:

Adafruit_AM2320 am2320 = Adafruit_AM2320(&mywire, -1, -1); // as the default values

However
Most Arduino boards have the I2C pins hard-wired internal to the chip and can't be changed. You would need to use some form of software implementation that is also a polymorphic child of the TwoWire class. If such a thing exists.


text:
Unable to use analog pins as digital inputs
I want to use the analog pin A7 as a digital input pin. As stated in the Arduino docs the analog pins can be configured in the same way like any other digital pin.
However, when trying to configure an analog pin as a digital input pin, I get unexpected behaviour:

Using a digital pin (e.g. D2) works as expected.
When using an analog pin (e.g. A7) the LED is lit after start-up without pressing the button and does not change/react to any button press.
Since the docs state, that analog pins can be configured as digital pins and used in the same way, this behavior seems to be kind of confusing.

See my attached snippet to reproduce/examine the issue:
// using pin 2 (D2) works as expected (LED is lit on button press only)
// const int buttonPin = 2;

// using analog pin 7 (A7 / pin 21) as a digital input is not working,
// LED is lit directly after start-up & does not react to button press,
// analog pins are generally usabable as digital inputs
// see https://www.arduino.cc/en/Tutorial/Foundations/AnalogInputPins
const int buttonPin = A7;

const int ledPin = 13;

int buttonState = 0;

void setup() {
  // button is connected to GND, so enable internal pull-up resistors
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
};

void loop() {
  // as we use internal pull-up resistors, logic HIGH & LOW are inverted
  buttonState = !digitalRead(buttonPin);
  if (buttonState) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
};

A6 and A7 are special on the nano. They are the only pins that can't be used for digital.  They are only analog inputs.

Is that due to Arduino's hardware abstraction / pin mapping or related to the capabilities of the Atmega328?

It's the hardware capabilities of the ATMega328P-AU. Those pins only connect internally to the ADC MUX and don't have any digital drivers.

@albert, in fairness to the authors of the website, it is likely true at the time they wrote that statement, that analog pins could always be used as digital.  The DIP package ATMega328P, ATMega168P, and ATMega8 were used on the earlier Arduino boards.  The -AU in the part Majenko mentions refers to a surface mount version of the chip that has pins not present on the DIP version of the 328P.  You can see the lack and presence of A6 and A7 between the DIP and SMT versions of the Arduino UNO board.

const int buttonPin = A7; //is an invalid statement because A7 is not an integer.
Use a number instead:
const int buttonPin = 21; // 21 is the decimal pin number for A7.
Don't use A6 or A7 for pinMode(21, INPUT); on Nano, they don't work. You can use analogRead() (returns  0..1023) and then convert it to wanted boolean value (eg. >511 or <511 for crossing half Vref level)

A7 is a constant with value 21. https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/variants/standard/pins_arduino.h#L63