text:
Problem interfacing both esp8266 and EM18 with Arduino Uno
I have connected esp8266 with Arduino Uno and programmed 8266 with Arduino IDE to send data to firebase over WiFi. Now I also want to interface EM18 RFID Reader with Arduino in order to read the RFID tag and send information to firebase through esp8266. I have integrated the code for the same.
Now after uploading the code, only one of the interface works at a time, i.e if both esp8266 and EM18 are connected to Arduino, esp8266 connects to WiFi and sends data(verification data to check esp8366 is working) also, but not the data I want because EM18 is not reading the tag id. Having uploaded the same code if I remove connections with esp8266, the EM18 works fine(i.e. ID is printed in serial monitor after being read by EM18 Reader module).
Please help me with this, how can I send the information read by EM18 to esp8266 because they are not working together.
P.S. In my code there is different Rx Tx pin defined for esp8266(digital pin 0,1) and for EM18(digital pin 9,10(random)). Used softwareserial library for defining new Rx Tx.
My Connections:
Arduino and ESP8266
RX with RX;
TX with TX;
GND with GND;
3.3V with VCC;
3.3v with CH_PD;
GND with GPIO0(To Flash ESP8266);
Arduino's Reset pin is connected to Ground
Arduino and EM18 RFID Module
5v wuth VCC;
GND with GND;
Pin 13(Set as Rx) with TX;
My Code:
#include <BearSSLHelpers.h>
#include <CertStoreBearSSL.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiAP.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WiFiScan.h>
#include <ESP8266WiFiSTA.h>
#include <ESP8266WiFiType.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiClientSecureAxTLS.h>
#include <WiFiClientSecureBearSSL.h>
#include <WiFiServer.h>
#include <WiFiServerSecure.h>
#include <WiFiServerSecureAxTLS.h>
#include <WiFiServerSecureBearSSL.h>
#include <WiFiUdp.h>

#include <Firebase.h>
#include <FirebaseArduino.h>
#include <FirebaseCloudMessaging.h>
#include <FirebaseError.h>
#include <FirebaseHttpClient.h>
#include <FirebaseObject.h>

#include <ArduinoJson.h>

#include <SoftwareSerial.h>
//firebase and wifi
#define FIREBASE_HOST "my-shopping-d.firebaseio.com"
#define FIREBASE_AUTH "rkyF4AuzssSIO5VYRO6iP"
#define WIFI_SSID "****"
#define WIFI_PASSWORD "****"

const int disp=9;
//int j;
int tx=10,rx=13;
SoftwareSerial emSerial(rx,tx);  //EM18 Rx,Tx
int buttonState2 = 0;
int count = 0;                                          // count = 0
char input[12];                                         // character array of size 12
int count_arr[5]={0,0,0,0,0};
int i,cnt,total=0;
int price[5]={295,20,50,500,15};
char id_arr[6]={'2','F','7','E','3'};
char *myStrings1[] = {"Rice Rs.295", "Oreo Rs.20", "Silk Rs.50",
                     "Ghee Rs.500", "Nestle Rs.15", "TOTAL : "
                    };
char *myStrings2[] = {"Removed Rice Rs.295", "Removed Oreo Rs.20", "Removed Silk Rs.50",
                     "Removed Ghee Rs.500", "Removed Nestle Rs.15", "TOTAL : "
                    };

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

   //connect to wi-fi
   WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);

   pinMode(disp,INPUT);
}
 Serial.println();
  Serial.print("connected: ");
  Serial.println(WiFi.localIP());

  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Serial.println("Firebase Connected");
}

int n = 0;

void loop()
{

   if(emSerial.available())
   {
    Serial.println("Card reader");
      count=0;
      while(emSerial.available() && count < 12)          // Read 12 characters and store them in input array
      {
         input[count] = emSerial.read();
         count++;
         delay(5);
      }
      Serial.print("id inpiut");
      Serial.println(input);
      for(i=0;i<5;i++)
      {
        if(input[10] == id_arr[i])
        {
          cnt=i;
          break;
        }
      }

      if(count_arr[cnt] == 0)
      {
        total=total+price[cnt];
        Serial.println(myStrings1[cnt]);
        Serial.print("TOTAL : ");
        Serial.println(total);
        count_arr[cnt]=1;
      }
      else if(count_arr[cnt] == 1)
      {
        total=total-price[cnt];
        Serial.println(myStrings2[cnt]);
        Serial.print("TOTAL : ");
        Serial.println(total);
        count_arr[cnt]=0;
      }

   }
      buttonState2 = digitalRead(disp);   // read the state of the pushbutton value:

      // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
      if (buttonState2 == HIGH)
      {

        j=1;
        for(i=0;i<5;i++)
        {
          if(count_arr[i]==1)
          {

            Firebase.setString("Items in Cart: ", myStrings1[i]);
             // handle error
            if (Firebase.failed())
            {
               Serial.print("setting /message failed:");
               Serial.println(Firebase.error());
               return;
            }
            delay(1000);
            String name = Firebase.pushInt("Total: ",total);
             // handle error
            if (Firebase.failed())
            {
                Serial.print("pushing /logs failed:");
                Serial.println(Firebase.error());
                return;
             }
            //j++;
          }
          delay(2000);

        }
      }
      int test = 5;
  String name = Firebase.pushInt("cart",test);
  // handle error
  if (Firebase.failed()) {
      Serial.print("pushing /logs failed:");
      Serial.println(Firebase.error());
      return;
  }
  Serial.print("pushed: /cart/");
}

You can only reliably (for given values of "reliably") use one SoftwareSerial at a time.

I have added connections and code, plz see and reply :)

Do you have the EM18 wired to the Arduino's pins 10 and 13, or the ESP8266's pins 10 and 13?

Em18 is wired with pin 13, i do not need tx pin for em18(only one way communication), and esp8266 is connected with default tx rx pins of arduino

Which pin 13? ESP8266 pin 13, or Arduino pin 13?

Arduino pin 13 set as Rx using softwareserial

So... you run code on the ESP8266, and expect it to somehow be able to make the Arduino's pin 13 do something...?

Haha, it's running though, because after uploading the code in esp8266(when both esp and EM18 are connected to Arduino) if I remove connections of esp8266 from Arduino then the EM18 reads the RFID tag and prints it on serial monitor.

Then you must have some code installed into the Arduino that does that.


text:
Two buttons, one LCD
I'm trying to make a program that whenever a button is push, a different word will show on a lCD screen. However, it seems that the two buttons provide the same output ("Screen A"), it's like there is no difference between them, and I'm not sure what's the cause.
The code is very simple:
const int buttonPin1 = 13;     // the number of the pushbutton pin
const int buttonPin2 = 12;     // the number of the pushbutton pin

int buttonState = 0;

long randNumber;

void setup() {

  for(int x=0; x<2; x++)
  {
    pinMode(buttonPin[x], INPUT);
  }

}
    void loop() {

      for(int x=0; x<2; x++)
      {
        buttonState = digitalRead(buttonPin[x]);

        if (buttonState == HIGH && buttonPin[x] == 13) {
          lcd.print("  Screen A ");
        }
        if (buttonState == HIGH && buttonPin[x] == 12) {
          lcd.print("  Screen B ");
        }
      }

    }

Any help is appreciated

You are missing the definition of your buttonPin[] array.

I guess it's something with the circuit ... can you add it to your question.
Also, make sure buttonPin has the values 13 and 12 in the first and second index.
Btw, The following code is functionally identical:
void loop()
{
    if (digitalRead(buttonPin[0]) == HIGH)
    {
       lcd.print("  Screen A ");
    }
    if (digitalRead(buttonPin[1]) == HIGH)
    {
       lcd.print("  Screen B ");
    }
}

If you want to have the loop and a flexible amount, use something like:
#define NR_OF_PINS 2

int buttonPins[NR_OF_PINS] = { 8, 9 };
String screens[NR_OF_PINS] = { "Screen A", "Screen B" };

void loop()
{
    for (int pin = 0; pin < NR_OF_PINS; pin++)
    {
        if (digitalRead(buttonPins[pin]) == HIGH)
        {
            lcd.print(screens[pin]);
        }
    }
}

Update
My answer is related to the code before you edited.
Remarks:

After your edited code, you forgot to declare buttonPin:
int buttonPin[] = { buttonPin1, buttonPin2 };
You do not use long randNumber
Instead of a global variable int buttonState  you can create it locally in the loop function (although you do not need it according to my code above).
buttonState = digitalRead(buttonPin[x]);
Also, what you high likely want to add is button debouncing (check the arduino example about this), unless you add a delay after showing a screen of a considerable amount (like 100 ms or more).

source: Stack Exchange

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

sort: votes


text:
Connection of a DS18B20 on a Arduino pro mini
I'm actually trying to connect a DS18B20 sensor to a homemade board build with a ATmega328P processor running with a power of 3.3V and at 8 Mhz.
In order to get the address I wired the board as the following schematic on the pin 5 of my board.

To power the sensor and the pull up resistor I use the VDD output of my board which provides 3.3V.
For the code part I uploaded this:
// This sketch looks for 1-wire devices and
// prints their addresses (serial number) to
// the UART, in a format that is useful in Arduino sketches
// Tutorial:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

#include <OneWire.h>

OneWire  ds(5);  // Connect your 1-wire device to pin 5

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

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  Serial.print("Looking for 1-Wire devices...\n\r");
  while(ds.search(addr)) {
    Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rThat's it.\r\n");
  ds.reset_search();
  return;
}

void loop(void) {
  // nothing to see here
}

When I make it run on an Arduino Uno card I can get the address of the sensor but when I make it run on my card I only obtain this:

Looking for 1-Wire devices...

That's it.
Anyone got a idea why it's working on an Arduino Uno but not on my card?

On schematic two pins are connected, in question description and code, there's only one pin.

Is that a mosfet? Is it used to shortcut the data to 3.3v? why?

Sorry @domen  i had put the wrong diagram in my post, i edited my post

You're saying it's same chip (and similar surrounding hardware) and same software? Is there a schematic for your own hardware, because you've probably made some mistake there. Include the details of all differences to working setup.

@domen i added in the post a hardware shematic around the chip , we use the PD5 (D5 )

You may have based it on this, but with RX, TX and D5 not connected, your hardware could be quite different :) Is your software the same (vs. working setup)? What are the hardware differences?

Did you try a lower value for the pullup resistor? 2k2 for instance. Check the spec.

I finally made it work, thx @domen.
I looked at the other part of the schematic and found I was using the wrong pin - I have two LDO and the one I was using was deactivated for sensor.
Thanks all for your help.

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


