message:
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.

[![enter image description here][1]][1]

     /

        /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);
    }

  [1]: https://i.stack.imgur.com/j8ZWb.jpg

body:
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](https://www.hackster.io/Pedro52/arduino-capacitive-soil-moisture-sensor-diy-with-esp32-d7ad72#toc-step-4--the-electronic-set-up-1). Fortunately, a [legible schematic was derived here](https://forum.arduino.cc/index.php?topic=713146.0).

The author of the [hackster.io article](https://www.hackster.io/Pedro52/arduino-capacitive-soil-moisture-sensor-diy-with-esp32-d7ad72) cites Andreas Speiss' well-known YouTube video on ["Why Most Moisture Sensors Suck"](https://www.youtube.com/watch?v=udmJyncDvw0&feature=youtu.be)... and then proceeds to design a moisture sensor that... sucks! This design seems to "miss the point": ***dc current causes an [electrolytic reaction](https://opentextbc.ca/chemistry/chapter/17-7-electrolysis/) 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](https://www.analog.com/en/design-center/design-tools-and-calculators/ltspice-simulator.html) simulation of the [sensor circuitry](https://forum.arduino.cc/index.php?topic=713146.0) 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:

[![enter image description here][1]][1]

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

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

2. Note the dc current flow through Rw2 averages ~ 0.18mA. Knowledge of this value will allow use of [Faraday's Law of Electrolysis](https://www.finishing.com/faqs/faradayslaw.shtml) to estimate how much of the [chrome plating](https://hcsplating.com/about/plating-faq/) will be dissolved in your soil over time.

3. 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
```

  [1]: https://i.stack.imgur.com/4SY5d.jpg


sender: user

sender: assistant

body:
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.


message:
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.

body:
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.


body:
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...  ;-)


message:
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() {

    }

body:
> 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.


body:
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:

```c++
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:

```c++
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.


message:
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][1]) 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][2], 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);
    }

}
```

  [1]: https://github.com/adafruit/Adafruit_MAX31856/blob/master/Adafruit_MAX31856.cpp
  [2]: https://www.adafruit.com/product/254

body:
For anyone who has a similar issue with the SPI Bus, `SdFat` library has a Software SPI option built in (example [here][1]).

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.

  [1]: https://github.com/greiman/SdFat/blob/master/examples/SoftwareSpi/SoftwareSpi.ino


message:
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"

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


message:
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.

body:
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.


message:
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.

body: 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.


message:
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);

}
```

body:
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.


message:
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.

body:
A few possibilities come to mind:

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


message:
How to use an Arduino Speaker module with DFPlayer Mini?

I've bought an [Arduino speaker module](https://aliexpress.com/item/1005001728930766.html?spm=a2g0o.productlist.0.0.29d8b723i5oVcV&algo_pvid=2b423ecb-737d-4cfb-aa5b-d9bf775acb1c&algo_expid=2b423ecb-737d-4cfb-aa5b-d9bf775acb1c-31&btsid=0b8b15f516051880750104598e2019&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_). 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 -`.

body:
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.


message:
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) + '0';    // thousands place
        name[5] = (i/100) + '0';     // hundreds
        name[6] = (i/10) + '0';      // tens
        name[7] = i + '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) + '0';    // thousands place
        name[4] = (i/100) + '0';     // hundreds
        name[5] = (i/10) + '0';      // tens
        name[6] = i + '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() { }

body:
Normally I'd write this a differently, but I've kept in relatively simple just to illustrate the basic idea:

````cpp
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.


body:
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:

```c++
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:

```c++
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.


message:
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.

body:
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.


body: 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.


message:
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.

body:
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.


body:
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][1], that shows you, what devices can be found on the I2C bus and what addresses they have.

  [1]: https://playground.arduino.cc/Main/I2cScanner/


message:
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.

body:
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");
    }

`getLocalTime`returns 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).


body:
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][1] 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.

  [1]: https://github.com/arduino-libraries/NTPClient


message:
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 .

body:
> 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.


message:
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==&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.

body:
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").


message:
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][1] 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!

  [1]: https://joy-it.net/en/products/ARD-RS232

body:
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).


message:
L298N regulated output is greated than 5V

A few months ago I used a L298N module (actually the [Velleman VMA409](https://www.velleman.eu/downloads/29/vma409_a4v01.pdf)) 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?

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/PSD6X.jpg

body: 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.


message:
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](https://github.com/adafruit/Adafruit_AM2320/blob/master/examples/basic_am2320/basic_am2320.ino) 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?

body:
Two problems:

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

```c++
TwoWire mywire;
```

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

```c++
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.


message:
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][1] 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);
      }
    };

  [1]: https://www.arduino.cc/en/Tutorial/Foundations/AnalogInputPins

body: 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.


body:
`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)


message:
I'm looking for a way to emulate addressable LED strip using LED diodes in a custom arrangement

What I want to achieve is, I want to use my own LED pin diodes, customly place them into my sculpture and animate them. This is as I understand quite straightforward. The problem is the amount of wiring . I would want them to connect one another in series with addresses, rather then each led needing a direct data from the controller on a separate cable.

I know that addressable LEDs use a single data line through the all lights, eliminating the need to connect each led physically to the controller to get data. Is there any way to build a similar system with a bus-like structure, I believe it is possible. And if so, how? What would I need? I guess I need individual small chips for each LED, but I don't know if that's the case or even if it is how so.

I consider myself quite a newbie in electronics-arduino or LEDs, however I'm actively looking into it and researching.

body: You can buy individually addressable LEDs like the ones in LED strips. If you are fairly new to electronics I would not try to build your own serial LED controller.


message:
Cant make the second 74HC595 to start counting

I'm doing my first project with Arduino, however I got in a block and cannot figure out what I am doing wrong.

This project is 'simple'. It's that Stranger Thing's Wall.

However, I want to use the 74HC595 to leave pins free on the arduino for maybe expand and do something else with that too, so, I tried doing the arduino tutorial (https://www.arduino.cc/en/Tutorial/Foundations/ShiftOut)

So my current schematic is this one below

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/SOA0s.png

My code, however, is kind of a frankenstein. I used the shiftOut from the tutorials, however I must confess I do not know how it works (And I think its where the error may lie). I do know VBA and Python, but I know nothing of C (Or whichever this language is)

        //Pin connected to ST_CP of 74HC595
    #define latchPin 5
    //Pin connected to SH_CP of 74HC595
    #define clockPin 7
    ////Pin connected to DS of 74HC595
    #define dataPin 6
    String text;                                                    //Variável do tipo string que receberá o texto
    void setup() {
      Serial.begin(9600);                                           //Velocidade de comunicação
      for (int i = 2; i < 7; i++) {
        pinMode(i, OUTPUT);                                   //Declarando o pino como saída
      }
      Serial.println("Iniciando");
      inicializationEffect();                                       //Chamada da Função responsável pelo efeito inicial
      //basicTest();
    }
    void loop() {

      receiveText();                                               //Chamada da função responsável por receber o texto digitado
    }
    //Função que recebe o texto diitado
    void receiveText() {
      while (Serial.available() > 0) {                              //Verifica se existe alguma informação na Serial
        char c = Serial.read();                                     //atribui cada caractere a variável c que é do tipo char
        if (c != '\n') text.concat(c) ;                              //verifica se a variável do tipo char recebeu uma quebra de linha que indica o fim da palavra ou frase e concatena todos os caracteres na String text
        delay(10);                                                  //aguarda 10 milissegundos
      }
      if (text.length() > 0) {                                      //verifica se a string text tem tamanho maior que 0
        text.toUpperCase();                                       //transforma tudo que estiver na string text para maiúsculo
        if (text[0] == '#'){
          waveEffect();
        }else {
          executeEffect(text);                                        //chama a função executeEffect passando a string text como parâmetro
        }
      }
      text = "";                                                    //limpa a string text
    }
    //Função responsável por ativar linha que recebe como parâmetro o número da linha
    void lineActivation(int line, int keepalive) {
      if (keepalive == 0) {
        for (int i = 2; i <= 4; i++) {
          digitalWrite(i, LOW);
        }
      }
        digitalWrite(line+1, HIGH);                               //coloca a linha 1 em estado lógico alto
    }

    void activateLetter(char letter, int on, int off) {
      int lt;
      lt = (((int)letter - 64) % 9);
      if (((int)letter - 64) > 8) {
        lt = lt + 1;
      }
      if (on) {
        callCol(1<<lt-1);
        delay(on);                                                //mantém o pino em nível lógico alto durante o tempo que foi determinado no parâmetro da função
      }
      if (off) {
        callCol(0);
        delay(off);                                               //mantém o pino em nível lógico baixo durante o tempo que foi determinado no parâmetro da função
      }

    }

    void callCol(int col){
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, 0);
      shiftOut(dataPin, clockPin, col);
      digitalWrite(latchPin, HIGH);

    }
    void executeEffect(String text) {
      for (int i = 0; i < text.length(); i++) {
        if (text[i] == ' ') {
          delay(1000);
        } else if ((int)text[i] < 65 or (int)text[i] > 90) {
        } else {
          lineActivation(int(((int)text[i] - 64) / 9) + 1, 0);
          activateLetter(text[i], 1000, 200);
        }
      }
    }

    void inicializationEffect() {
      for (int i = 1; i < 27; i++) {
        lineActivation(int(i / 9) + 1, 0);                          //ativa a linha
        activateLetter(char(64 + i), 1000, 10);                   //ativa a letra
      }
    }
    void waveEffect() {
      for (int i = 1; i < 4; i++) {
        lineActivation(i, 1);                          //ativa a linha
      }
      for (int i = 1; i < 10; i++) {
        activateLetter(char(72 + i), 100, 0);
      }

      for (int i = 1; i < 10; i++) {
        activateLetter(char(72 + i), 0, 100);
      }
      for (int i = 1; i < 4; i++) {
        lineActivation(i, 1);                          //ativa a linha
      }
    }

    void basicTest() {
      lineActivation(2,1);
        for (int i = 0; 1 < 500; i++) {
        callCol(255-i);
        delay(100);
        }

    }

    void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
    // This shifts 8 bits out MSB first,
    //on the rising edge of the clock,
    //clock idles low
    //internal function setup
    int i=0;
    int pinState;
    pinMode(myClockPin, OUTPUT);
    pinMode(myDataPin, OUTPUT);
    //clear everything out just in case to
    //prepare shift register for bit shifting
    digitalWrite(myDataPin, 0);
    digitalWrite(myClockPin, 0);
    //for each bit in the byte myDataOut�
    //NOTICE THAT WE ARE COUNTING DOWN in our for loop
    //This means that 000001 or "1" will go through such
    //that it will be pin Q0 that lights.
    for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);
    //if the value passed to myDataOut and a bitmask result
    // true then... so if we are at i=6 and our value is
    // 010100 it would the code compares it to 000000
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
    pinState= 1;
    }
    else {
    pinState= 0;
    }
    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
    }
    //stop shifting
    digitalWrite(myClockPin, 0);
    }