text:
Can't use MEGA as Transmitter and UNO as Receiver nRF24L01
I have a project with 7 May Deadline, i really need help on this. Here is the problem, I need to use my Arduino MEGA 2560 as transmitter and Ardino UNO(CH340G) as receiver. I can use uno as transmitter and mega as receiver , but vice versa doesn't works.
I've used the tutorial on this site :
https://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/
All codes, connections are same, but when i set MEGA as transmitter and uno as receiver, there is no data coming to Serial port of Uno. I really need help on this, i will be very very very grateful. Thank you so much.
Code on MEGA(transmitter)
/*
* Arduino Wireless Communication Tutorial
*     Example 1 - Transmitter Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}
void loop() {
  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));
  delay(1000);
}

Code for receiver(UNO)
/*
* Arduino Wireless Communication Tutorial
*       Example 1 - Receiver Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}
void loop() {
  if (radio.available()) {
    char text[32] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text);
  }
}

    PINS ON MEGA :
    3.3 -- VCC
    GND -- GND
    8   -- CSN
    7   -- CE
    51  -- MOSI
    52  -- SCK
    50  -- MISO
    PINS ON UNO :
    3.3 -- VCC
    GND -- GND
    8   -- CSN
    7   -- CE
    11  -- MOSI
    12  -- MISO
    13  -- SCK

Please show your actual wiring for both devices. Also your code would help.

I have edited my post, thank you so much i will be very grateful for all helps please.

Are both your modules identical? If you swap the modules over does it start working?

I will try it now thanks for advice :D i hope it works

It didn't worked , but thanks for help :D Still waiting for somone to help me btw :D i ll be very thankful if someone can , thanks a lot.

Shame. Still, we know it's not the modules at fault.

Did you add a capacitor to the 3V3? https://www.instructables.com/id/NRF24L01-Fixing-Connection-Issues/

I didn't i 'll try when i get home but vice versa works, mega can work as receiver but not as transmitter, but thank you i will try , still waiting for help , thanks


text:
Restoring all fuse bits on AtMega328P-PU
I'm worked with Low Fuse bits in AVRDUDEPROG 3.3. Fuses was non-inverted. And by mistake I enabled SUT1 and SUT0, when SUT0 was enabled. And when I programmed avr,
it shows me error that avrdude.exe: initialization failed, rc=-1. I have read I can restore it with Avr Fuse Doctor, but I can't buy or make with pcb. Can I recover avr with:
#include <avr/io.h>

int main(void) {
    DDRB = 0xFF;
    while(1) {
        PORTB ^= 0xFF;
    }
}

and load it to another avr and connect it to broken avr?
Can I make doctor on breadboard or Can I do it with usbasp/isp?
Can I load a new bootloader in it?

It doesn't answer your question, but I foubd this online tool very useful when configuring fuses on avr-uCs: http://www.engbedded.com/fusecalc/

The following is from:
https://www.allaboutcircuits.com/projects/atmega328p-fuse-bits-and-an-external-crystal-oscillator/
"The two bits to be avoided unless you are absolutely certain you know what you are doing are bit7, the RSTDISBL (external reset disable) bit and bit 5, the SPIEN (Serial Peripheral Interface Enable) bit. Disabling either one is often the cause for "bricked" Atmel µCs; "leave them alone" is good advice."
According to the article SUT0 and SUT1 are clock start up time related bits. It doesn't seem as though it is necessary to use anything special to change them.
You will find the information at the website very usefu. I know I have.
The High Voltage (other names too) programmer you have mentioned should not be necessary if you only changed the SUT0 and SUT1 fuses.
HOWEVER, if you did change the SPIEN or RSTDISBL fuses, you should either get one of the special programmers or just purchase another 328P microprocessor.
If you search the internet for "AVR High Voltage programmer" you will find many ideas for how to build one.
This link :https://electronics.stackexchange.com/questions/33/arduino-as-avr-programmer/71
provides good information.

I have got 2 atmega328 and one uno. OK. But I didn't touch to Rest disable or Spi enable(I coiuldn't touch him because it was untouchable). I have set CKSEL to 0000 without invert. And set SUT1,0=11 non-invert and I loaded it to avr. With CKSEL=0000 It worked because I have got external Crystal with 16 MHZ. But when I loaded sut1,0=11 It shows me Error that avrdude cannot connect it.

And if you now, what High Voltage programmer is?

If it is 5V programmer?

No, it switches 12V in to reset the fuses.  Nick Gammon has a nice writeup on it here https://gammon.com.au/forum/?id=12898 with a schematic showing the setup needed to bring the Reset pin to 12V for the needed duration under software control.

Thanks but can I get 12V adapter and connect to atmega with resistor. And which contact I connect it?

Hey if I have got usbasp I can't do it?

Or I must take arduino uno and do it

ANd what I must do with my Uno for it

How can I get 12v from Uno?

Use the link CrossRoads posted, you should be able to 'engineer' a way to use it with what you have...


text:
How to connect Arduino Nano to Thermal Printer via serial connection
I have a generic Arduino Nano board that uses the old bootloader. I have the printer and the Arduino connected like so:

This is my code:
#include "Adafruit_Thermal.h"

// Here's the new syntax when using SoftwareSerial (e.g. Arduino Uno) ----
// If using hardware serial instead, comment out or remove these lines:

#include "SoftwareSerial.h"
#define TX_PIN 5 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 6 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor
// Then see setup() function regarding serial & printer begin() calls.

// Here's the syntax for hardware serial (e.g. Arduino Due) --------------
// Un-comment the following line if using hardware serial:

//Adafruit_Thermal printer(&Serial1);      // Or Serial2, Serial3, etc.

// -----------------------------------------------------------------------

void setup() {

  // This line is for compatibility with the Adafruit IotP project pack,
  // which uses pin 7 as a spare grounding point.  You only need this if
  // wired up the same way (w/3-pin header into pins 5/6/7):
  // pinMode(BUILTIN, OUTPUT); digitalWrite(7, LOW);

  // NOTE: SOME PRINTERS NEED 9600 BAUD instead of 19200, check test page.
  mySerial.begin(9600);  // Initialize SoftwareSerial
  //Serial1.begin(19200); // Use this instead if using hardware serial
  printer.begin();        // Init printer (same regardless of serial type)

  // The following calls are in setup(), but don't *need* to be.  Use them
  // anywhere!  They're just here so they run one time and are not printed
  // over and over (which would happen if they were in loop() instead).
  // Some functions will feed a line when called, this is normal.

  // Font options
  printer.setFont('B');
  printer.println("FontB");
  printer.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  printer.setFont('A');
  printer.println("FontA (default)");
  printer.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

  printer.sleep();      // Tell printer to sleep
  delay(3000L);         // Sleep for 3 seconds
  printer.wake();       // MUST wake() before printing again, even if reset
  printer.setDefault(); // Restore printer to defaults
}

void loop() {
}

When I run my code or reset no prints get sent to the print.
Here's what I've tried.

Ensure power is on on both devices
Try baud rate 19200
Swop Tx and Rx cables around
Tried D5 and D6 for Tx and Rx

Any help would me much appreciated.

the printer cannot detect the data signals because it has no ground reference ...connect grounds together

Sorry I didn't show that in my diagram but I did connect ground and 5vcc together with the Arduino and the thermal printer. Is there anything else I can try?

the Vcc should no be connected ... the printer should have its own power supply

Tell what printer that is! It does not look like having a serial interface.

Your additional info about your printer tells me that it has a Bluetooth and a USB interface - but I can not see any other serial connection port.
So there is no way connecting this printer as-is to the arduino nano by some digital port pins.
You may decide to either buy the Thermal printer offered by Adafruit our search for a Thermal printer that clearly states that is has a "Serial Interface" or "Serial RS232 Interface" - no matter if that comes with "TTL" or not like the Adafruit printer.
The printer is intended to be connected to a USB host port (of an PC or RPi or so) or via Bluetooth (to an PC or Android phone).
It may offers a virtual serial interface over both USB and Bluetooth, but that is a speculation.
It may be possible to hack your printer. I think the Adafruit printer was modded by Adafruit. They may have bought a stock-printer and added the connector for the TTL interface. This may also be possible with the printer you have, but that is not in the scope of your question and highly speculative.

Sorry man, it's a Chinese machine I can't find a datasheet for it. It's made by Andowl. This site has the most information I've seen: https://www.electromannsa.com/products/goojprt-58mm-wireless-bluetooth-thermal-receipt-printer


text:
How to upgrade ESP8266 NodeMCU SDK from V2.5.2 to V3?
ESP.getFullVersion() output:
SDK:2.2.1(cfd48f3)/Core:2.5.2=20502000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020Connecting to DO_231455

I upload sketches from the Arduino IDE. How do I update the SDK?
I have the flasher tool but I can't seem to find documentation on what to do from this point:

I've downloaded the assets from Github

The SDK is linked into every Arduino application you flash to the ESP8266 - it's not flashed separately.
Choose it in Tools menu. It is available only if you select "Generic ESP8266 module".

The SDK is linked into every Arduino application you flash to the ESP8266 - it's not flashed separately.
Presumably you've already followed the instructions to put the URL for the ESP8266 Arduino Core in the preferences for the Arduino IDE.
Once that's there, to update the ESP8266 Arduino SDK, go to the Tools menu, select Board, then select the Boards manager (the first item in the menu).
That will bring up a dialog listing all the board families your Arduino IDE knows how to build for. You can limit the list to those with updates available by selecting "Updatable" in the "Type" field. Or just scroll down or search till you find the ESP8266 entry. Click it and if there's an update available you'll see an "Update" button appear on it. You can also reinstall older versions by choosing a version and clicking the "Install" button.

However, there is no version 3 as yet. At the time that I'm writing this, 2.5.2 is the most recent release of the SDK.

it is the Arduino core version in Boards Manager, not the Espressif SDK version


text:
Sound sensor's output stucks to high values when I include a delay in the loop function
I use Waveshare's Sound Sensor module.
I use this simple code to test the module:

As you can see, the problem is that when I have a delay in the program, once the analogRead is bigger than 10 (by slightly knocking the mic with my finger), "sound" is printed, but sound sensor's output doesn't decrease back to normal values and "sound" keeps repeating.
If I don't use delay, everything works fine, but I need that delay.
*NOTE: on this test I use a STM32 nucleo development board, but I don't think that contributes to the problem.

What is a "Waveshare's Sound Sensor module"? We aren't psychic. No links, no answer.

please print the actual values ... do not use a graph

I uploaded monitor's prints

Is this your mystery device? If so, how are you wiring it? Are you trying to read the AOUT or DOUT pin?

Majenko no need for superpowers. You only need 5 seconds to google it and find all the infos in the first link that appears. If spending 5 seconds is too much time feel free to dismiss the question and save your time

Yes. Wired as instructed by the User manual. I'm reading AOUT.

@BrainTrance YOU know that the first link is the right link because YOU know what your device is. WE don't. If you are not explicit with your information then we are floundering in the dark and unable to give a good answer. Be precise in your information.

The AOUT pin of that device is no more than an amplified audio signal. It is AC coupled, and that means that it is a small signal varying around 0v. It is not suitable for feeding directly into an ADC.
The AC coupling capacitor will be being charged up by the DC offset it is there to remove, and the lack of any drain on that capacitor while the ADC is not sampling means it never discharges as it should. By sampling faster you increase the load and thus it can discharge somewhat.
To properly read that AOUT pin you need to add your own DC offset to half the VCC voltage of your Arduino board, which can be done by adding two 10k resistors. One from VCC (5v) to the analogue input, and the other from the analogue input to ground.
The signal you read will then be "idle" at around 2.5v (512 ADC reading) and vary around that as sound is picked up.
Note that you can't just sample once per second and hope: there is no provision for "did sound happen in the past second". Instead you really need to be sampling all the time.
If all you care about is if some sound above a threshold has happened then you would be better using DOUT connected to a digital input or even an interrupt pin, and using the threshold setting trim pot on the board.


text:
Compute SHA256 of string and output to string
In my Arduino project I want to compute the SHA256 hash of a string and store the result to a string, and do this recursively many times (i.e. compute hash of hash of hash etc...). So my goal is to have a reliable function as follows:

String h(String input) {
...
return output;
}

where for example h("abc") would return "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad".
I downloaded this library
(from Tools->Manage libraries, it is also in github) and then ran the example in TestSHA256.ino which passes all the checks. However I'm stuggling to make my function work since the library doesn't have a specific example on how to compute and return a SHA256 hash.
I have been looking in function testHash_N() in TestSHA256.ino, which appears to create a hash (from struct TestHashVector data) and compare it with the precomputed hash (from struct TestHashVector hash[]).
The hash seems to be computed in lines 89-96 in TestSHA256.ino.  I just want to take the actual hash string result, so for testVectorSHA256_1  in the example, I would need to have a string = "ba7816bf....15ad" as the result.
I understand that this is related to memory referencing in Arduino but I'm not experienced so I'd be grateful if you helped me with this.
EDIT: My code snippet so far is as follows, but it doesn't output the correct hash..
#include <Crypto.h>
#include <SHA256.h>
#include <string.h>

#define HASH_SIZE 32
#define BLOCK_SIZE 64

char hex[256];

char *hashvalue;

SHA256 sha256;

byte buffer[128];

char *btoh(char *dest, uint8_t *src, int len) {
  char *d = dest;
  while( len-- ) sprintf(d, "%02x", (unsigned char)*src++), d += 2;
  return dest;
}

char* h(Hash *hash, char* hashvalue)
{
    size_t size = sizeof(&hashvalue);
    size_t posn, len;
    size_t inc = sizeof(&hashvalue);
    uint8_t value[HASH_SIZE];

    hash->reset();
    for (posn = 0; posn < size; posn += inc) {
        len = size - posn;
        if (len > inc)
            len = inc;
        hash->update(&hashvalue + posn, len);
    }
    hash->finalize(value, sizeof(value));

    return(btoh(hex, value, 32));
}

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

    bool tmp;
    char *testvalue = "abc";
    Serial.println(h(&sha256,*testvalue));

}

void loop()
{
}

Hint#1: sizeof(&hashvalue); is not the length of the string. It is the number of bytes of a pointer.

Hint#2: *testvaluein the statement h(&sha256,*testvalue)); is not a pointer. It is actually the value of the first character, a in the testvalue.

Hint#3: uint8_t value[HASH_SIZE]; is a local value and cannot be returned. static uint8_t value[HASH_SIZE]; will allow that.

Thank you very much for helping

The main trick is to understand how the Arduino String class works. You can find the source code in your installation of the Arduino IDE or on github.
The basic pattern you are looking for is:
String h(String& input) {      // Pass String by reference to avoid copying
  char output[OUTPUT_MAX];
  char* data = input.c_str();  // Access to internal buffer
  ...
  return String(output);       // Return a String object of the output
}

Cheers!

Thanks, I've updated my question with an attempt to solve this but I'm still struggling with errors, can you please help me with the code inside to make it work?

Yes you have several issues but before going forward please acknowledge that you received an answer to your original question :) and I will get back to you.

ok right, just want to solve my problem in its entirety

Updated my code again, it works but it doesn't output the correct hash, outputs "ffe9aaeaa2a2d5048174df0b80599ef0197ec024c4b051bc9860cff58ef7f9f3" instead of "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"

I suggest the following function. That replaces a string by its hash.
It's done in place in order to save memory. Make sure the buffer you
give it is at least 65 bytes long. Warning: not tested.
#include <Crypto.h>
#include <SHA256.h>

#define HASH_SIZE 32

SHA256 sha256;

/*
 * Replace a string by its hash, in place.
 * `data' should point to a buffer at least 65 bytes in length.
 */
hash_in_place(char *data)
{
    uint8_t value[HASH_SIZE];

    sha256.reset();
    sha256.update(data, strlen(data));
    sha256.finalize(value, sizeof(value));

    // Convert to hex into the original buffer.
    data[0] = '\0';
    for (size_t i = 0; i < HASH_SIZE; i++) {
        data += sprintf("%02x", value[i]);
    }
}

Nice implementation! Could avoid sprintf() to reduce program memory size.


text:
Is it possible to output a variable clock using Fast PWM?
I am trying output a clock and change its frequency dynamically with a rotary encoder.
When the code for the rotary encoder is included the clock doesn't reach its max freq(31Khz). But without the rotary encoder code, it does. What is happening that it can't reach its max freq?
const byte CLOCKOUT = 9;
int val;
int encoder0PinA = 3;
int encoder0PinB = 4;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;

void setup() {
  pinMode (CLOCKOUT, OUTPUT);
  // set up Timer 1
  TCCR1A = bit (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = bit (WGM12) | bit (CS12);   // CTC, no prescaling
  OCR1A =  0;

  pinMode (encoder0PinA, INPUT);
  pinMode (encoder0PinB, INPUT);
  Serial.begin (9600);
}

void loop() {
  n = digitalRead(encoder0PinA);
  if ((encoder0PinALast == LOW) && (n == HIGH)) {
    if (digitalRead(encoder0PinB) == LOW) {
      OCR1A-=100;
    } else {
      OCR1A+=100;
    }
    Serial.print (OCR1A);
    Serial.print ("/");
  }
  encoder0PinALast = n;
}

The Code that reaches the Max freq properly is below
void setup ()
  {
  pinMode (CLOCKOUT, OUTPUT);
  // set up Timer 1
  TCCR1A = bit (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = bit (WGM12) | bit (CS12);   // CTC, no prescaling
  OCR1A =  0;
  }

void loop (){
  }

you exclude a lot of values if you increment by 100 .... please post the code that reaches max freq

Note that when OCR1A-=100; makes TCNT1 lower than OCR1A you miss the compare match and have to wait a full second for the timer to overflow. Use waveform generation mode 15 instead of 4 (CTC) to avoid this.

Okay, I updated with the code that reaches the full freq. I intend to skip a lot of values in the increment as I am not trying to get every single value.
What does the changing to wave generation mode 15 do?

I'm not sure whether this is the real issue you have, but I spot an issue which can be the issue you have.
You wrote something like this:
if (pulseFromEncoder)
  if (direction1)
    OCR1A -= 100;
  else
    OCR1A += 100;

Now, the OCR1A is a unsigned 16 bit integer. A value of 100 corresponds to 1.6ms of delay on the timer (see comment from Edgar Bonet below). This is what happens when you rotate in direction 2:
        OCR1A  Time delay
Rotate:   300      4.8ms
Rotate:   200      3.2ms
Rotate:   100      1.6ms
Rotate:     0      0ms
Rotate: 65436   1047ms

See? The value rolls over and the time completely changes.
Now, maybe the issues are other (for instance changing the mode to 15 instead of 4 like EdgarBonet said (no idea on what this means, you should double check the differences on the atmega datasheet), but I strongly suggest you to fix this issue, for instance this way:
const uint16_t OCR1A_Min = 0
const uint16_t OCR1A_Max = 20000
const uint16_t OCR1A_Step = 100

...

if (pulseFromEncoder)
  if (direction1)
  {
    if (OCR1A > OCR1A_Min + OCR1A_Step)
      OCR1A -= OCR1A_Step;
    else
      OCR1A = OCR1A_Min;
  }
  else
  {
    if (OCR1A < OCR1A_Max - OCR1A_Step)
      OCR1A += OCR1A_Step;
    else
      OCR1A = OCR1A_Max;
  }

Sidenote: doesn't your encoder need debounce?

Re “let's assume the OCR1A is a unsigned 16 bit integer”: This is indeed the case. Re “Let's assume also that 100 corresponds to 1ms of delay”: It's actually 100 × 256 ÷ F_CPU = 1.6 ms.

@EdgarBonet Thank you, I updated the answer with your confirmations and fixed the data. As a side note, I was pretty close even if I gave a totally random value ;)

PWM doesn't vary frequency. It holds the frequency steady and varies the duty cycle of the output. (Percent of on-time to total time.) So unless fast Arduino PWM does something very unconventional, the answer to the question you asked is no.


text:
[Solved]How to make my stepper motor run clockwise and counterclockwise?
I'm relatively new to Arduino thus need your help to figure out why my stepper motor doesn't rotate clockwise and counterclockwise. All I could do was to make it rotate only in one direction.
I am using AccelStepper Library
Here is my code:

#include <AccelStepper.h>
//Define stepper motor connections
#define dirPin 4
#define stepPin 14
//Create stepper object
AccelStepper stepper(1,stepPin,dirPin); //motor interface type must be set to 1 when using a driver.
void setup()
{
  stepper.setMaxSpeed(1200); //maximum steps per second
}
void loop()
{
  stepper.setSpeed(1200); //steps per second
  stepper.runSpeed(); //step the motor with constant speed as set by setSpeed()
}

I have tried to add delay and counterclockwise code but its not working.
#include <AccelStepper.h>
//Define stepper motor connections
#define dirPin 4
#define stepPin 14
//Create stepper object
AccelStepper stepper(1,stepPin,dirPin); //motor interface type must be set to 1 when using a driver.
void setup()
{
  stepper.setMaxSpeed(1200); //maximum steps per second
}
void loop()
{
  Serial.println("clockwise");
  stepper.setSpeed(1200); //steps per second
  stepper.runSpeed(); //step the motor with constant speed as set by setSpeed()
  delay(1000);
  Serial.println("counterclockwise");
  stepper.setSpeed(-1200); //steps per second
  stepper.runSpeed(); //step the motor with constant speed as set by setSpeed()
  delay(1000);
}

Try to use lower values for spinning, let's say 150. Some drivers are easy overheating when using higher speeds.

it rotate only in one direction ... which direction is that?

No its not about heating or higher speed
If i put 1200 it move perfectly clockwise if i put value to -1200 it move perfectly counter-clockwise
But if i try to use both it creates problem

What hardware do you use? I mean, what is the stepper motor driver? There are some drivers which overheat easily and (due to built-in overheat protection) stop operation.

@smajli its not about heating
i am missing something with code
if i rotate in 1 direction only with default code it works fine.
Motor - NEMA17 5.5Kgcm Stepper Motor

Hi here it the reference to the library functions that are available in accelstepper library.
Go through the link, it will provide you the issues with your code and example for your application like @smajli said steps more than 1000 is unreliabe, here you can see setSpeed(float) function where setting negative or positive sign selects the direction and value set the speed of rotation.

than you for your input but i am still struggling to understand functions :(
i have changed speed to 1000 and behavior is still same

did you tried -500 and 500 ?

yes buddy seems i can't use delay function in loop but i am not getting how to use other function of this library or use millis function

From the AccelStepper website: link

Speeds of more than 1000 steps per second are unreliable

Try to change the speed to lower value, and let us know what is the outcome.

thank you for pointing out but still same behavior


text:
Debouncing interrupt using capacitor
I'm currently working on nodeMCU and need to use interrupt pin. I find out there are bouncing problem when using interrupt thus i use capacitor 100uF to solve this problem. The question is by using multiple interrupt pin, do i need multiple capacitor (one for each pin) or only one for all pin? The question arise because if I parallel the capacitor it would increase the capacitance and perhaps would create a problem(?)
I using interrupt pin for LM 393 speed encoder like this one
(for simplicity, i use switch to describe the encoder pin on schematic)
Basically work like switch but no floating pin since it is a comparator, always between high or low.
Schematic :

You are talking about an interrupt being used for some kind of switch closure, correct?

@timemage input of lm393 encoder

4 encoder using 4 different pin as input

The LM393 is as common comparator.  You're saying "encoder".  So this is confusing. Perhaps you should edit the question to link to the thing you're talking about.  And a diagram of what you're doing maybe of what you're proposing as a possible solution that you're asking about.

sorry for confussions i make, i attach the schematic and some additional info above @timemage

Yeah, that's definitely clearer.  I had about four different interpretations of it before.  It still doesn't quite make sense as drawn.  Being open collector, the LM393 that is part of your encoder boards acts to pull the signal to GND, rather than to VCC as you have modeled.  And It's not clear how the capacitors are supposed to work under the way you've drawn the model.  Just a warning, I'm not sure to what degree others will find this on topic.  So although we may refine the question it may get closed anyway.  We'll see.

Does the output of the encoder board really show bouncing? Thats normally only with mechanical switches. A ready to use module like you showed shouldn't do that. Or did you just assume, that is bounces?

the caps go in parallel to the "switches".

I suggest using a low pass filter where the capacitor is on the micro pin.  You can then add a series resistance to control your debounce time. I do not know the part but are you sure it has internal pull down resistors.


text:
Why does my TFT keep turning white after moments?
Alright, seems there is something wrong I am doing that I don't understand. Before I start explaining, my question is different than this white screen question.
First of all my TFT ST7735 is working very well with the below code, let's name it, code part 1:
#define USE_ARDUINO_INTERRUPTS true    // Set-up low-level interrupts for most acurate BPM math.
#include <PulseSensorPlayground.h>     // Includes the PulseSensorPlayground Library.
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <SD.h>

  #define TFT_CS        10
  #define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_DC         8

#define TFT_MOSI 11  // Data out
#define TFT_SCLK 13  // Clock out

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float p = 3.1415926;
int Variable1;
int ledState = HIGH;
//  Variables
int PulseWire = 0;       // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
int myBPM = 0;
const int LED13 = 13;          // The on-board Arduino LED, close to PIN 13.
int Threshold = 550;           // Determine which Signal to "count as a beat" and which to ignore.
// constants won't change:
const long interval = 1000;

unsigned long previousMillis = 0;
static uint32_t tsLastReport = 0;

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

  Serial.print(F("Hello! ST77xx TFT Test"));

#ifdef ADAFRUIT_HALLOWING

  tft.initR(INITR_HALLOWING);        // Initialize HalloWing-oriented screen
  pinMode(TFT_BACKLIGHT, OUTPUT);
  digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on
#else

  tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab

#endif

  Serial.println(F("Initialized"));

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  Serial.println("done");
  delay(1000);

}

void loop() {

  testdrawtext(" BPM: ", ST77XX_WHITE);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(2);

  int sensorValue = analogRead(A0);

  tft.print(sensorValue);
    delay(300);
  tft.fillScreen(ST77XX_BLACK);

}

void testdrawtext(char *text, uint16_t color) {
   tft.setCursor(0, 0);
 tft.fillScreen(ST77XX_BLACK);

  tft.setCursor(0, 0);
  //  tft.setCursor(10, 40);
  tft.setTextSize(2);
 // tft.setTextColor(color);
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextWrap(true);
  tft.print(text);
   delay(200);
}

Here is the video for Part 1 running very good with a random analog number.
Secondly, I have a simple Heart Beat circuit and it is working very well when I apply this getting_BPM_to_Monitor code into it. I don't have a photo for it but trust me it is working good so please, when I do attach the schematic don't focus too much on the hardware side, it might not be very perfectly stable but it is working fine for me.
Now, is the magic when I combine the Heart Beat which is getting_BPM_to_Monitor & TFT ST7735 circuit things don't seem alright and I think a code with a video is better explaining the issue than me. The below code, let's name it, code part 2:
#define USE_ARDUINO_INTERRUPTS true    // Set-up low-level interrupts for most acurate BPM math.
#include <PulseSensorPlayground.h>     // Includes the PulseSensorPlayground Library.
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <SD.h>

  #define TFT_CS        10
  #define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_DC         8
.
#define TFT_MOSI 11  // Data out
#define TFT_SCLK 13  // Clock out

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float p = 3.1415926;
int Variable1;
int ledState = HIGH;
//  Variables
int PulseWire = 0;       // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
const int LED13 = 13;          // The on-board Arduino LED, close to PIN 13.
int Threshold = 550;           // Determine which Signal to "count as a beat" and which to ignore.
int myBPM = 0;
PulseSensorPlayground pulseSensor;  // Creates an instance of the PulseSensorPlayground object called "pulseSensor"

static uint32_t tsLastReport = 0;

void setup(void) {
  Serial.begin(9600);
 // .  PulseWire = 3;
  pulseSensor.analogInput(PulseWire);
  pulseSensor.blinkOnPulse(LED13);       //auto-magically blink Arduino's LED with heartbeat.
  pulseSensor.setThreshold(Threshold);
  pulseSensor.begin();

  Serial.print(F("Hello! ST77xx TFT Test"));

#ifdef ADAFRUIT_HALLOWING

  tft.initR(INITR_HALLOWING);        // Initialize HalloWing-oriented screen
  pinMode(TFT_BACKLIGHT, OUTPUT);
  digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on
#else
  // Use this initializer if using a 1.8" TFT screen:
 // tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab

  // OR use this initializer (uncomment) if using a 1.44" TFT:
  tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab

  // OR use this initializer (uncomment) if using a 0.96" 180x60 TFT:
  //tft.initR(INITR_MINI160x80);  // Init ST7735S mini display

  // OR use this initializer (uncomment) if using a 1.54" 240x240 TFT:
  //tft.init(240, 240);           // Init ST7789 240x240
#endif

  Serial.println(F("Initialized"));

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  Serial.println("done");
  delay(1000);

  Variable1 = 90;

}

void loop() {

  testdrawtext(" BPM: ", ST77XX_WHITE);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(3);

  myBPM = pulseSensor.getBeatsPerMinute();
if (pulseSensor.sawStartOfBeat()) {
}

  tft.print(myBPM);
      delay(300);
  tft.fillScreen(ST77XX_BLACK);

}

void testdrawtext(char *text, uint16_t color) {
   tft.setCursor(0, 0);
 tft.fillScreen(ST77XX_BLACK);

  tft.setCursor(0, 0);
  //  tft.setCursor(10, 40);
  tft.setTextSize(2);
 // tft.setTextColor(color);
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextWrap(true);
  tft.print(text);
   delay(200);
}

Here is the video or this video for Part 2
Lastly, I provided the schematic for more reasoning opinion and it was provided by Easyeda.com and you have to have an account to view my schematic
Things I have tried...

I have modified TFT pins since Gtting_BPM_to_Monitor uses Timer1 & Timer2
I have added/remove a lot of delays
I have insertednoInterrupts(); and interrupts();

Edit 1 :
Here is a PNG of the schematic if and hopefully, it is clear enough.

Make it easy for people to help you. Copy your schematic somewhere people can see it without having to create an account. I for one have too many accounts, I do not want to be creating more accounts and risk getting more spam from overseas companies.

Good, I added PNG file.


text:
Why does this take more byte?
I am only replacing a portion of my code where I want to use the first method but as you can see it is making my sketch size little bigger
//if(iBPM >= 40 || iBPM <= 170 )
      {
      char iBPMwav[50];
      String thisString = String(iBPM);
      String stringThree =  "n" + thisString;
      stringThree =  stringThree + ".wav";
      stringThree.toCharArray(iBPMwav, 50);
      tmrpcm.play(iBPMwav);
      }

Sketch uses 29678 bytes (100%)
This is simple but at the end, I want to go from the number 40 up to 170, and this is why I want to use the first method.
//if(iBPM >= 40 || iBPM <= 170 )
  {
      if(iBPM == 71)
tmrpcm.play("n71.wav");
  else if(iBPM == 72)
tmrpcm.play("n72.wav");
  else if(iBPM == 73)
tmrpcm.play("n73.wav");
  else if(iBPM == 74)
tmrpcm.play("n74.wav");
  else if(iBPM == 75)
tmrpcm.play("n75.wav");
  else if(iBPM == 76)
tmrpcm.play("n76.wav");
  else if(iBPM == 77)
tmrpcm.play("n77.wav");
  else if(iBPM == 78)
tmrpcm.play("n78.wav");
  else if(iBPM == 79)
tmrpcm.play("n79.wav");
  else if(iBPM == 80)
tmrpcm.play("n80.wav");
  else if(iBPM == 81)
tmrpcm.play("n81.wav");
  else if(iBPM == 82)
tmrpcm.play("n82.wav");
  else if(iBPM == 83)
tmrpcm.play("n83.wav");
  else if(iBPM == 84)
tmrpcm.play("n84.wav");
  else if(iBPM == 85)
tmrpcm.play("n85.wav");
  else if(iBPM == 86)
tmrpcm.play("n86.wav");
  else if(iBPM == 87)
tmrpcm.play("n87.wav");
  else if(iBPM == 89)
tmrpcm.play("n89.wav");
  else if(iBPM == 90)
tmrpcm.play("n90.wav");
  else if(iBPM == 91)
tmrpcm.play("n91.wav");
  else if(iBPM == 92)
tmrpcm.play("n92.wav");
  else if(iBPM == 93)
tmrpcm.play("n93.wav");
  else if(iBPM == 94)
tmrpcm.play("n94.wav");
  else if(iBPM == 95)
tmrpcm.play("n95.wav");
  else if(iBPM == 96)
tmrpcm.play("n96.wav");
  else if(iBPM == 97)
tmrpcm.play("n97.wav");
  else if(iBPM == 98)
tmrpcm.play("n98.wav");
  else if(iBPM == 99)
tmrpcm.play("n99.wav");
  else if(iBPM == 100)
tmrpcm.play("n100.wav");
  else if(iBPM == 101)
tmrpcm.play("n101.wav");
  else if(iBPM == 102)
tmrpcm.play("n102.wav");
else
 tmrpcm.play("n170.wav");
}

Sketch uses 29024 bytes (101%)

You are using the String class which is pretty mighty and not light weight. It is always a good idea NOT to use the String class on MCUs.

Are you aware that iBPM >= 40 || iBPM <= 170 is always true?

@EdgarBonet No, I didn't know

Then you should learn what the operators >=, <= and || mean.

@EdgarBonet Yes I did look that up that after you mentioned and learned from somewhere else. Tell me about it what a huge mistake boy ha ha

I suggest having simpler file names (same size, always 3 digit numbers)
/// Return a text "n000.wav" ... "n255.wav"
/// depending on the parameter
char* makeFileName(byte i) {
  static char name[9] = "nxxx.wav";
  byte digit = i/100;
  name[1] = '0' + digit;
  i -= digit*100;
  digit = i/10;
  name[2] = '0' + digit;
  i -= digit*10;
  name[3] = '0' + i;

  return name;
}

Looks smart to me. I will try it today.

Alright, I like your idea.. changing the name of the files will be like loosen flywheel for me. Instead, I made your code into two versions the first for "nxx.wav" and one for "nxxx.wav"

While the Strings class makes a C/C++ program easy to understand and maintain, as stated in the comments, using the Strings class is a memory intensive option which should be should be avoided when memory is in short supply.  Such as on the embedded processors used in most Arduino platforms.
Here are 2 examples where Stings is used and not used.  Note the reduction from 2326 bytes to 734 bytes of program memory necessary to store the sketch in the embedded processor.
void setup()
{
}

void loop()
{
  uint8_t iBPM;
  uint8_t pointer;
  for(iBPM = 40; iBPM <= 170; iBPM++)
  {
    char iBPMwav[50];
    String thisString = String(iBPM);
    String stringThree =  "n" + thisString;
    stringThree =  stringThree + ".wav";
    stringThree.toCharArray(iBPMwav, 50);
//  tmrpcm.play(iBPMwav);
  }
}

Sketch uses 2326 bytes (7%) of program storage space. Maximum is 32256 bytes. Global variables use 27 bytes (1%) of dynamic memory...
void setup()
{
}

void loop()
{
  uint8_t iBPM;
  uint8_t pointer;
  for(iBPM = 40; iBPM <= 170; iBPM++)
  {
    char iBPMwav[50];
    pointer = 0;
    char temp_str[10];
//  String thisString = String(iBPM);
//  String stringThree =  "n" + thisString;
//  stringThree =  stringThree + ".wav";
//  stringThree.toCharArray(iBPMwav, 50);
    itoa(iBPM, temp_str, 10);
    if(iBPM < 100)
    {
      strncpy(&iBPMwav[pointer],"n0",2);
      pointer += 2;
      strncpy(&iBPMwav[pointer],temp_str,2);
      pointer += 2;
    }
    else
    {
      strncpy(&iBPMwav[pointer],"n",1);
      pointer += 1;
      strncpy(&iBPMwav[pointer],temp_str,3);
      pointer += 3;
    }
    strncpy(&iBPMwav[pointer],".wav",4);
//  tmrpcm.play(iBPMwav);
  }
}

Sketch uses 734 bytes (2%) of program storage space. Maximum is 32256 bytes. Global variables use 15 bytes (0%) of dynamic memory...

BTW: String use even more RAM than compiler can see. And String+String is awfully complicated, creating a lot of garbage  :)


text:
Why am only hearing noise or no sound?
Alright, there is something missing in the question, I was able to hear one sound of the files and the others apply to the question I asked and that is why I am wondering. what is happening!
Here is the code:
#include <SD.h>                      // need to include the SD library
#define SD_ChipSelectPin 4  //using digital pin 4 on arduino nano 328, can use other pins
#include <TMRpcm.h>           //  also need to include this library...
#include <SPI.h>

TMRpcm tmrpcm;   // create an object for use in this sketch

void setup(){

  tmrpcm.speakerPin = 9; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc

  Serial.begin(9600);
  if (!SD.begin(SD_ChipSelectPin)) {  // see if the card is present and can be initialized:
    Serial.println("SD fail");
    return;   // don't do anything more if not
  }
  tmrpcm.play("music.mp3"); //the sound file "music" will play each time the arduino powers up, or is reset
}

void loop(){

  if(Serial.available()){

    if(Serial.read() == 'p'){ //send the letter p over the serial monitor to start playback

      /* These are spkean Numbers */

     // tmrpcm.play("1-24bit.wav");
     // tmrpcm.play("1-16bit.wav");
     // tmrpcm.play("200-insane.mp3");
     // tmrpcm.play("music.mp3")       // Strangely this is the working perfectly with good sound
     // tmrpcm.play("200-standard.mp3");
        tmrpcm.play("200.wav");        // from https://evolution.voxeo.com/library/audio/prompts/numbers/index.jsp
    }
  }

}

Everything is good when I play this tmrpcm.play("music.mp3"); but the others I hear aliens sounds expect this tmrpcm.play("200.wav"); which I can hear the number two hundred but I feel the sound is 4-bit depth which very noisy. The files used in the code are here
For clarification previously, I thought it was amplifying issues which then I had to used LM386 but the sound was the same noise with tmrpcm.play("200.wav"); and later when I tried this tmrpcm.play("music.mp3"); I was shocked it worked perfectly like what I need it to be!  so I was curious I removed the LM386 and played this tmrpcm.play("music.mp3"); again and worked alright just maybe less volume.

Should I try to record a sound again with a lower pitch?

you renamed the sample file "music" to "music.mp3"? the library can play only prepared sound files https://github.com/TMRh20/TMRpcm/wiki

Yes, that is correct and it was working. I made to music.mp3 and  music.wav because I just was curious. I was going to rename 200.wav to 200 but did not know how my Mac was not allowing me.

So how I do play spoken numbers from 1 to 100 as prepared sound files? Can I record them?

@Juraj I'm so dumb that link you sent has the solution... I will try it when I go home... sorry I just hate to read so that why I skip links. They are a smaller version of books.

@Juraj - Alright, I guess since that time I been trying to follow the author instructions but as always l have to struggle... So I tried to create wav same as the one working https://imgur.com/a/TuMAYQa but  I can not get close to that info as seen here https://imgur.com/a/NjnggDd

@Juraj I guess I will stick with this one tmrpcm.play("200.wav"); and get over the noise I tried low pass filter but not working. I don't know!!

@Juraj - will you upload sample .wav has a spoken number and upload it to your Github because I'm frozen in this step and can not search further

This wonderful site https://www.online-convert.com/ doing what I need, just need to store a file to SD and test the sound!

Oh yeah, I am hearing my sound there now!

As @Juraj mentioned it was solved by changing the setting and I was able easily to play the sound when I matched the setting to this file:

So, I could not create one from scratch matches above setting but I was able to convert existing sound through this site
which allowed me to convert with desire setting and here finally the exiting sound has matched the setting:


text:
Adding zero padding to decimal values
I want to add zero before the float number like this:
010.0

The code I'm using is this:
if(value < 10){
  lcd.print(F("0"));
}

lcd.print(value);

But when the value is exactly 10, it adds the zero anyway:
0010.0

I tried something like this but haven't had any luck:
if(value < 10 && value != 10){
  lcd.print(F("0"));
}

How can I solve this issue?

- EDIT:
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3B, 16, 2);