If I understood right (Which I may not) theoretically, when I send a value over 255, it should "overflow" to the next 74HC595, which would be used to light the ninth column.

body:
Solved using https://arduino.stackexchange.com/a/17093/37827

By removing the custom shiftOut function and changing my

    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, col);

with

    shiftOut(dataPin, clockPin, MSBFIRST, highByte(col));
    shiftOut(dataPin, clockPin, MSBFIRST, lowByte(col));

Works like a charm

PS: Feel free to suggest something else, but this way it fixed my problem


message:
Arduino Serial Monitor displaying weird characters and changes spelling

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/p9sab.png

I am recieving the following in my serial monitor. There is a mix of wierd characters then the spelling changes for words once it gets repeated. I don't know why its doing this. my esp01 chip uses 115200 baud rate and the program is 115200 baud rate as well. What is going on.

````cpp
#include <SoftwareSerial.h>

#define TIMEOUT 5000 // mS
#define LED 5

SoftwareSerial mySerial(7, 6); // RX, TX

const int button = 11;
int button_state = 0;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(button, INPUT);

  Serial.begin(115200);
  mySerial.begin(115200);

  SendCommand("AT+RST", "Ready");

  delay(5000);

  SendCommand("AT+CWMODE=3", "OK");
  SendCommand("AT+CIFSR", "OK");
  SendCommand("AT+CIPMUX=1", "OK");
  SendCommand("AT+CIPSERVER=1,80", "OK");
}

void loop() {
  button_state = digitalRead(button);
  mySerial.println(button_state);

  if (button_state == HIGH) {
    SendCommand("AT+CIPSEND=0,23", "OK");

    delay(250);

    mySerial.println("<h1>Button was pressed!</h1>");

    delay(250);

    SendCommand("AT+CIPCLOSE=0", "OK");
  }

  String IncomingString = "";
  boolean StringReady = false;

  while (mySerial.available()) {
    IncomingString = mySerial.readString();
    StringReady = true;
  }

  if (StringReady) {
    Serial.println("Received String: " + IncomingString);

    if (IncomingString.indexOf("LED=ON") != -1) {
      digitalWrite(LED, HIGH);
    }

    if (IncomingString.indexOf("LED=OFF") != -1) {
      digitalWrite(LED, LOW);
    }
  }
}