#define turnOff 3
#define turnOn 2
#define gateStatus 8
#define btn 4

float ADC0, current, ADC1, voltage, ADC2, temp, watt;
int8_t state, btnState, btnPushed, btnToggle, lcdClear;
uint32_t deBounce = 0;

void setup() {
  analogReference(EXTERNAL);
  pinMode(turnOff, OUTPUT);
  pinMode(turnOn, OUTPUT);
  pinMode(gateStatus, INPUT);
  pinMode(btn, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  lcd.begin();
}

void loop() {
  digitalWrite(13, LOW);
  state = digitalRead(gateStatus);
  btnState = digitalRead(btn);

  if (!btnState) {
    if (millis() - deBounce > 200) {
      btnPushed = 1;
      deBounce = millis();
    }
  }
  if (btnPushed && btnState) {
    btnToggle = 1;
  }
  if (btnToggle && state) {
    digitalWrite(turnOn, HIGH);
    delay(5);
    digitalWrite(turnOn, LOW);
    btnToggle = 0;
    btnPushed = 0;
  }
  if (btnToggle && !state) {
    digitalWrite(turnOff, HIGH);
    delay(5);
    digitalWrite(turnOff, LOW);
    btnToggle = 0;
    btnPushed = 0;
  }

  for (int i = 0; i < 500; ++i) {
    ADC0 += analogRead(A0);
  }
  ADC0 /= 500;
  current = ADC0 * (2.5 / 1023.0);
  current = current / 0.211;

  for (int i = 0; i < 500; ++i) {
    ADC1 += analogRead(A1);
  }
  ADC1 /= 500;
  voltage = ADC1 * (2.5 / 1023.0);
  voltage = voltage * 20.2;

  for (int i = 0; i < 100; ++i) {
    ADC2 += analogRead(A2);
  }
  ADC2 /= 100;
  temp = ADC2 * (2.5 / 1023.0);
  temp = temp * 100.5;

  watt = voltage * current;

  lcd.setCursor(0, 0);
  if(voltage < 10){
    lcd.print(F("0"));
  }
  lcd.print(voltage);
  lcd.setCursor(5, 0);
  lcd.print(F(" V"));

  lcd.setCursor(9, 0);
  if(temp < 10){
    lcd.print(F("0"));
  }
  lcd.print(temp, 1);
  lcd.print((char)223);
  lcd.print(F(" C"));

  if (state) {
    lcd.setCursor(0, 1);
    lcd.print(F("   OUTPUT OFF   "));
    lcdClear = 1;
  }

  else {
    if (lcdClear) {
      lcd.clear();
      lcdClear = 0;
    }
    lcd.setCursor(0, 1);
    if (current < 10) {
      lcd.print(F("0"));
    }
    lcd.print(current);
    lcd.setCursor(5, 1);
    lcd.print(F(" A"));

    lcd.setCursor(9, 1);
    if (watt < 10) {
      lcd.print(F("0"));
    }
    if (watt < 100) {
      lcd.print(F("0"));
    }
    lcd.print(watt, 1);
    lcd.setCursor(14, 1);
    lcd.print(F(" W"));
  }
}

Then something else in your code is wrong. The if statement check for value being snaller than 10. If value is exactly 10, it will not execute. Please show a minimal compilable example code, that shows your problem. Then we can try to reproduce and solve your problem

@chrisl the code wasn't too long so I added the whole code to the question.

I currently cannot try that out myself, but you could try writing 10.0 (which is a float) instead of 10 (which is an int). And have you tried also printing the values directly to the serial monitor for debugging? Or inserting serial prints in the if statements, to check, if they get executed?

@chrisl I tried that and also 10.000 and 9.999. still the same! I can't print to serial monitor, it's standalone with no USB interface...

This looks like a rounding problem. If the number you want to print lies
within the open interval (9.95, 10), the condition value < 10 is true,
as the number is strictly less than 10. Obviously, value != 10 is also
true. Yet, lcd.print(x, 1) will round the number to the closest
multiple of 0.1, which in this case is 10.
I see no better solution than handling the rounding yourself. I would
use integers for the comparison, as they avoid all rounding issues:
// Print a float to the LCD in 2.1 format (xx.x), left padded with a
// zero if needed. Assume x < 100.
void printPadded(float x)
{
    // Left pad.
    int i = round(x * 10);
    if (i < 100) lcd.write('0');

    // Print the rounded value.
    lcd.print(i * 0.1, 1);
}


text:
How to repeat an IF statement
My LCD info is called from an IF statement but since it's clock and temperature info i don't want to just show the information but update the information constantly in real time.
i don't want to use (while) loop or any other "code-blocking".
Here's the whole code:
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2
int Heater= 3;
int Switch1= 4;

Time t;
LiquidCrystal_I2C lcd(0x27, 16, 2);
DS3231  rtc(SDA, SCL);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Push button

boolean oldSwitchState = LOW;
boolean newSwitchState = LOW;
boolean lcdScroll = LOW;
boolean lcdBacklight = LOW;
boolean lcdWelcome = LOW;

unsigned long previousMillis = 0;
const long BacklightTime = 10000;

void setup() {
  Serial.begin(115200);
  pinMode(Heater, OUTPUT);
  pinMode(Switch1, INPUT);
  lcd.begin();
  rtc.begin();
}
void loop() {
  float testTemp = sensors.getTempCByIndex(0);
  sensors.requestTemperatures();
  t = rtc.getTime();
  if(lcdWelcome == LOW){
      lcd.setCursor(0,0);
      lcd.print("Welcome, Admin!");
      lcd.setCursor(0,1);
      lcd.print("press Start");
  }

  // LCD
  newSwitchState = digitalRead(Switch1);
    if (millis() - previousMillis >= BacklightTime) {
      lcd.noBacklight();
      lcdBacklight = LOW;
    }
    else if ( lcdBacklight == LOW ){
      lcd.backlight();
      lcdBacklight = HIGH;
    }
    if ( newSwitchState != oldSwitchState ) {
       if ( newSwitchState == HIGH ){
       previousMillis = millis();
       lcdWelcome = HIGH;
       lcd.clear();
      if ( lcdScroll == LOW ){
        lcd.setCursor(0,0);
        lcd.print(testTemp);
        lcd.print("   ");
        lcd.print(rtc.getTimeStr());
        lcdScroll = HIGH;
      }
      else{
        lcd.setCursor(0,0);
        lcd.print(rtc.getDOWStr());
        lcd.print("   ");
        lcd.print(rtc.getDateStr());
        lcdScroll = LOW;
      }
       }
       oldSwitchState = newSwitchState;
    }
}

How can i update the functions inside the if(lcdScroll == LOW){} and else{} statements constantly to show on display?

please use true and false as boolean values

@Juraj thanks but does it make any difference?

I'm not clear on what your problem is - I don't see any blocking code here - you test the clock and the switches and either act on them or don't, which is appropriate. Also, what do you mean by "How to repeat an IF statement"?

Also, do not compare values with true, false, 1, 0, or HIGH or LOW, just write if (variable), by default all nonzero values will result in executing the if statement.

well your void loop() is already a while loop.....What is it that you are wanting to repeat that is not already happening?

@JRobert the problem is code inside if (lcdScroll == LOW){} only runs once but if i want to have the time to update in real time, time functions have to be in a loop not only run once.

Well, it runs once per loop(). If the rest of the code is implemented properly, loop() will be fast and you have everything you want. I don't see any blocking code like delays(), etc. So what was the problem again?

Maybe it is happening so fast OP can not see the scrolling - giving the appearance that it is only running once.???? What happens if you put some serial.println's in your code? Does the if statement get executed more than once then when you press "the button"???

@SimSon if we add a Serial.prinln("test"); to if (lcdScroll == LOW){} statement you'll see that when push button pressed the code inside that statement only runs once. i think what i need is a "state machine" to get this to work...

Ah, now I got it, see my answer

Like you suggested in your comment, you can implement a state machine, but the simplest would probably be setting a flag bool a_flag in this if(lcdScroll==LOW) clause and checking if(a_flag) in the highest scope of the loop() section. This is where you print("test");.
In respect to your code this will look like:
bool a_flag=false;
void loop() {
  // some irrelevant stuff
  if ( newSwitchState != oldSwitchState) {
    // some stuff
    if ( lcdScroll == LOW ){
      // stuff you would handle here
      a_flag=true;
    }
    else {
      // stuff you would handle here
      a_flag=false;
    }
  }
  if (a_flag) Serial.println("lcdScroll is LOW");
  else Serial.println("lcdScroll is HIGH");
}

Beside this general solution you could simply do the following in your specific case:
loop(){

  // your actual code

  if (lcdScroll) Serial.println("lcdScroll is LOW");
  else Serial.println("lcdScroll is HIGH");
}

i'm very new to this can you please implant that in the code so i can get the whole idea?

@newbie You need to clear this flag somewhere and I'm not sure where (probably in the corresponding else{}). I'll add an implementation of this soon...

See my example implementation. This will continuously print the corresponding message. Note also that the backlight will behave erronuously when millis runs over!

i asked this question both in reddit and arduino forum and they didn't/couldn't give me an answer. you sir are a legend. thank you and god bless you.


text:
MCP4725 I2C address
I want to use four of MCP4725 DAC module at the same time but it only has two I2C addresses which can be set via jumpers:

In page 10 of the datasheet it says:

Device Address Selection pin. This pin can be tied to VSS or VDD, or
  can be actively driven by the digital logic levels. The logic state of
  this pin determines what the A0 bit of the I2C address bits should be.

Is there anyway to set more than two addresses for this module? or any hack via hardware/software...

The MCP4725 has 3 variable address bits. A0 on which you have access and A1 A2 which can be chosen by the customer that bought the chips to create these breakout boards (see picture above). Perhaps there is a chance to get boards of two address series. I know, that's a bad advice if you just bought the boards, but if not this could be a chance to four boards on the bus.

There is a trick to this, and it involves considering one device "active" and all others "inactive".
You only ever work with one address, and that is the address of the "active" unit. All other units are on the secondary "inactive" address which you ignore.
The address pin of each unit is then connected to an IO pin, and can be considered a "chip select" pin.
The sequence, then, is:

Set unit one's A0 low and all other units HIGH.
Communicate on Address 0
Set unit two's A0 LOW and all other units HIGH.
Communicate on Address 0
Etc for each unit

Since you never communicate on Address 1 the rest of the "inactive" units ignore all the communication.

Thanks, If DAC1 output is for example 1024 and then I switch to DAC2 the value on DAC1 will reset to 0 or stays at that value?

The DACs only ever change their value if you change the value or if you reset the device by removing the power.

This concept will surely work, but the OP should be aware of that, he can not use this solution in a setup with variable/pluggable devices where scans of the I2C bus are necessary. (e.g. switching to a raspi may cause this).


text:
Powering Arduino AND Relays
I have a 5V (5.3V) switching transformer that goes to a 7805 voltage regulator and powers Arduino, Arduino controls 4 relays using BJTs. those relays getting power directly from the same power source.
Arduino and it's modules + LCD uses ~40ma, each relay consumes 70ma. total current is around 350ma lets say 400ma.
The problem is 5V isn't enough to power Arduino, modules, sensors and relays. LCD gets very dim etc...
it works with 9V but 7805 gets really hot ~70 centigrade while having a heat sink on!
If i remove the 7805 and switching power burns or something bad happens then there's nothing in between to protect the Arduino!
What's the solution for this situation?

EDIT: for anyone who may have the same problem; I solved the problem with using a proper switching power salvaged from an old USB type-C charger and removed the 7805 voltage regulator, there's no heat anymore and it's working perfectly.

switching 5.3V to 5V seems not high enough. The regulator needs some headroom to convert the voltage.

@chrisl i know but i don't wanna remove the regulator for safety reasons, on the other hand increasing the voltage causes heat! what do i do!

Use a switching regulator and increase the incoming voltage.

@Majenko a LM2575T, thanks.

Personally I like to use pre-built modules from model aircraft stores (called a BEC, SBEC or UBEC depeding on who you talk to). Cheap and ready built.

@Majenko i already have a switching module, should i remove the 7805 and connect it directly to Arduino? it's a chinese one and i'm afraid something might happen to it and damage the arduino after some time... it's a 220 to 5V.

5.3V is within specification for the Arduino's 5V pin.

@Majenko my arduino is a standalone arduino and don't have the smd voltage regulator. are you sure it's safe?

The Absolute Maximum rating for Vcc on an ATMega328P is 6V.

You would have to check the datasheets for your other devices, but in general 5.3V is perfectly fine, since it's pretty much within the USB specification of 4.75V to 5.25V (just rounding will give you 5.3V).

Also, how have you determined that it is 5.3V?

@Majenko using a multi-meter, i connected the switching power LCD gets a little bit dim when all 4 relays are on but meh it's fine. but there's no protection for my arduino and modules now IF switching power burns out or idk something happens...

Did you have anything connected when you measured the voltage?

@Majenko no nothing, so after a few minutes the switching power gets a little bit hot too... is that normal?

With nothing attached you will be measuring the open circuit voltage. That will measure high. Measure the voltage with your circuit connected.

@Majenko it's 5V when connected to arduino and drops to 4.5 when all relays are on, i found a usb type C rapid charger which is 5V/3A can i use it for my project?

Yes, you can. What rating is your current 5V supply?

@Majenko i think it's 1A but it's a chinese one, i don't trust it wanna use the usb C charger module, check this out.

Linear regulators such as the 7805 operate by dissipating the additional voltage until their rated voltage remains.
This - as you noticed - requires a higher voltage  than the rated voltage.
Some variants, labeled as LDO for low drop-out, have reduced requirements for this, but normal 7805 usually require around 7 V to operate correctly.
The difference to the rated voltage is dissipated as heat as per P = U * I, with U being the voltage difference, and I the current pulled by your circuit.
You can use the switching power supply directly, or use a more advanced voltage regulator like the R-78E5.0 directly from 9 V, which has far lower losses.
Another option would be using the 5V from the switching transformer to drive the (less delicate) relays, and use the 7805 only for the MCU and display, but you would still want to use a heat sink in that case.


text:
Controlling 16x2 LCD backlight (I2C module)
I've installed an I2C module on my 16x2 LCD so i don't have access to all those LCD pins to control the backlight LED.
BUT there is a 100 ohm smd resistor in series with anode of the backlight LED, i want to remove the resistor and use Arduino PWM to control the backlight or i can just replace that resistor with a 330 ohm or a 1K resistor.

Red box showing the resistor and blue box showing the Jumper.
Also I2C module itself have a jumper for LED backlight which also goes to that resistor...
Just wanted to ask here and make sure it is going to work before doing any modification to the LCD.
which way is better? is it going to work?

UPDATE: i used Arduino PWM and a 2n2222 transistor and was able to successfully control the backlight brightness via jumper pins of I2C module.

Possibly. Do you have a schematic of the I2C module?

@Majenko this is the datasheet i found

not sure why i got a down vote...

Probably because you were very vague.

@Majenko or maybe people really want to finish that down vote achievement ;)

It's hard to tell from that datasheet what backlight control there is. It looks like it's connected to pin 3 of the IO expander, and that 100Ω resistor you speak of is inline. What the back light jumper does I have no idea. In all probability you can remove the jumper, then one pin of it will connect to the anode of the back light for you to connect to wherever you want to drive it from.

@Majenko thanks man i'll try that, gonna delete this question because of that down vote!

Don't. I just cancelled it with an upvote.

@Majenko you're so nice, thanks again.

It's hard to tell from the limited information, but chances are the "backlight jumper" mentioned in passing in the datasheet can be simply removed.  This will then give you two pins.  One will connect to pin 3 of the IO expander, and the other will connect to the back light anode itself.
Which is which you will have to discover for yourself.  One of them will have the 100Ω resistor in line with it as well.
If you can't see the tracks (some black boards are hard to make them out) then you should get a digital multimeter and set it to continuity mode and probe the pins to see where they lead.
Once you have identified which pin is which you can connect the one that goes to the back light to your Arduino and drive it with PWM.


text:
Why Buzzer interfere with PWM?
This is the code:
#define TMST A2 // Thermistor
#define BZR 10  // Buzzer
#define FanP 11 // Fan

void setup() {
  DDRD = B11000000;
  DDRB = B00001111;
  DDRC = B00000000;
  TCCR2B = TCCR2B & B11111000 | B00000101; // pin 3 & 11 -> 245Hz
  T0 = 25 + 273.15;
}