boolean SendCommand(String cmd, String ack) {
  mySerial.println(cmd); // Send "AT+" command to module

  if (!echoFind(ack)) // timed out waiting for ack string
    return true; // ack blank or ack found
}

boolean echoFind(String keyword) {
  byte current_char = 0;
  byte keyword_length = keyword.length();
  long deadline = millis() + TIMEOUT;

  while (millis() < deadline) {
    if (mySerial.available()) {
      char ch = mySerial.read();
      Serial.write(ch);

      if (ch == keyword[current_char])
        if (++current_char == keyword_length) {
          Serial.println();
          return true;
        }
    }
  }

  return false; // Timed out
}
````

body: Your code for the most part looks ok. Your symptoms indicate a Baud mismatch or the receiver is not getting all of the bits. Try doing without the delay's, even reducing them may help. Note when in a delay the processor is committed and cannot do anything else.  See if that helps. 115000 baud is quit hot for the Arduino and software serial. Maybe you can slow things down a little and see if that helps.


body:
Try adding:

    void setup()
    {
      pinMode(LED, OUTPUT);
      pinMode(button, INPUT);

      Serial.begin(115200);
      while(!Serial){}       // Loop until USB is ready

      mySerial.begin(115200);

It will unblock once the USB port is ready.


message:
Upload s sketch to a 5v Pro-Micro board as 3.3V by mistake

I have 2 types of Pro-Micro([as shown here][1]), both 5v, micro-usb, which worked as expected, until, accidentally were flashed as 3.3v using the Arduino IDE.

At first I thought that the fact it stoped working right after, has nothing to do with that error, but since again, did the same mistake, I understand that this is no coincidence.

After doing so, boards seemed to be powered on ( leds are ON ), but are not found under `port` in the Arduino IDE.

Are they really can be destroyed by such an error ?

  [1]: https://www.aliexpress.com/item/32849563958.html?spm=a2g0s.9042311.0.0.56654c4d46zEGT

body:
Holding `RST` and `GND` pins after re-connecting USB, showed it on `port` menu.
needed another such holding, prior to upload.

All good now.


body: I had the same issue with a promicro wired in to a button box, before i found out that you need to upload a sketch....I know...I`m a noob, I was trying to rename my button boxes board to a Sparkfun board but I think i had 3.3v 8mhz selected instead of 5v 16mhz, as a result my board was not detected under comm ports and gave a driver error, given that...with my board at least there is only an 8 second delay in which you have to select the correct comm device and then upload a sketch, I shortened the process by opening IDE and selecting the board type and left IDE with a black sketch, of coarse this does not allow the board to be detected as a usb device but it fixes the comm port issue, instead of using a fiddly wire jumper i just used a small screw driver to jump the gnd and reset contacts and quickly selected the boards comm port in IDE then upload  with out a delay, by the time IDE actually recognizes a device you actually have closer to 3-4 seconds to react....but its doable.


message:
Rc switch library display received values only one times using serial monitor

I use Rc switch library to transmit and receive data. It works fine.

The part that sends the data is as follows :

    #include <Arduino.h>
    #include <RCSwitch.h>

    RCSwitch transmitter = RCSwitch();

    void setup()
    {
        Serial.begin(9600);
        transmitter.enableTransmit(10);
    }

    void loop()
    {
        /* Send data in binary */

        // Go right
        transmitter.send("010101010101010100000011");
        delay(1000);

        // Go left
        transmitter.send("010101010101010100001100");
        delay(1000);
    }

And the receiving part is like this:

    #include <RCSwitch.h>

    RCSwitch receiver = RCSwitch();
    int rightLED = 4;
    int leftLED = 7;
    unsigned long receivedValue;
    unsigned long goRight = 5592323;
    unsigned long goLeft = 5592332;

    void setup()
    {
        Serial.begin(9600);
        receiver.enableReceive(0); // Receiver on interrupt 0
        pinMode(rightLED, OUTPUT);
        pinMode(leftLED, OUTPUT);
    }

    void moveRight()
    {
        Serial.println("I'm going right");
    }

    void moveLeft()
    {
        Serial.println("I'm going left");
    }

    void loop()
    {
        if (receiver.available())
        {
            receivedValue = receiver.getReceivedValue();
            if (receivedValue == goRight)
            {
                moveRight();
            }
            if (receivedValue == goLeft)
            {
                moveLeft();
            }
            receiver.resetAvailable();
        }
    }

The problem is, when I open a serial monitor and look the output of the received values `moveRight` and `moveLeft` functions are called multiple times.

    I'm going right
    I'm going right
    I'm going right
    I'm going right
    I'm going left
    I'm going left
    I'm going left
    I'm going left
    I'm going right
    I'm going right
    I'm going right
    I'm going right

What kind of change should I do in the receiver part so that `moveRight` and `moveLeft` functions are called only once.

    I'm going right
    I'm going left
    I'm going right

body:
You can save the previous received value, and only print if it is different from what you just received.

Something like this:

    // near the top
    const int rightLED = 4;
    const int leftLED = 7;
    const unsigned long goRight = 5592323;
    const unsigned long goLeft = 5592332;

    // to hold the state
    unsigned long previousValue = 0;

    // ...

    // loop code
    void loop()
    {
      if (receiver.available())
      {
        unsigned long receivedValue = receiver.getReceivedValue();
        if (receivedValue != previousValue) {
          // something changed
          if (receivedValue == goRight)
          {
            moveRight();
          }
          if (receivedValue == goLeft)
          {
            moveLeft();
          }
          // remember the current value
          previousValue = receivedValue;
        }
        receiver.resetAvailable();
      }
    }


body:
Old post, I know but I have to add to it.  The statement   "transmitter.enableTransmit(10);" causes the RCSwitch library to send the message 10 times.  You are receiving 4 messages; you should be receiving 10. I have found that when using "receiver.available()" I also get about half of what is expected. Just a hunch, but I think the "receiver.available()" is getting every other message.  The RCSwitch library may have a dwell period after a message is received that holds the receiver in suspense causing every other message to be lost.  "Serial.begin(9600)" also is a bit slow, but I think the buffer can handel it.

The attached image shows my transmitter power consumption.  You can see that 10 messages are sent in about 200 mS.  Your delay(1000) leaves plenty of time for completion of all messages received.

[![transmitterPowerDemand][1]][1]

  [1]: https://i.stack.imgur.com/0tU8k.png


message:
How to get the sizeof array of structs

I'm trying to make a use of a relay module,
I want a clear way to configure and control my relay module
I've defined the struct and filled it with some info about id, pin number, title, and relay state
I can't loop with for in the array of controls, because I can't get the sizeof the array right

```
typedef struct{
  int id;
  int pin;
  String title;
  bool state;
}  SwitchControl;

SwitchControl controls[2] = {
  {1, 22, "Switch 01", 1},
  {2, 23, "Switch 02", 0},
};

for(int i=0; i<sizeof(controls) - 1; i++){
}
```

thanks

body:
sizeof(controls) returns the size, in bytes, of the entire object which is not what you want.  You want the number of elements.

I'll point out that since you're statically allocating this as:

> SwitchControl controls[2]

The size you are looking for is always going to be 2.  So just use 2 in your for loop like:

> for(int i=0; i<2; i++)


body:
To make it generic, you simply divide the `sizeof` the array by the `sizeof` the type:

```
for(int i=0; i<sizeof(controls)/sizeof(SwitchControl); i++){
}
```

Then you can later change the items if the array, or the structure and the code will be the same.


body:
A more generic way (usable in future cases) is:

<!-- language: lang-c++ -->

    // number of items in an array
    #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

Now you can use ARRAY_SIZE (the_array) in your code like this:

    for(int i=0; i<ARRAY_SIZE (controls); i++){
    }

The above works in C as well as C++.

---

The more C++ way of doing it is to use a template like this:

    // number of items in an array
    template< typename T, size_t N > size_t ArraySize (T (&) [N]){ return N; }

Now ArraySize(the_array) returns the number of elements in the array:

    for(int i=0; i< ArraySize (controls); i++){
    }

The "Arduino language" is C++ with some initial pre-processing. For all intents and purposes any tutorial on C++ will help you with Arduino programming (except that the Standard Template Library (STL) is not included by default).

---

I don't know why you were subtracting 1 in your posted code. Did you not want to iterate through the whole array?


message:
Compensate weight due to acceleration (load cells)

I'm trying to make a weighing scale that works in a lift. I'm using load cells to measure the weight, let's say it's F. Then I use that weight F and g which I know is 9,81 m/s2 to calculate the mass of the object like this:

F = m·g <=> m = F/g

This works when the lift is in rest (or when moving at a constant speed), but when it accelerates the weight F increases and because of that the mass also increases. Is there a way to compensate this weight(/extra force) due to acceleration?

body:
The force due to acceleration is: F = m*a

So to calculate the weight while accelerating the formula is:

F = m*g + m*a or F = m(g + a)

Note, of course, that a can be positive or negative depending on whether the elevator is accelerating or decelerating.

The trick here is to know what "a" is.  The best approach is probably to get an accelerometer and use its reading in your calculations.

By the way, the mass is always a constant here.  It does not change, in Newtonian Physics at least, due to acceleration.


body:
You could measure the total acceleration (g + lift acceleration) with an accelerometer, and use that value in your calculation instead of 9.81m/s2. If the measured value is 0, sound an alarm.

Or, assuming the elevator only accelerates/decelerates for short periodes only (say, less than 2s) during a "trip", you could make a series of measurements in a loop at, say, every 0.5s.

When you get, say, 5 measurements that are the same, or very close to each other, you know acceleration = 0 and you can average those 5 measurements to get the desired result.

Values may vary depending on the lift, and the measurements will be slow in coming.


message:
Own type definition using a struct does not name a type

I need to initialize several buttons and LEDs connected to my Arduino. To store data related to an individual button or LED, I decided to define my own data type using two different structs. One for a button and another one for a LED.

As I need to configure some GPIOs and other peripherals after instantiating each button/LED, I implemented a small factory function to get a clean interface and combine the required steps for instantiating and initialization.

Defining my own `button_t` type works as expected. The compiler does not throw any errors. However, I tried to implement the same approach for `led_t` type upon the compiler states the following error:

> example:25:1: error: 'led_t' does not name a type
>
>  led_t ledFactory(uint8_t pinNumber)
>
>  ^~~~~
>
> exit status 1 'led_t' does not name a type

My example code looks like this:

    #include <Arduino.h>
    #include <stdint.h>

    struct button_t
    {
        const uint8_t pin;
        uint8_t currentState;
        uint8_t lastState;
        uint32_t lastDebounceTime;
    };

    button_t buttonFactory(uint8_t pinNumber)
    {
        button_t btn = {pinNumber, 0, 0, 0};
        // setting some MCU registers here
        return btn;
    };

    struct led_t
    {
        const uint8_t pin;
        const uint8_t state;
    };

    led_t ledFactory(uint8_t pinNumber)
    {
        led_t led = {pinNumber, 0};
        // setting some MCU registers here
        return led;
    };

    void setup()
    {
    }

    void loop()
    {
    }

body:
This is a bug in the Arduino IDE: when converting your .ino file to a
.cpp file, it added a declaration for the function `ledFactory()`
_before_ the declaration of the type `led_t`.

As it appears to be adding those declarations right before the first
function of your sketch, a simple workaround is to put all your type
definitions before your functions.


message:
Trying to connect to WiFi on ESP32 using credentials from SD card

I am trying to connect to WiFi on an ESP32 using credentials I stored on an SD card. I am able to read and parse the credential and printing them to the serial monitor shows that the SSID and password are correct, but it is not connecting to WiFi. When I hardcode the WiFi credentials it works. What could I be doing wrong?

body:
I use the NVS partition to store NON VOLATILE information.

I use this library: [NVS library][1]

You can save like string and restore after reset/off.

Example:

    #include <Arduino.h>
    #include "ArduinoNvs.h"

    void setup() {
        NVS.begin();
        Serial.begin(115200);
        // write to flash
        String set_SSID = "WIFI_name";
        NVS.setString("nvs_wifi_name", set_SSID ); //upload 1 time. after comment this line and upload again **
        // read from flash
        String get_SSID = NVS.getString("nvs_wifi_name");
        Serial.printf("Wifi name stored %s\n", get_SSID);
    }

    void loop() {}

  [1]: https://github.com/rpolitex/ArduinoNvs


message:
(very new to C) I'm trying to use irsend with what I think is char* but it won't take it. How can I convert it to what it needs?

I'm attempting to use a raspberry pi to send ir codes directly to my arduino to have as simple as a C program as possible. Here's my code I've been tinkering with that leads to errors or not working if I don't specifically hardcode the hex ir signal.

```
#include <IRremote.h>

char buf[80];

String code = "empty";

int readline(int readch, char *buffer, int len) {
  static int pos = 0;
  int rpos;

  if (readch > 0) {
    switch (readch) {
      case '\r': // Ignore CR
        break;
      case '\n': // Return on new-line
        rpos = pos;
        pos = 0; // Reset position index ready for next time
        return rpos;
      default:
        if (pos < len-1) {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
    }
  }
  return 0;
}

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

IRsend irsend;

void loop() {
  if (readline(Serial.read(), buf, 80) > 0) {
    Serial.print("You entered: >");
    //Serial.print(buf);
    //Serial.println("<");
    //irsend.sendNEC((uint32_t) buf, 32);
    String str(buf);
    //irsend.sendNEC((uint32_t) code, 32);
    //irsend.sendNEC(0x210704FB, 32);
    code = buf;
    delay(600);
    //Serial.print((uint32_t) buf, 32);
    Serial.print(code);
    irsend.sendNEC(buf, 32);

  }
```
I've left my mess on the bottom to illustrate how little I know and what I've tried. I've been trying to figure out what I'm sending it but it doesn't help that serial.print doesn't work like irsend. I'm intending to send hex codes directly and have the arduino blindly plug them into irsend.sendNEC(0x210704FB, 32); which works but when I try to put my own variable in it won't.

Very much appreciate any help! I know it'd be easy for anybody who knows a little C.

irsend.sendNEC(buf, 32); returns:
initializing argument 1 of 'void IRsend::sendNEC(uint32_t, uint8_t, bool)'
     void sendNEC(uint32_t data, uint8_t nbits, bool repeat = false);

and irsend.sendNEC((uint32_t) buf, 32); doesn't throw any errors but also does not seem to do anything

body:
[The library][1] you're using and the protocols it implements are not for sending large chunks of data.

The sendNEC function you're using is simply limited to 32 bits per transmission.  You're not going to be able to send an arbitrary length string with it, except by constructing some protocol around it that breaks the string into multiple transmissions of as much as 32 bits at a time.

Without splitting hairs about the language standard and qualifying everything to be perfectly accurate: what you're doing with your `(uint32_t)` cast is sending the memory address of your string over IR, which is no doubt not what you wanted nor likely particularly useful on the receiving end.

What you appear to want is something closer to [IrDA][2].  That said, you probably *could* do what you want by calling `sendNEC()` on each character of your data in the simple case.  Better would be to send 32-bits of the string at a time since there is overhead to each transmission.  But again, these functions and protocols are designed for sending short, infrequent messages.  They were designed to be dirt simple so that they could on be implemented hardware a fraction of the power of a typical Arduino, so that they could be cheap decades ago when when they were inverted.  In an effort to be both simple and at least *somewhat* reliable, they sacrifice a lot of speed.

  [1]: https://github.com/z3t0/Arduino-IRremote
  [2]: https://en.wikipedia.org/wiki/Infrared_Data_Association


body:
If you are sending HEX values like `0x1234abcd` from the Pi to the Arduino to send those as an IR code you first have to interpret that string data as a hexadecimal number.

That's not as simple as just casting the string since, as @timemage says, all you're doing there is casting the *address* of the character array.

Instead you should use `strtoul()` to parse the string and give you the equivalent number to what it contains.

`strtoul()` can convert numbers in a number of different bases, and can even work automatically.  From the Linux man page:

> **SYNOPSIS**
>
> `unsigned long int strtoul(const char *nptr, char **endptr, int base);`

And later on:

> If base is zero or 16, the  string  may then include a "0x" prefix, and the number will be read in base 16; otherwise, a zero base is taken as 10 (decimal) unless the next character is '0', in which case it is taken as 8 (octal).

That means it can automatically parse `0x1234abcd` as a hexadecimal number, `12345678` as a decimal number, and `052714` as an octal number (it's important to remember that one so you don't accidentally add a leading zero to a decimal number and have it parsed wrong).

So knowing all that you can now:

```c++
uint32_t code = strtoul(buffer, NULL, 0);
```

and `code` will contain the contents of `buffer` represented as an actual numeric variable (assuming the content can be parsed as a number).


message:
ESP32 AsyncWebServer SPIFFS problem loading page

I can load spiff docs, but I get a 404.  Wireless works, IP addressing works and I can load other examples successfully.  This simple image load ino is giving me fits!

```cpp
#include <WiFi.h>
#include <AsyncTCP.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h>
const char *ssid = "x";
const char *password =  "123456789";
IPAddress staticIP(10,0,0,1); //ESP static ip
IPAddress gateway(0,0,0,0);   //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0);  //Subnet mask

AsyncWebServer server(80);

void setup() {
  Serial.begin(115200);
  WiFi.softAP(ssid, password);

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{request->send(SPIFFS, "/index.htm", "text/html");});

server.on("/image.png", HTTP_GET, [](AsyncWebServerRequest *request)
{request->send(SPIFFS, "/image.png", "image/png");});

server.begin();

}//END setup

void loop()
{
}
```
```html
<!DOCTYPE HTML>
<html>
<head>
     <meta charset='UTF-8'>
</head>
<body>
     <img src="image.png" alt=" image goes here">
</body>
</html>
```

body:
I don't have an ESP32 to test with.  Though, I tried to make your code run on an ESP8266, but it's a bit of an effort to validate what is ultimately a wild guess on my part.

And that is: *perhaps* you have some uppercase letters in your filename such that `"/image.png"` does not match perfectly and furthermore *maybe* SPIFFS is case sensitive.  That is, your file could be named Image.png or IMAGE.png and that might matter.

UPDATE:

In my exploring this on the ESP8266, I'd forgotten to execute `SPIFFS.begin()`.  And I see no counterpart to it in your code.
At least one example of ESPAsyncWebServer I've seen [does call `SPIFFS.begin()`][1]

I found that the filenames **are** case sensitive, again at least on the ESP8266; so that can be a source of problems.

Also checked that if the SPIFFS size is changed through menu selections, I did indeed need to reupload the SPIFFS image.

I know these are different systems; in fact the code I'm using to test doesn't compile for ESP32, but I suspect a lot of the code is shared, and so maybe the problems are as well.

  [1]: https://github.com/me-no-dev/ESPAsyncWebServer/blob/3c6f5f9/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino#L133


message:
Detect if MCU is ESP8266 or ESP32

I'm coding a library which handles sleep procedures.

Since I'm using both ESP826 and ESP32, which uses different sleep commands ( and WiFi ), I'm looking for a way to detect the MCU, while NOT using a boolean flag that indicates so.

Guy

body:
I take this to mean that you do not want to have to ask *the user* of the code to configure a boolean flag.

The ESP8266 Arduino package provides `-DARDUINO_ARCH_ESP8266 -DESP8266`
command-line options these while calling g++.  These effectively `#define` feature test macros as though they were at the beginning of the source code.

For ESP32 it does likewise with `-DARDUINO_ARCH_ESP32 -DESP32`

You could perform tests in your code such as:
````cpp
#if defined (ARDUINO_ARCH_ESP8266)
// do one thing
#elif defined(ESP32)
// do another
#else
#error Architecture unrecognized by this code.
#endif
````

There are likely also macros like these that are predefined by the xtensa g++ compiler.


message:
Stepper motor driver not working properly

I have a problem. I am following this guide about controlling a NEMA 17 stepper motor: https://www.makerguides.com/a4988-stepper-motor-driver-arduino-tutorial/

I uploaded the code to my arduino uno and powered on everything, but the stepper motor doesn't rotate, except when I put my finger on the metal screw of the a4988 driver. The arduino is powered by a 5v 1A adapter and the a4988 driver is powered with a 12v 2amp adapter.

What is causing this?

body:
The "metal screw" is a "trim potentiometer" that is used to set the current used to drive the motor. It sounds like you may be altering the current when you push against it. Try turning it to different angles to see what effect that has on the motor.

Alternatively if it only ever works when you push on it then it could be that you have a faulty potentiometer on your board.


message:
How to assign ESP8266 access point a hostname that can be resolved by the stations?

I want to assign a *hostname* to a ESP8266 **access point**, so that the clients can reach a webserver on this access point without caring about the IP address of the AP. How can that be done?

I tried using `WiFi.hostname("something");` but that does not work with AP mode. Can this somehow be done?

### UPDATE

Using *mDNS* seems to work in this AP mode too. However, I am still curious to know if this is possible to access the webserver on the AP using the *hostname* and not *mDNS*.

body:
I'm unclear on the distinction being drawn here:
> the hostname and not mDNS

mDNS, like DNS, and hostname lists are all things a "resolver" would use to map a "hostname" to an IP address.

If you mean "how do I use DNS instead of mDNS?", you'd need to have your ESP8266 running a DNS server.  And for clients to be aware of it you'd probably have to be running a DHCP server as well.

By the way, the examples list for the ESP8266 Arduino package contains a DNSServer/DNSServer example that appears to do exactly this.  I have just tested it.

[This is the exact code I ran][1] out of the ESP8266 Arduino github repo at the tag for the version of the ESP8266 Arduino core I tested it on, 2.7.4.

  [1]: https://github.com/esp8266/Arduino/blob/2.7.4/libraries/DNSServer/examples/DNSServer/DNSServer.ino