void loop() {
  if (hallState > magnetDistance) {
    PORTB &= ~(1 << 0); // port manipulation -> LOW
    strcpy(WPStatus, "OFF");
    if (Alarm == 1) { // this will be set in setting menu
      if ((millis() - BZRT) > 500) {
        tone(BZR, 2300);
        BZRT = millis();
      }
      if ((millis() - BZRT) > 250) {
        noTone(BZR);
      }
    }
    else {
      noTone(BZR);
    }
  }
  else {
    PORTB |= (1 << 0); // port manipulation -> HIGH
    noTone(BZR);
    strcpy(WPStatus, " ON");
  }

  if ((millis() - fanTimer) > 2000) { // checks every 2 seconds if temperature changed
    Thermistor();
    if (TX <= 32) {
      analogWrite(FanP, 60); // Fan spinning speed
    }
    if (TX > 32 && TX <= 36) {
      analogWrite(FanP, 120);
    }
    if (TX > 36) {
      analogWrite(FanP, 255);
    }
    fanTimer = millis();
  }
}
float Thermistor() { // reading and calculating from thermistor
  VRT = analogRead(TMST);
  VRT = (5.00 / 1023.00) * VRT;
  VR = 5 - VRT;
  RT = VRT / (VR / 10000);
  ln = log(RT / 10000);
  TX = (1 / ((ln / 3977) + (1 / T0)));
  TX = TX - 273.15;
  return TX; // returning the temperature
}

The 5V buzzer connected to a PWM pin with a 100 ohm resistor, thermistor and fan are connected to Arduino like this:

simulate this circuit – Schematic created using CircuitLab
Why When buzzer is alarming fan stops spinning?

I have an idea why, but from that code snippet I cannot be certain. You need to post your whole code, since the part that will tell me if I am right in my surmise or not is the part you have replace with the comment "// defined Variables and stuff".

@Majenko the whole code is too long, but i added the part you mentioned.

Ta. Also, which Arduino are you using for this?

@Majenko Arduino UNO

"Use of the tone() function will interfere with PWM output on pins 3 and 11." https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/

the pin for tone() doesn't need to be a pwm pin

The tone() command uses Timer2 to generate the square wave (it triggers an interrupt which toggles an IO pin).
However Timer2 is also used to generate the PWM signal on pins 3 and 11.
Thus you cannot use tone() and PWM on pins 3 or 11 simultaneously.
The simple fix: use PWM from pins 5, 6, 9 or 10 to control your fan.

an off topic question; since i can't use that pin anymore and other pins are occupied, is it better to use a series of diodes to reduce the fan speed or a high wattage resistor would work?

A high wattage resistor would work. That is basically what is used in mains fans with the buttons that change the speed.

you're the best.

@newbie, you can use pin 10 for fan and pin 11 or any other pin for tone()

@Juraj then i have to rework the whole PCB, i already spent almost 2 month on this project. that's enough. thanks for the suggestion.

If you don't mind your sketch blocking while playing a tone there is TimerFreeTone

or you can change the timer used by the tone() library


text:
Measuring current directly with Arduino
Is it safe to measure current like this as long as measured voltage drop don't exceed 5V? I'm asking this because in almost all current sense circuits they used an opamp in their design.
Do I need a resistor between shunt resistor and ADC? Is there any noticeable current flowing to Arduino ADC that can damage it?

simulate this circuit – Schematic created using CircuitLab

Where do you connect the Arduino ground?

@EdgarBonet common ground.

You need to measure at the other side of the sense-resistor. Otherwise you'd always measure 0 Volts. The reason a lot of designs use an opamp, is so they can keep the sense-resistor as low as possible. Higher value sense-resistors will create higher voltage drops, resulting in a lower voltage supplied to the load.

@Gerben Thanks, corrected the schematic.

You should show (and connect) power source -  to Arduino GND. Normally, scematics are clearer when GND is at the bottom.

Maybe I wasn't clear enough... by “Where do you connect the Arduino ground?” I meant “Please, show the ground connection in the schematic.”

@EdgarBonet updated the schematic.

Let's imagine that you expect to have 1A of current going through your circuit.
Resistor of 0.1 Ohm will give you a voltage drop of 0.1V.
This causes two problems.
Firstly Arduino has a cheap ADC builtin. It's supposed to be easy to use, but not really precise. It has nonlinearities towards lower and higher range. You will get more precise reading when measuring voltages around 2.5V.
Secondly The precision of your measurement is cut by factor of 50. Arduino contains ADC that has resolution of 10 bits. This means that there are only 20 steps between 0V and 0.1V That's not really precise.
Solution? Use an opamp as "differential amplifier". If you multiply the voltage difference by 25 you will get 2.5V on the amplifier output when the resistor has 0.1V of drop on it. This value is much more precise when reading it by analogRead of the Arduino, and even a tiny change in voltage on the resistor will give you 25 times larger change on the amplifier output. This way it's much more precise and accurate.

I did dig into opamp "realm" and honestly a good opamp for sensing current is expensive, I was thinking to use Arduino and if i needed more accuracy i could use a 12bit ADC or increase the shunt resistor value a bit... but the question is; is it safe to connect shunt resistor directly to Arduino ADC or not.

This answer is true but not complete. You can use the internal 1.1V reference voltage for your ADC. So 0.1V would correspond to around 90 steps between it an 0V. So you can get usable but not great results with the built in approach. The diff-Amp is definitively the way to go.

@newbie I recently successfully used LM358 to boost the voltage 20 times for my battery charger feedback. They literally cost 6 cents each with free delivery from China. Just keep output in the "middle" of the voltage (2.5V)

@FilipFranik it is possible and I even purchased some LMC6482 which is way more superior to LM358 but it can't go all the way down to ground rail 0V, minimum in my case was 9mv (maximum 20mV!) which means it can't measure small voltage drops (5mV for example) on a 0.1 ohm resistor. beside you need four 1% resistors which should match two by two... it gets complicated... I want to measure current simply with Arduino.

@newbie The real power of Arduino is that you can use cheap hardware, but compensate for imprecise resistor values and hardware nonlinearities inside the software. If you want to go for precision just build the circuit, connect (expensive) ampmeter to it, and measure what ADC shows for each amperage. Then use linear interpolation algorithm to get precise values between measurements. You will get  more precision then you need this way.

There's a bad current flowing into your Arduino, if ADC voltage exceeds Vcc (5V). This undesired current can be limited by a resistor. But if there's such a high voltage across a shunt resistor, something else is wrong. You rather suffer from a too small voltage for useful measurement.
My first doubt is rather, whether it's safe for the shunt resistor.


text:
Why Arduino pins don't output 0 volt?
void setup() {
  pinMode(5, OUTPUT);
}

void loop() {
  analogWrite(5, 0);
  // or
  //digitalWrite(5, LOW);
}

Output is 0.003V and the tiny voltage causes the circuit to draw 20uA.
Is there anyway to get absolute 0V from Arduino PWM pin?

That is a quite tiny voltage. This is not a code issue, since you cannot do more that driving the pin to LOW (which is what happens, when you use analogWrite(pin,0). Please show us your circuit.

@chrisl I'm converting arduino PWM to analog with RC and OA and then use that voltage as a reference voltage for another OA...

To be clear, setting a voltage this precise can be very hard (also because this is in the range of noise). I'm not sure, if this even comes from the Arduino. It might as well come from the opamp circuit itself, since they are not build perfectly either. Depending on your exact circuit it might be better to use an extra circuit part for turning the opamp circuit really off, instead of letting it amplify noise.

@chrisl the 0.003V is from Arduino, of that i'm sure (tested it). it's just gonna count from 0V to 0.5V and then stay at 0.5V. can you please provide a link or anything related to that "extra circuit" you mentioned?

Where get's anything counted? I don't see something like this in your code. About the extra circuit: That was just a thought about cutting the power of the opamps (maybe through a MOSFET) or pulling the output of the opamp over a current limiting resistor to low (also with a MOSFET). Just a thought, not a full fletched circuit, that I could provide a link for

@chrisl i didn't add that counting to the code because it was unrelated to the question. using a mosfet/transistor is a good idea, i'll try that. thanks.

You probably won't get below 3mV even with a transistor (that's what the arduino already does). Do you really need to get below that tiny voltage, I mean, it's 4 times less than the pwm's (ideally filtered) resolution when running at 3V3. If so, the only chance I see is to use external circuitry

Inside the Arduino, a FET is turning on, shorting the output pin to the internal ground on the chip. If the ground of your external circuit is not at the same potential as the ground Inside the chip, your external circuit will see some voltage.  Now.... how could the two grounds be at different potentials?. Perhaps there is some current traveling through the wire connecting the two grounds! Make sure there is NO current in the wire that connects the grounds.

@Sim Son I suggested using a MOSFET after the amplification, because the problem seems, that the opamp amplifies the 3mV to an unwanted greater signal. Pulling the output of the amplification to a low voltage might be sufficient, so that the amplification itself doesn't matter at that point.

@newbie how did you actually test that those 3mV are comming from the arduino? Have any external circuitry been removed when you did so? Otherwise I would suspect those 3mV to be the opamp's input offset voltage.

@SimSon I disconnected everything form Arduino and then measured the voltage on pin 5.

https://majenko.co.uk/blog/what-exactly-gpio-pin

It doesn't output 0v because it's near impossible. 0.003v is in fact very low. The LOW output, according to the datasheet, can be as high as 0.8v (when powered by 5v) and still be considered valid.
LOW does not mean 0v. It means "below the voltage threshold that is considered a LOW".


text:
I need help for applying a logic to this code
Here's the code:
int softStart = A0;
int enable = A1;
int powerBTN = A2, powerState = HIGH, lastPowerState = HIGH;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 25;
unsigned long powerTimer = 0;
unsigned long powerHoldTimer = 0;
bool softStartENB = 0;

void setup() {
  Serial.begin(115200);
  pinMode(softStart, OUTPUT);
  pinMode(enable, OUTPUT);
  digitalWrite(enable, LOW);
  digitalWrite(softStart, LOW);
  pinMode(powerBTN, INPUT_PULLUP);
}

void loop() {
  int powerReading = digitalRead(powerBTN);

  if (powerReading != lastPowerState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay && !softStartENB) {
    if (powerReading != powerState) {
      powerState = powerReading;
      if (powerState == HIGH) {
        digitalWrite(enable, !digitalRead(enable));
        Serial.print("Normal start: ");
        Serial.println(digitalRead(enable));
      }
    }
  }

  if (powerReading == LOW) {
    powerTimer = millis() - lastDebounceTime;
  } else {
    powerTimer = 0;
  }

  if (powerTimer >= 1000 && millis() - powerHoldTimer >= 2000) {
    softStartENB = 1;
    digitalWrite(enable, LOW);
    digitalWrite(softStart, HIGH);
    Serial.print("Soft start started: ");
    Serial.println(digitalRead(softStart));
    powerHoldTimer = millis();
  }

  if (softStartENB && lastPowerState == HIGH && powerReading == LOW) {
    digitalWrite(enable, HIGH);
    delay(2000);
    digitalWrite(softStart, LOW);
    Serial.print("Soft start ended: ");
    Serial.println(digitalRead(softStart));
    softStartENB = 0;
  }

  lastPowerState = powerReading;

}

So the logic is as this:

By pressing powerBTN the enable pin toggles.
By holding powerBTN for 1 seconds softStartENB condition becomes true.
When softStartENB is true, if I press powerBTN again it sets enable pin to high and after 2 seconds softStart to low.

The problem is that after setting softStartENB to 0, lastPowerState = powerReading toggles enable pin to low but I want enable pin to stay high until I press powerBTN again to toggle it.

How can I apply the described logic?

should enable toggle when powerBTN is pressed for 1 second?

@jsotola It can't, because after holding it for a sec the 'softStartENB' flag becomes true and 'enable' can only toggle when 'softStartENB' is flase.

point 1. says nothing about softStartENB ... also, the softStartENB could be false at the beginning of the button press ... should enable be toggled when the button is released?

Your problem statement seems very incomplete. Once softStartENB becomes true, does it stay true forever? If not, which events toggle it back to false? Same question for softStart: can it ever change from LOW to HIGH? What happens if the button is pressed during the 2 second delay? Please, try to give a complete description of the desired behavior, preferably in the form of a state diagram.

@jsotola see the edit.

@EdgarBonet see the edit.

The device you are controlling has 3 states, OFF,  ON, and IN_SOFT_START. A short press of the button causes the device to toggle between ON and OFF.  A long press initiates IN_SOFT_START. A second press of the button in this state  then puts the device in state ON after waiting 2 seconds. Simple but you should draw it as a conventional state diagram. What about adding a timeout if, after entering state IN_SOFT_START, the user does not press the button again within a reasonable amount of time?

@6v6gt I can do all these later, right now the problem is that enable pin goes low after softStartENB flag becomes false.

I solved the problem by using JC_button library:
#include <JC_Button.h>

const byte softStart(A0), enable(A1);
int powerStates = 0;
bool enableState;

Button powerBTN(A2);

void setup() {
  Serial.begin(115200);
  powerBTN.begin();
  pinMode(enable, OUTPUT);
  pinMode(softStart, OUTPUT);
}

void loop() {
  powerBTN.read();
  Serial.println(powerStates);

  switch (powerStates) {
    case 0:
      if (powerBTN.wasReleased())
        switchEnable();
      else if (powerBTN.pressedFor(1000))
        powerStates = 1;
      break;

    case 1:
      if (powerBTN.wasReleased()){
        digitalWrite(enable, LOW);
        digitalWrite(softStart, HIGH);
        enableState = false;
        powerStates = 2;
      }
      break;

    case 2:
      if (powerBTN.wasReleased()){
        digitalWrite(enable, HIGH);
        delay(2000);
        digitalWrite(softStart, LOW);
        enableState = true;
        powerStates = 0;
      }
      break;
  }
}

void switchEnable() {
  enableState = !enableState;
  digitalWrite(enable, enableState);
}

I restructured your code as a finite state machine. There is a minimal number of "foreign" flags and almost a 1:1 relationship between the code and the state diagram.
You can test a simulation of it here: https://wokwi.com/projects/383445446722551809

int softStart = A0;
int enable = A1;
int powerBTN = A2;

enum State { OFF = 0, ON = 1, WAIT_ON = 2 , WAIT_OFF = 3, IN_SOFT_START = 4, SOFT_START_CONFIRM = 5 } ;
State state  ;
State oldState ;
bool stateChange = true ;

uint32_t inCurrentStateAtMs = 0 ;

void setState ( State newState ) {
  // forces change to new state
  inCurrentStateAtMs = millis() ;
  oldState = state ;
  state = newState ;
  stateChange = true ;
}

void setup() {
  Serial.begin(115200);
  pinMode(softStart, OUTPUT);
  pinMode(enable, OUTPUT);
  pinMode(powerBTN, INPUT_PULLUP) ;
  digitalWrite(enable, LOW);
  digitalWrite(softStart, LOW);

  setState( State::OFF ) ;

}

void loop() {

  if ( stateChange ) {
    //debug
    stateChange = false ;
    Serial.print("state changes to: ");
    Serial.println( state ) ;
  }

  switch ( state ) {

    case State::OFF : {
        if ( ! digitalRead( powerBTN ) && millis() - inCurrentStateAtMs > 100 ) {
          setState( State::WAIT_ON ) ;
        }
        break ;
      }

    case State::WAIT_ON : {

          if ( digitalRead( powerBTN ) && millis() - inCurrentStateAtMs < 500 ) {
            digitalWrite( enable, HIGH ) ;
            setState( State::ON );
          }
          else if ( digitalRead( powerBTN ) && millis() - inCurrentStateAtMs >= 500 ) {
            digitalWrite( enable, LOW ) ;
            digitalWrite( softStart, HIGH ) ;
            setState( State::IN_SOFT_START );
          }

        break ;
      }

    case State::ON : {
        if ( ! digitalRead( powerBTN ) && millis() - inCurrentStateAtMs > 100 ) {
          setState( State::WAIT_OFF );
        }
        break ;
      }

    case State::WAIT_OFF : {
        if ( digitalRead( powerBTN ) && millis() - inCurrentStateAtMs > 100 ) {
          digitalWrite( enable, LOW ) ;
          setState( State::OFF ) ;
        }
        break;
      }

    case State::IN_SOFT_START : {
        if ( ! digitalRead( powerBTN )  ) {
          digitalWrite( enable, HIGH ) ;
          state = State::SOFT_START_CONFIRM ;
        }
        else if ( millis() - inCurrentStateAtMs > 3000 ) {
          // timeout
          digitalWrite( softStart, LOW ) ;
          setState( State::OFF );
        }
        break ;
      }

    case State::SOFT_START_CONFIRM  : {
        if ( digitalRead( powerBTN ) && millis() - inCurrentStateAtMs > 2000  ) {
          digitalWrite( softStart, LOW ) ;
          setState( State::ON ) ;
        }
        break ;
      }

  } // switch

}  // loop

Please don't change the code behavior, in my code even if the enable pin is high and powerBTN held for 1 second, enable pin goes low. in any case the problem persist, the enable pin doesn't stay/goes high before and after softStart goes high and then low.


text:
Noisy analogRead
I'm trying to read voltage using Arduino, here's the code:
float r1 = 99700;
float r2 = 10004;
float adc, voltage;
unsigned long analog;
void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
  pinMode(A0, INPUT);
}

void loop() {
  for (int i = 0; i < 64; ++i) {
    analog += analogRead(A0);
    delay(1);
  }
  analog = analog / 64;
  adc = (analog * 2.441) / 1024;
  voltage = adc / (r2 / (r1 + r2));
  Serial.print(analog);
  Serial.print(", ");
  Serial.print(adc);
  Serial.print(", ");
  Serial.print(voltage);
  Serial.println(" ");
}

Had a VERY noisy reading and what I did was adding an external voltage reference (TL431) and also connected a 9V switching adapter to Arduino UNO. But I still had some noise in analog readings so as you can see in the code I'm taking 64 sample and averaging them.
After doing all those noise reduced a lot but not completely:

What else should one do to get an steady reading?
By taking 1024 sample noise will be removed but then I'm sacrificing performance...

your 0.46 looks very steady :) SCNR.  You might look at the sensor itself and it's wiring. Add capacitors ...

@DataFiddler it looks steady in that screenshot but it's not, after all the value IS depended on the raw analogRead...

the range of analogRead is 0 to 1023. you read 190. what are the magic numbers?

@Juraj the numbers doesn't matter i can calibrate it one way or other, what i want is an steady reading.

common ground is connected?

@Juraj yes they're connected.

What is it you are reading from? How is it wired to the Arduino?

@Majenko reading is from two 1% resistor voltage divider and wired on a breadboard.

I solved the problem by adding 3 capacitors:

220uF on the Arduino power supply.
100uF on TL431 output.
1uF on A0 input.

I also increased the sampling rate to 128 times (and removed the delay).
Here's the result, as accurate as my multimeter:

There's still 2mV difference in higher voltages which is because of my 2.5V reference voltage and Arduino ADC 10bit resolution (2.5 / 1024 = 0.002).

Effectively, Serial.begin(9600); and the lots of output control speed.

A/D converters are always noisy.  If you dive into the specific processor's specifications you may find a 10 bit A/D converter only has, maybe, 8 bits of meaningful data.  1) Have you verified the processor is tracking the voltage as expected by changing the voltage at the A/D converter's input?  2) What are you using as a reference voltage.  And, consider using exponential averaging instead of averaging a fixed group of A/D conversions.

@st2000 yeah it shows the correct voltages with ~2mV difference, the voltage reference is TL431. i don't even know what exponential averaging is! gonna google it now. thanks.

Looks like wikipedia calls it exponential smoothing, not exponential averaging.  Pick values based on powers of 2's to keep the math simple and adapt to embedded programming.


text:
I want to print onto serial monitor when it's detected the value change
This code is measuring distance from object by using the Ultrasonic Sensor and print onto serial monitor.
However, serial monitor constantly output values.
I want to print only one time if detected value not change.
and serial monitor print again only when detected value change.
and The above condition keeps repeating.
How can i change the code?
int distance ;
int trig = 3;
int echo = 2;

void setup()
{
  Serial.begin(9600);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
}

void loop()
{
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  distance = pulseIn(echo, HIGH) / 58;
  Serial.println(distance);
}

the loop() block keeps repeating over and over ... think about how you would remember what the value of "distance" was the last time around

Store the distance in another variable, like int distanceValue; and then you can do this: if(distance != distanceValue){Serial.println(distance); distanceValue = distance;}.

int distance;
int last_distance; // <== To hold the value from the previous pass
int trig = 3;
int echo = 2;

void setup()
{
  Serial.begin(9600);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
}

void loop()
{
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  distance = pulseIn(echo, HIGH) / 58;
  if (distance != last_distance) {  // <== Check if new distance is different
    Serial.println(distance);       //     Print only if the values are different
  }
  last_distance = distance;         // <== Store this loop's distance for next round
}

I recommend AGAINST providing fully functional code for beginner questions. When you do that newbies tend to copy/paste the solution without understanding it. It's more work for both you and the OP if you tell them how to solve it and then support them as they work through it, but ultimately the questioner learns more that way.