text:
Can't get "Burn Bootloader" working - Arduino Nano
This is a follow up from a previous question. I have one Nano working perfectly (I think) (Nano A) and another one (Nano B) which seems to be working but has no bootloader. So I am trying to use Nano-A as an ISP programmer to burn the bootloader into Nano-B. I am pretty confident with my hardware and Arduino IDE setup. See previous question for the details; Problems uploading with a new Nano
I have pasted below two screen sessions. The first shows the Arduino IDE Log when I (unsuccesfully) try to run "Burn Bootloader" - IT almost works! (but not quite). - So I beleive that there is not too much wrong with my setup.
The second session is me using running avrdude in "terminal" mode from a Windows command prompt. I have used individual "send" commands to send the ISP instructions required to programme a single word into bootloader flash memory and this all seems to work OK. So I don't understand why avrdude is not working when invoked by the IDE.
Arduino IDE Log (lengthy)
C:\Users\--\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\--\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM8 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\--\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : COM8
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.11s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: erasing chip
avrdude: reading input file "0x3F"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.04s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3F:
avrdude: load data lock data from input file 0x3F:
avrdude: input file 0x3F contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.04s

avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0xFD"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.04s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xFD:
avrdude: load data efuse data from input file 0xFD:
avrdude: input file 0xFD contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.04s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xDA"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.04s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xDA:
avrdude: load data hfuse data from input file 0xDA:
avrdude: input file 0xDA contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.04s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xFF"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.04s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
avrdude: load data lfuse data from input file 0xFF:
avrdude: input file 0xFF contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.04s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude done.  Thank you.

C:\Users\--\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\--\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM8 -b19200 -Uflash:w:C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex:i -Ulock:w:0x0F:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\--\Documents\ArduinoData\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : COM8
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.11s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex"
avrdude: writing flash (32768 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_cmd(): programmer is out of sync
avrdude: stk500_cmd(): programmer is out of sync
avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex:
avrdude: load data flash data from input file C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex:
avrdude: input file C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex contains 32768 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.00s

avrdude: loadaddr(): (b) protocol error, expect=0x14, resp=0xc0

avrdude: stk500_paged_load(): (a) protocol error, expect=0x14, resp=0x10
avrdude: stk500_cmd(): protocol error
avr_read(): error reading address 0x7e00
    read operation not supported for memory "flash"
avrdude: failed to read all of flash memory, rc=-2
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0xd1

avrdude done.  Thank you.

Error while burning bootloader.

avrdude session (short)

Note that when writing to the bootloader flash, using the "send" instruction, you have to supply the address as a "word" - i.e. 16bit address - hence 0x3C00. When usning the "read" instruction, the address is a "byte" (8 bit) address, hence 0x7800 - this is the same address.
Update: I have now managed to upload my original sketch to the application area of flash on this Nano using the "Sketch->upload using programmer" menu option of the Arduino IDE. So I do now have a useable Nano but I have still not solved my original problem i.e. this  Nano still does not have a bootloader. I would like to fix this problem becaue I am sure that I will want to update/modify my app int the future. So there is now an ancilliary question - i.e. is it possible to burn a  bootloader without erasing a pre-existing application? - Answer, I think is no because maybe you have to do a chip erase before writing to the bootloader area?

Dear timemage - once again that is really useful I will give it a try with the addresses that you suggest. The reason why I said 0x7C00 (which I now realise is wrong anyway) is that the hfuse setting is 0xDA which is binary 10111010 - i.e. the "BOOTSZ" bits are 01 which according, to the datasheet, should give a bootloader size of 1024 words. So is the correct start address 0x3C00?

Alright, so this is bizarre. I tried it here just as a sanity check. Although my setup is a bit different than yours, I don't have a normal nano to work with.  I'm using an UNO as my target but programming it to be a nano. There's essentially no difference hardware-wise.  I can confirm that it fuses 0xDA but puts the 512 byte optiboot program on it.  Apparently is basically NOP-sliding from the configured reset vector at 0x3C00 to where the bootloader code actually begins at what would be the UNO reset vector 0x3f00.  Anyway, it's stupid but it works.

Thanks again - I have now updated my question as suggested. Now that I have got my addresses sorted out I can see that the avrdude "send" commands are able to write into the bootloader area OK. So it's beginning to like my problem has  something to do with the way that arduino IDE invokes avrdude - I'll now look more carefully at this.

Show the wiring I guess.

I'm thinking that if I can get avrdude to  use Nano A as an ISP programmer in terminal mode, then doesnt this prove that the wiring is OK?

It suggests to me that it's not so bad that it is failing constantly.

I now semi-understand why the fuses are being set to start the bootloader area at 0x7800 - I thk that it's because the Arduino IDE supports a couple of different options for nano bootloaders. It's a  bit dumb I guess.

Yay! - I now have a fully working Nano with new bootloader and application loaded using this.
I have done so much that I'm not sure what the original problem was but the final change was modifying the "programmers.txt" file such that "Arduino as ISP" entry was changed as follows;
Original line;
arduinoasisp.protocol=stk500v1

Changed to;
arduinoasisp.protocol=arduino

I did this because I noticed that the menu option "Upload using programmer" (which worked) invoked avrdude with the parameter "-c arduino" whereas the "burn bootloader" option used "-c stk500v1" (which was not working).
I can't pretened that I fully understand but I'm happy that this now works and that I have now learnt enough to know where to start looking if I get similar problems in the future.
I should also add that I would never have got here without the help of @timemage - who has helped a lot - many many thanks

There are differences between stk500v1 and "arduino" in terms of how reset is explicitly handled and how signatures are read; otherwise they're the same.  I have no idea why this would fix your problem.  What is it that made you try this to begin with?

I looked closely at the Arduino IDE logs - especially the avrdude invokations - to see what the IDE was doing differently between (1) "Upload using programmer" (which was working) and (2) "Burn bootloader" (which was not working) and noticed that the "burn bootloader" invokation had the "-c stk500v1" parameter.

Well, I'm glad something is working. But I am skeptical that alone is the cause and solution.  It fails and then works again consistently with changing that option back and forth?

I suspect that the original problem was that there was something amiss in the supplied  configuration of the cheap chinese nano clone that I bought on eBay. I suspect that it may have been supplied without a bootloader, but I do not know this for sure. So  I cannot get back to my original starting point, unless I order another Nano from the same supplier, which I might do, just for the hell of it. At £3.00  it might be worth it just to prove my theory. I have purchased two other cheap Nano clones from other suppliers and have not had any problems. I share your skepticism.


text:
I am looking into putting sound files onto an Arduino Nano without a microSD card
I figured out how to install the sound onto the card from this site
https://github.com/charliegerard/dev-notes/blob/master/arduino/wavFilesWithoutSdCard.md
It says I need to use pin 11 on the Uno but would pin 11 on the nano work or not? I am getting these boards.
https://www.amazon.com/gp/product/B0713XK923/ref=ox_sc_act_title_3?smid=A2WWHQ25ENKVJ1&psc=1
Also, does anyone have good speaker suggestions, I'm going with these right now(https://www.amazon.com/CQRobot-JST-PH2-0-Interface-Electronic-Projects/dp/B0738NLFTG/ref=sr_1_6?dchild=1&keywords=speakers+arduino%5D%5C&qid=1607285501&sr=8-6)
I'm not sure if I'm giving enough information so just tell me if I need to provide you with more information.

what's special about pin 11?

It just says to use pin 11 so I'm just going to use it.

what is your end use? ... why do you wish to use wav files?

So I am trying to play an audio file at the click of a button and I don't have to use .wav files it just says that in the thing. But the audio file is super short so I can put it on the arduino without a microsd card holder.

Uno and Nano uses the same Atmel MCU, so pin 11 is the same on both.
And a for the speakers, Arduino CAN'T driver 8ohms load! You need a amplifier.

To add to the above for those wondering why pin 11: The OP is apparently using the PCM library for Arduino which is hardcoded to use OC2A, that is timer 2 output compare A: https://github.com/damellis/PCM/blob/v1.0/PCM.c#L108   Which is Arduino Pin 11 for these 328P models.

Is there a way I could use another pin?

source: Stack Exchange

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

sort: votes


text:
Connect RGB LED board to Arduino?
I'm trying to repurpose an RGB LED (pictured) and use an Arduino board I've just gotten to reprogram the lights. I'm very new to electronics engineering and I don't really know how to get started. How would I connect it to the Arduino? What kind of wire(s) would be best for soldering this to as well as connecting to the Arduino? Can this be programmed like any other LED?
Images:
https://i.stack.imgur.com/u14Bd.jpg
https://i.stack.imgur.com/2inQB.jpg

that is not an RGB LED ... it is three separate LEDs ... Vdd would probably connect to positive voltage ... one of the other pins would connect to a resistor, which would connect to ground ... circuits are plentiful on the web

Connect each of the 3 "L" wires to 3 separate digital IO pins of an arduino e.g. D8, D9, D10 via a resistor say 470 ohms but the value is not too critical. Connect VDD to the arduino +5v.
Use the arduino IDE write a sketch that configures pins 8 9 and 10 as outputs and then see what happens when you send these pins HIGH or LOW. Theres lots more you can do. Good luck.

Ah that makes sense! I thought the VDD was for ground. Thanks so much!

Given that the pin is labeled VDD, it's likely that the LEDs are common anode. (You'd hook the VDD pin to a positive voltage, and then connect the other pins to ground in order to light them.)
You really need to know the specs of the LEDs in order to calculate the size of the current limiting resistors.
Say your LEDs have a 1.2v forward voltage and can take 20 mA of current (.02 amps)
You'd use the formula R = (supply_voltage - LED_voltage)/current
so R = (5-1.2)/.020  = 190 Ω. Use the next higher value. (220 Ω for 20% resistors, the cheapest/most common kind you're likely to have access to.)
Try hooking each of the LEDs through a 220 Ω resistor to ground and seeing what you get. (Note that different colors of LEDs can have different forward voltages, so the forward voltage you use in the above calculation might be different for each LED.) If it barely lights, move down to the next-lower resistor value and try again. (150 Ω for 20% resistors.) If it's crazy-bright, or gets warm to the touch, use the next higher resistor value.
You'd then control the LEDs using PWM pins on your Arduino, and vary the duty cycle on 3 different output pins to vary the apparent brightness of the different colored LEDs. Note that since these LEDS appear to be common anode (Common power connection, and you switch the grounds to turn them on and off) the PWM values will be reversed. Setting a PWM pin to 0 will make that LED burn the brightest, and setting it to 255 will turn it off. That's because at 0, the pin is at 5V 0% of the time and connected to ground (which lights it) 100% of the time.

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


text:
Different Output Voltages from Same Source?
I'm wondering whether it is possible to wire multiple buck converters with different voltage requirements and amperage draws to the same power source (this idea is for controlling a radio-controlled boat). Going off other related questions this seems to be possible (1, 2).
My background is in programming, not electronics, so the terminology is difficult for me to understand. I'm getting a grasp on voltage and amperage. My problem is always understanding how electricity can be "split" into different modules. In my understanding, this below would be a parallel circuit and that should be fine.

Are there any gotchas to consider with this type of circuit, or is this the totally normal way of doing things (eg. like wiring a house out of a breaker box)?
Is there a better way to do this?
This won't cause a short circuit, right?

Are there any gotchas to consider with this type of circuit, or is this the totally normal way of doing things (eg. like wiring a house out of a breaker box)?

That's a perfectly normal way of wiring it.

Is there a better way to do this?

No, it's how I'd do it.

This won't cause a short circuit, right?

Not intentionally, no. However it's always good to add a fuse or two to protect everything just in case anything untoward should happen. Especially where water is concerned.


text:
listener for Plotter library doesn't work
I try to use Plotter to plot some data from my Adafruit Circuitplayground board, but the listener is kept showing "Scanning serial ports..." and not displaying any plot (as shown below in the picture).

I have java 1.8.0_271 installed (in order to run listener) and I put the listener folder under the same directory as the Arduino code file (though I'm not sure if there's a requirement of where to put the listener folder). Arduino is the latest version. Code is copied from the sample code of the Plotter library

close the console window

@jsotola if I close the Serial monitor Listener will be turned off automatically


text:
Storing and sequencing output value (Arduino)
I am new to Arduino programming, after days and nights trying to use array and for loop, and googling a lot of articles, I am still unable to find how to store each weighing output value from int Sampling() to be executed by the respective servo in sequence order.
If you have any clue to share and help me, I'll be very happy.
Below is my base code:
#include <HX711.h>
///////////////////////////////////////////////////////////////////////
#define calibration_factor -251
#define LOADCELL_DOUT_PIN 7   // data
#define LOADCELL_SCK_PIN 8    // sck
////////////////////////////////////////////////////////////////////////
HX711 scale;
////////////////////////////////////////////////////////////////////////
int servo1 = 12;
int servo2 = 13;
int proxiPin1 = 2;
int proxiPin2 = 3;
////////////////////////////////////////////////////////////////////////
int toggleState = 0;
int proxiState1 = 1;
int proxiState2 = 1;
////////////////////////////////////////////////////////////////////////
int weight;
int weightFinal;
////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale(calibration_factor);
  scale.tare();

  pinMode(servo1, OUTPUT); // simulating servo1
  pinMode(servo2, OUTPUT); // simulating servo2
  pinMode(proxiPin1, INPUT_PULLUP); // proximity
  pinMode(proxiPin2, INPUT_PULLUP); // proximity

}
/////////////////////////////////////////////////////////////////////////
void loop()
{
  Serial.print(Sampling());
  Serial.print(" gram");
  Serial.println();
  ///////////////////////////////////////////////////////////////////////
  if ( weightFinal == 10 )
  {
    toggleState = true;
    servo10gr();
  }

  if ( weightFinal == 20 )
  {
    toggleState = true;
    servo20gr();
  }
}
////////////////////////////////////////////////////////////////////////
int Sampling()
{
  int weight = scale.get_units();

  if (weight >= 10  && weight< 20)
  {
    weightFinal = 10;
  }

  else if (weight >= 20  && weight < 30)
  {
    weightFinal = 20;
  }

  return weight;
}
/////////////////////////////////////////////////////////////////////////
int servo10gr()
{
  proxiState1 = digitalRead(proxiPin1);
  if ( proxiState1 == 0 && toggleState == true )
  {
    digitalWrite(servo1, HIGH);  //Simulating servo signal Pin//
    delay(500);
    digitalWrite(servo1, LOW);

    toggleState = false;
    weightFinal=0;
  }
}
/////////////////////////////////////////////////////////////////////////
int servo20gr()
{
  proxiState2 = digitalRead(proxiPin2);
  if ( proxiState2 == 0 && toggleState == true )
  {
    digitalWrite(servo2, HIGH);    //Simulating servo signal Pin//
    delay(500);
    digitalWrite(servo2, LOW);

    toggleState = false;
    weightFinal=0;
  }
}

What do you need weight for? The servo functions don't use it. And what do you mean by each weighing output [...] in sequence order? You mean to store it in an array? Please describe what you want to achieve.

I am simulating conveyor. So first the scale weigh each object value and then the object send through a conveyor until the object separated by the servo depend on the object weight. I am using proximity switch to trigger the servo. In the code above,I am using LED to simulating servos to make the code shorter. If I am only using the code above, i cant weigh the new object before the previous object executed by the servo. If I do so, only the latest weight will be execute, so the previous object that is already on the conveyor will be executed by the wrong servo. Thank you

The speed of your loop depends on whether delay(500) is executed or not, inside your servo functions. I guess that's hard to control properly.

I am using LED to simulating servo() function on the above code that's why i am using delay(). In reality, I am using servo. My main problem is how to store value for each object weight to be executed later by the designated servo. Some people suggest me to use array. But after a week, I cant figure it out how to integrate the  button/ proximity switch with "for loop" .

It seems like you need to learn what arrays are and how to use them (explaining them on SE would go a bit too far). It's important to keep in mind that a typical loop() is executed thousands of times per second. There are some basic concepts (like BlinkWithoutDelay and finite state machines), that make your life easier.

Thank you for your suggestion @Sim Son. Yeah, I need to learn much much more about how to implementing structures to the program.

I'm still not entirely sure what you want to achieve, but maybe this will help:
You have a global variable int weight, and in int Sampling() you create another int weight = scale.get_units() which you give a value.
That second variable is only accessible inside of Sampling(). If you want to use it elsewhere for storing or in other functions, change:
int weight = scale.get_units();
to
weight = scale.get_units();
and you can then use weight wherever you like in your code, also in servo10gr() and servo20gr().
You don't need to store a sequence of weights to drive the servos; you can just use the current weight immediately to drive a servo and then get a new weight.
If, however, you want or need to keep a list of weights for some reason, there's a bit more work to be done.
There are better ways of going about this, but let's see first if this solves your problem.

First of all, i would like to say thank you for your kindness. I'll try to describe in another way. What i want to do is if my output value of each object (from the scale) was let say: 10gr>10gr>20gr>20gr>20gr>20gr>10gr> and so on, I want those each object(depend on it weight) is assign to the servo based on it designation servo, in this case servo10gr() or servo20gr(). Should I use array or another method to store those value so that those servo assignment will be executed sequencially  by the servos?. Ok I'll try different method by using  weight inside servo10gr() and servo20gr.

@FlipFlop as I understand your requirement, this answer will not solve your problem. What you need are arrays, because you want to store "a bunch" of values. What ocrdu explained is relevant, though. As arrays can't be passed as function arguments, you'll need to make them global.

Thank you Sim son for your willingness to give me suggestions.


text:
Trouble with ESP8266 on Eero network
I have an ESP8266 Node MCU and am learning to use its wifi capabilities. In my home I have a router provided by my ISP that runs a network we'll call 'network1'. I also have an Eero mesh network that runs in the house, called 'network2'.
When I upload the following minimal example and use network1,

my 8266 device connects to network1 (the messages in the serial monitor confirm this) and
I can use my phone and laptop to connect to the 8266 - i.e., I can put the IP into my browser and see a webpage telling me 'Hello World'.

However, I have trouble with network2, the Eero network.

I can connect my 8266 device to network2 (the messages in the serial monitor confirm this)
but
I can't connect to the 8266 device with my phone/laptop. (Yes, I switch these over to network2 first.) I put the new IP into my browser and I am told the page is taking too long to respond.

I haven't done anything special with my network1 router; things just worked. With network2, I've tried various settings with my Eero - given the 8266 a static IP address, enabled port forwarding (on port 80) and established a firewall rule for it, but nothing works.
I can run many different programs through network1, and nothing works on the Eero network. Any suggestions on getting things to work?
My minimal working example:
#include <ESP8266WiFi.h>

const char* ssid = "network1"; // or 'network2'
const char* password = "thepassword"; // real password used in code

WiFiServer server(80); //just pick any port number you like

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

  // Connect to WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
  //gateway = WiFi.gatewayIP();
  Serial.print("GATEWAY: ");
  Serial.println(WiFi.gatewayIP());

  // print your subnet mask:
  //subnet = WiFi.subnetMask();
  Serial.print("NETMASK: ");
  Serial.println(WiFi.subnetMask());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n\r\n";
  s += "\r\n";
  s+= "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\r\n";
  s+= "<title>ESP Web Server</title>\r\n";
  s+= "\r\n";
  s += "Hello World";
  s += "\n";

  client.flush();

  // Send the response to the client
  client.print(s);
  delay(1);
}

I'm not totally sure, but have you successfully connected any two devices on the Eero network? I wonder if you could add some Serial.println() to the loop() to verify that things are working as expected in network1 and then see where things break down for network2.

@garson Do you mean connecting two ESP8266s & have them talk to each other? I have done things like get my iPhone to screencast to my Roku; in that sense, I've had devices on the Eero network talk together just fine. But not any devices that I've programmed.

Yes, that's what I meant. Hmm. This suggests restarting the eero. https://support.eero.com/hc/en-us/articles/207613706-Help-I-m-having-trouble-with-my-eeros. Printing confirmations to the log when someone accesses the ESP (on network1, and then trying on network2) may point you in the right direction but I'm not sure.

no matter what, you want to use the server.on() methods instead of that painful low level packet handling in loop().

@dandavis Will that help with the Eero issue, or just make for better page building once I get to making real applications? At the moment, learning to write good code is secondary to getting something working.

I was able to find an answer though I'm not sure why it works. It comes down to adding WiFi.mode(WIFI_STA); in the setup, as in
void setup() {

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  ...
  }

I was able to replicate success with another file on my ESP8266 device and Eero network as well.


text:
How to get rid of low quality sound out from DFPlayer plus amplifier?
I use my Seeeduino V4, DFPlayer mini, and this speaker module from AliExpress to create an automatic doorbell.  The problem is that it seems that this speaker module's Yurobot amplifier is not powerful enough to create a noise-free loud sound. Also, the bundled speaker is 0.5 W, 8 Ω.
There is a volume selector on the speaker module. If it is selected to a value a bit higher than 0 then the sound's quality is quite high (click here to listen), but the volume is not enough by far for a doorbell, even though the DFPlayer's programmed volume is set to maximum.
But if I increase the amplifier's volume selector to something near maximum, I start hearing some very scary noises (please click here to listen).
How can I increase the volume without having hard-to-listen-to noises? Maybe I need to buy another, better amplifier?

The DFPlayer already has a 3W amplifier on it you can connect a 3W speaker to. If you connect an extra amplifier to the DPlayer and turn the volume of the DFPlayer up, the second amplifier will probably clip. You could try how the DFPlayer sounds when you connect a speaker directly to it; a 3w speaker would be good for this.

I don't have a 3W speaker currently at my's, so I can't do such a test. Also, my only speaker has a unique connector that is compatible with the speaker module I talked about in the question.

If you want a load sound, you should buy a speaker with the wattage of your amplifier (here the 3W amp of the DF player).

@chrisl, otherwise I'll get rasps and hard-to-listen-to noises?

I think that is because your extra amp module is clipping the sound,  since it reached its maximum amplification. In that case you get distorted sounds (that how the distortion with e-guitars works). But with the 3W speaker you could enable to full potential in the DF player and then see, if that is load enough. On aliexpress there is mostly few to none documentation, so we cannot know, how strong the amp module is. But judging from the speaker, that came with it, I would say, that it is weaker than the DF player.

Somewhat related: https://arduino.stackexchange.com/questions/79260/how-to-use-an-arduino-speaker-module-with-dfplayer-mini/79261#79261

can I use a 50 Ohm speaker? Are there the speaker's ohmnage restrictions?

Also, the datasheet says about a drive speaker **less** than 3W. Does this mean that I can use only 2W speakers maximally?

I would think, the "less than 3W" is just a not ideal phrasing. 2.99W would be less than 3, so like 3W max. I would interpret this as 3W max.

You can use a higher wattage speaker with the same impedance. If you have a 5W instead of a 1W and they are both 8 ohms you should be able use the 5W unit without any problems. I would expect the 50 Ohm to work but the sound level will be low. Wattage is the amount of power it can withstand, not its SPL or efficiency of the speaker. Generally increasing the impedance of the speaker is not a problem however lowering it can be very quickly cause problems.

The DFPlayer already has a 3 W amplifier on it, so you can connect a speaker directly to the DFPlayer. There is no need for an extra amplifier.
If you do connect an extra amplifier to the DPlayer, and turn the volume of the DFPlayer up too far, the input of the second amplifier will clip and it won't sound good.
Also, the output of the DFPlayer is probably from a class-D amplifier designed to be connected directly to a speaker; it won't play nice with other amplifiers.
You should try how the DFPlayer sounds when you connect a speaker directly to it. The 0.5 W speaker you have is not a good fit; it can't handle the power of the DFPlayer's amplifier.
A 3 W (or more), 8 Ω speaker would be good for this if you want to use the maximum power the DFPlayer can deliver. According to most publications on the interwebs a 2 W, 8 Ω speaker will also do, but I would be careful with turning the volume all the way up.
Note that the DFPlayer can pull a fair bit of current (about 25 mA in standby, and in the order of 200 mA when playing) and it needs a power supply that can deliver that.

I'm probably going to be playing with a couple of these soon and this contains some useful information to me.  Welcome to 1K.

@timemage: Thanks! Note that if you only need to play short sound bites for a user interface or something like that, the memory and DAC of anything SAMD21-based will also do.

The problem has been solved by buying a YD103-O4B 8Ohm 4W speaker. Thanks for the help!

Interesting! The wattage rating of the speaker does not affect its loudness, the efficiency does at a given wattage. Wattage is the maximum amount of power you can drive the speaker with, that does not indicate the source can provide more or less. The SPL (SPL stands for sound pressure level and is also commonly referred to as efficiency and sensitivity.  This parameter represents how loud a speaker is.  A higher SPL equates to a louder speaker). To get more volume out of a speaker you have to put more power in. Ohm's Law explained this. The impedance (AC Resistance) of the speaker varies with frequency but typically a nominal number such as 8 ohms is used.  Looking at Ohm's law the only way to get more power is to lower the impedance or increase the voltage with voltage being the most popular as well as the easiest. Putting more power into a speaker then it is rated at will eventually destroy it as well as distort the sound. This may not be noticeable to the human ear at low amounts but it is there.  Also the sound coming out is directly related to the signal going in. Clipping is a common occurrence when the amplifier is being over driven ie. it is asked to put out a higher voltage then it is capable of. There is an old saying garbage in garbage out. That includes the components as well. To solve your problem you probably need an amplifier capable of doing what you want and a speaker that will at a minimum handel the worse case power you will send it.

I am sorry if my questions are stupid, but is it possible to calculate the SPL of a speaker? Actually, this answer is very interesting, but it actually seems like I will need to experiment with multiple speakers... This will take a long, according to AliExpess' shipping durations. I actually hope that a 2W 8Ohm speaker will work correctly without an amplifier, but directly connected to the DFPlayer, as had people suggested some time ago.

It is relative involved with math. The easiest is to use a calculator. A good one is found here: https://myhometheater.homestead.com/splcalculator.html This works quite well. Have fun with it!

i was experiencing the same phenomen in my project , and got to this page in my research . I am using a tda 2003 amplifier and the speaker is a intercom that i modify so changing the speaker is out of question also the amplifier is a good and versatile . The problem is in the gain setting of the amplifier . I was using a 220ohm resistance on the gain setting . going back an forth i was getting better sound with low gains. i hooked up a potetiometer in the place of the resistance to fine tune the gain aand at 8 ohms i get the sound that i want.


text:
Changing address of MPU 9250 connected to ESP32
Can I change the I2C address of a device (MPU9250) connected to ESP 32 using int pin. I understand that in arduino board if we connect the int pin to A0 the default I2C address of MPU 9250 changes from 0x68 to 0x69. Is something similar possible with ESP 32? Which Pin I should connect to?

you are misunderstanding how A0 pin is used ... if it is connected to GND then the address is 0x68 ... if it is connected to Vcc then the address is 0x69 .... your question is not about the arduino, so it is off topic here

You have only two choices with this device on an I2C bus.  As stated in the datasheet:

So it's either:

0b1101000
0b1101001

The AD0 pin selects which of these two addresses are used.
The complete datasheet can be viewed at the following link as well as other places:
Datasheet


text:
How to read an analog value on ESP32-CAM with the SD card reader enabled?
I use an ESP32-Cam module for a project for which I need both the SD card and the cam. According to this page, the only pins that are not in use by either the camera or the SD card reader are GPIO0, GPIO2 and GPIO16. However, I need to read an analog value, which is only possible with the pins 12-15, 2 and 4, as the Arduino forums state, which are all in use by the SD card reader.
However, I came across a way to make the SD reader leave the GPIO4 pin out, namely by initializing it with
SD_MMC.begin("/sdcard", true);

Now the flashlight does not light up anymore when accessing the SD card, which means that there is no output anymore to GPIO4. However, it still does not allow me to read the pin after the SD card has been initialized. I also tried "converting" the pin to a GPIO through
pinMode(4, FUNCTION_3);

but it did not make a difference.
So my question is: How can pin 4 be used to read analog values while still keeping the SD card reader functional? And if this is not possible, is there any other way to read an analog value into the ESP32-CAM?

According to the schematic and pin notes, I don't think you can use GPIO4 as an ADC input (it can be used as a GPIO pin and technically it can be configured as an ADC pin), but it has a 47k pull-up resistor on it, making it not possible to be used as an ADC input.
Depend on your hardware wiring skill, one alternative is to use an external ADC chip with i2c interface (such as an MCP3221) and connect it to TWI_SCL and TWI_SDA, but those pins are only available on cam-connector, not on the header pins.

Thank you. I ended up using FTP instead of the SD-Card, which gave me "a lot" of digital pins. Then I connected an ADC-i2c-chip - as suggested - to two of them.


text:
How can I have different routines fire off at different intervals
I'm making an interface that will have a digital clock....once a second..
I'd like to do other things at different intervals but if I delay(1000) then I have to wait that second which is now the minimum other things have to run at.

this has been asked over and over ... study the blinkWithoutDelay example sketch in the arduino IDE and please, do some research ... akso look into FSM (finite state machine)

You can also Google and research "nonblocking cooperative multitasking." I've written about it pretty extensively in my answer here: https://stackoverflow.com/a/50032992/4561887. Start with Blink Without Delay though first to get the gist of the concept.

https://github.com/jandrassy/KitchenTimerClock/blob/master/KitchenTimerClock/KitchenTimerClock.ino

As said in the comments: you should read up on State Machines and have a close look at the Blink Without Delay example.
To get you started with an example closer to what you want to achieve, have a look at the code below; it will count seconds without blocking the loop.
unsigned long int secondsTimerMillis;
int seconds, minutes, hours = 0;
int secondsInterval = 1000; //ms

void setup() {
  Serial.begin(9600);
  // More setup() stuff goes here
  secondsTimerMillis = 0;
}

void loop() {
  if ((millis() - secondsTimerMillis) >= secondsInterval) {
    seconds++;
    secondsTimerMillis = millis();
    Serial.println(seconds);
    // More stuff you want to do every second goes here
  }
  // More loop() stuff goes here
}

This is just the basic mechanism, and it won't be very accurate without some way of adjusting the clock every now and again.
You will also have to add code for checking seconds == 60 and increase minutes / reset seconds when needed; the same goes for hours.
Having/handling other events at other intervals is just more of the same.
Note that using a Real Time Clock as the basis for your timing would make your life programming much easier, and your clock more accurate, but I am assuming you want to do this "by hand".

If you want a clock, your best option is... to buy a clock. Or, more
precisely, an RTC module. Not only will it be way more accurate than
your Arduino, it will also be able to keep the time off battery when
your project is powered off.
If you really want to rely on the (unreliable) timing capabilities of
your Arduino, you may want to try the millis()-based fake RTC provided
by the Adafruit RTClib library: RTC_Millis. Example
usage:
#include <RTClib.h>

RTC_Millis clock;

void setup() {
    Serial.begin(9600);
    clock.begin(DateTime(F(__DATE__), F(__TIME__)));
}

void loop() {
    static DateTime last_time;
    DateTime now = clock.now();
    if (now != last_time) {
        char buffer[] = "hh:mm:ss";
        Serial.println(now.toString(buffer));
        last_time = now;
    }
}

Note the test if (now != last_time), which is equivalent to the test
if (currentMillis - previousMillis >= interval) of the Blink Without
Delay tutorial (the RTC has a resolution of one second). It allows the
code to be non-blocking.
Note also that, if you are willing to measure you clock's drift rate,
you could calibrate-out that drift by using RTC_micros instead,
and calling the adjustDrift() method in setup().


text:
How the light brightness stays constant when we increase the frequency of stroboscope
Well I am trying to make a Stroboscop. I found this code at blow: and tried. It works normally. But if I increase the RPM so decrease the "strobeDelay" time, the brightness of the LEDs goes out. Even if I try the GreatScott code. The same problem persists at high RPM. I am using power LED.
On the other hand there is a stroboscop which is Fluke 820, it says

Features high-intensity 7-LED array—4,800 Lux @ 6,000 FPM/30cm

How they achieve that constant brightness under the high frequency?
    // Gray text are just helpful comments, you don’t need to type them. :)

/******* -----=====!! EASY STUFF TO MESS WITH !!=====------ ******/

  // What analog pin should we use to read the value from the potentiometer?
  int analogPin = 2; // Yep, you heard right: The coolest of the Analog pins...

  // What pin is the LED connected to?
  int ledPin = 13; // Contains a built in resistor!

  // How much time should the light stay on between delays, in Microseconds (millionths of a second)?
    /* Big number = more blur, more perceived brightness
     * Small number = less blur, less perceived brightness  */
  long onTime = 250;

  // What should the minimum delay be in milliseconds (thousandths of a second)?
  // This sets the bottom delay range of the strobe, as a delay of 0 doesn't actually flash =P
  // The strobe starts with this as the "fastest" mode, and goes slower from there, adding to the delay
  int minDelay = 1; // 1 is the lowest we can actually do without a better delay function

  // What should the maximum delay be in milliseconds?
  // This is the longest time that the biggest potentiometer value will be mapped to, and longest
  // time between strobe flashes.
  int maxDelay = 100;

/******* -----=====^^ EASY STUFF TO MESS WITH ^^=====------ ******/

// Initialize the number to hold our strobe delay. Isn't used till we get to the main loop
long strobeDelay = 0;

void setup() {
 pinMode(ledPin, OUTPUT); // Setup ledPin as an output.
}

void loop() {
  // To make the math easier, we use map(value, fromMin, fromMax, toMin, toMax) to convert the
  // 0 to 1023 range we get from analogRead, into our strobe delay range of 1 to 100 :D
  strobeDelay = map(analogRead(analogPin), 0, 1023, minDelay, maxDelay);

  digitalWrite(ledPin, HIGH); // Switch the ledPin to HIGH, turn it on!
  delayMicroseconds(onTime); // Delay while on, for the given onTime.
  digitalWrite(ledPin, LOW); // Switch the ledPin to LOW, turn if off!
  delay(strobeDelay); // Delay while off, for given strobeDelay.
}

For those who wonder there is a video, but another brand same result, brightness constant even if RPM changes. I tried 2 different power LED. on of them is this, the other LED is I found in a broken projector, I used them 2 working strip. No doubt in your mind, this led strip is very bright at low frequency. Both of them same result like this:

How are you driving the LEDs?

I think the answer is in the comments on the code you posted:    Big number = more blur, more perceived brightness * Small number = less blur, less perceived brightness Short duration makes for lower perceived brightness. The actual brightness is the same, but our eyes see it as less when the duration is shorter.

I don't think the term RPM applies here. What do you mean by it? What parameter are you changing and what exactly is the effect, that you see with what values? The analogRead() currently only changes the delay between the pulses. The onTime stays constant. Each pulse will be as bright as the other one. Though you might see the overall brightness rising with lower delays, as your eyes will start tying the pulses together - more pulses per second means more overall brightness.

@Majenko a npn channel mosfet (IRFZ44N) datasheet is here https://datasheet.octopart.com/IRFZ44N-Inchange-Semiconductor-datasheet-15981338.pdf

@chrisl Actually your says looks absolutly right, but in realty not works.I've never heard of it yet, but is there a time required for the leds to flash? I will change leds and try again.

@chrisl same result nothing changed. I think I need very shiny leds

Leds can be modulated very fast, much faster than your 1kHz. The led module is probably not the problem.

To keep the same brightness, you have to keep the same duty cycle (percent of on time over off time).  So to change the rate without changing the brightness, you have to increase
delayMicroseconds(onTime) by the same percent you increase delay(strobeDelay).  But note that as you go slower, the on time will be too long to freeze the motion you are trying to study.  (If it's just for a party effect this may not matter.)

Try delayMicroseconds(strobeDelay*250); (instead of delayMicroseconds(onTime);). This should give you the same perceived brightness, not matter what speed/"RPM" is selected.

nice idea, I will try tomorrow and write here the result

@Gerben same result nothing changed. I think I need very shiny leds


text:
Trouble obtaining values from Nextion screen to Arduino
Currently I have a setup running an Arduino BME 280 sensor and a 4.3" Nextion screen. What my program does is sent all the calculated values from the BME to numbers and progress bars in my Nextion on a screen called "Run".
This page consists of 3 values: Delta T, Temperature and Humidity as well as 3 buttons for an alarm. Each of these displayed values is connected to their own progress bar. Each of the individual values has a lower and upper alarm setting which can be adjusted on a following Nextion screen called "Settings".
So basically what I am struggling with is obtaining the obtaining the values from my "settings" screen to write the "if" function in my Arduino i.e (if the button is enabled on the run page and the value is less than X on the "Settings" page or more than Y on the "Settings" page, sound the alarm).
I have used the .getValue function, but it does not return a value to my Arduino program. Can anyone please assist. It will be highly appreciated.
// Include required libraries
#include <NexTouch.h>
#include <NexDualStateButton.h>
#include <NexNumber.h>
#include <NexProgressBar.h>
#include <NexText.h>
#include <Nextion.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

//Define BME parameters
#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C

//Define variables
int Delta_T;
int Temp_disp;
float Temp_wb;
float Temp;
int rh;

//Define NEXTION variables
//Transport Page
NexNumber Trans_deltaT = NexNumber(2, 10, "n0");
NexNumber Trans_T = NexNumber(2, 11, "n1");
NexNumber Trans_H = NexNumber(2, 12, "n2");

//Run Page
NexNumber Run_deltaT = NexNumber(3, 14, "n0");
NexNumber Run_T = NexNumber(3, 15, "n1");
NexNumber Run_H = NexNumber(3, 16, "n2");
NexDSButton Delta_Temp= NexDSButton(3, 12, "bt0");
NexDSButton Temperature= NexDSButton(3, 22, "bt1");
NexDSButton Hum= NexDSButton(3, 13, "bt2");

//Settings Page
NexNumber DT_min= NexNumber(4, 5, "n6");
NexNumber DT_max= NexNumber(4, 12, "n3");
NexNumber T_min= NexNumber(4, 6, "n7");
NexNumber T_max= NexNumber(4, 14, "n4");
NexNumber Hum_min= NexNumber(4, 7, "n8");
NexNumber Hum_max= NexNumber(4, 16, "n5");

NexTouch *nex_listen_list[] = {
  &Delta_Temp,
  &Temperature,
  &Hum,
  &Run_deltaT,
//  &DT_min,
//  &DT_max,
//  &T_min,
//  &T_max,
//  &Hum_min,
//  &Hum_max
    NULL
};

void Delta_TempPopCallback(void*ptr) {
  uint32_t DT = 0;          // Button State
  uint32_t DT_act = 0;
  uint32_t DelT_min = 0;    //Define DT_min setting
  uint32_t DelT_max = 0;    //Define DT_max setting

  DT_min.getValue(&DelT_min);
  DT_max.getValue(&DelT_max);
  Delta_Temp.getValue(&DT);
  Run_deltaT.getValue(&DT_act);

  Serial.println();
  Serial.println();
  Serial.println(DelT_min);

  // Read value of dual state button to know the state (0 or 1)

  if (DT == 0 && DT_act < DelT_min || DT_act > DelT_max) {  // If dual state button is equal to 1 (meaning is ON)...
    digitalWrite(2, HIGH);  // Turn ON internal LED
    Serial.println("ON");
  } else {                  // Since the dual state button is OFF...
    digitalWrite(2, LOW);   // Turn OFF internal LED
    Serial.println("OFF");
  }
}

void setup() {
  Serial.begin(9600);
  bme.begin();
  pinMode(2, OUTPUT);
  Delta_Temp.attachPop(Delta_TempPopCallback);
}

void loop() {
  Temp = bme.readTemperature();
  Temp_disp = Temp;
  // Serial.print("Temperature = ");
  // Serial.print(Temp);
  // Serial.println(" *C");

  rh=bme.readHumidity();
  // Serial.print("Humidity = ");
  // Serial.print(rh);
  // Serial.println(" %");

  Temp_wb = atan(0.151977 * pow(rh + 8.313659, 0.5)) * Temp + atan(Temp + rh) - atan(rh - 1.676331) + 0.00391838 * pow(rh, 1.5) * atan(0.023101 * rh) - 4.686035;
  // Serial.print("Wet Bulb Temp= ");
  // Serial.print(Temp_wb);
  // Serial.println(" *C");

  Delta_T=Temp-Temp_wb;
  // Serial.print("Delta T=");
  // Serial.print(Delta_T);
  // Serial.println(" *C");
  // Serial.println();

  Trans_deltaT.setValue(Delta_T);
  Trans_T.setValue(Temp_disp);
  Trans_H.setValue(rh);

  Run_deltaT.setValue(Delta_T);
  Run_T.setValue(Temp_disp);
  Run_H.setValue(rh);

  nexLoop(nex_listen_list);

  delay(50);
}

What do you mean by "does not return a value"? Why don't you print out more of the values you're trying to read to get more debugging info - at least all of those that you're using in the if? Also I'd recommend you put parens in expressions like a && b || c . (a&&b)||c and a&&(b||c) are very different and C precedence rules are not always intuitive.

I had to repeat the getvalue code multiple times, there seems to be a bug which a youtuber pointed out in his video.
https://github.com/rvxfahim/AHU-Firmware/blob/main/development_HMI.ino
you can see from line 133, I called it so many times to be safe because it sometimes returned nothing or probably returned zero I don't remember it was a long time ago.


text:
Is there any better choice other than using delay() for a 6-hours delay?
I am designing an incubator system and I need to drive a motor forward and reverse every 6 hours. Is there any better choice other than using delay()? A 6-hours delay seems a little unprofessional.

Use an RTC chip.

Explanation please if you don't mind

https://www.circuitbasics.com/how-to-use-a-real-time-clock-module-with-the-arduino/

A 6 hours delay seems a little unprofessional. The unprofessional attitude comes from the more important, but ignored questions: - Does it matter when/if the Arduino was restarted/reset while running? - Is it useful to have any feedback about the actual state of the cycle? - Which is the required accuracy for those 6 hours? - Is it useful/required to synchronize that period to some real world clock?

How accurate do you need the 6 hours to be, and what processor/plaftorm are you using? Many processors will have sleep modes where you can just tell it to sleep for a given time (though in many instances that will look like a reset it wakes up, so you need to save some state and check the boot reason on startup), but precision is often not very good.

Several options here, and a couple folks have pointed out some challenges.
"Best" answer -- probably to use a real-time clock (RTC) board to assist your timing, and effectively set a target time (next motor run is at 23:14...) each time the cycle restarts.  By saving this target off (to the EEPROM or an SD card for instance), you'd protect against a potential shutdown and reset of the arduino in the middle.
Secondary answer; set your loop() to include a relatively short delay() statement, then check the elapsed time since the last motor engagement.  This would allow you to have other items processing, as someone else noted in this thread.  This I've pseudocoded below.
unsigned long lastMotorRunTime;

void loop()
{
    /*
     * do whatever
     */
    if(millis()-lastMotorRunTime > 21600000)  // 6 hours have passed
    {
         runTheMotor(); // placeholder for the motor movements you need
         lastMotorRunTime = millis();
    }
   /*
    * do other stuff
    */
   delay(100); // loop about every 1/10 second, or whatever works
}

Given you don't seem to need detailed precision -- a few seconds either way wouldn't matter -- this should work reasonably.  Note it WILL fail if the Ardiuno is reset -- then it will only (in my pseudocode) rotate the motor 6 hours after the last Arduino reset.  Probably better to assume that an arduino reset means move the motor 'now', if the point is to ensure periodic motion rather than precise timing.
For precise timing, as noted, the RTC would be required.
(Updated: Changed lastMotorRunTime to unsigned long)

Should be unsigned long lastMotorRunTime to avoid issue with rollover; see https://arduino.stackexchange.com/questions/12587/how-can-i-handle-the-millis-rollover

The delay() seems perfectly useless here.

@EdgarBonet delay is probably useless, but it points out the idea, and can be replaced with something more useful like: https://www.arduino.cc/en/Reference/LowPowerSleep

Re “it points out the idea, and can be replaced with something more useful”: The comment do other stuff perfectly fills this role.

@MarkU Good catch on unsigned long -- edited a fix in.
Yes; Edgar Bonet and Patrick M I could have ignored putting in a delay() at all, but placed it there to show possibilities a little more clearly.

You will also want to incorporate some sort of state mechanism and/or a positional readout to ensure that the motor ran the appropriate time.
I've worked on encoders that jittered and caused 'more motion' resulting in time turned off too soon. Power failures, intermittent glitches or spikes- all can wreck movement. There are lots of ideas here and you're showing great pre-planning to solve them.

Using delay() for a 6-hour delay is a bit awkward, but perfectly doable. It will, however, not be very accurate, because the accuracy depends on the accuracy of the Arduino's clock, and it will block all other code you may wish to run.
Using timing with millis() would allow your Arduino to do other things while waiting. It will be just as inaccurate, though.
For long periods, and especially if you want things to be more accurate, you could use an external Real Time Clock, like the DS3231. You can get these as modules on break-out boards, and libraries are also available.
These RTCs have a backup battery, so they also keep running a while without external power, and will also keep time when the Arduino resets. Most also have settable alarm times you could use.
For your application, I would also implement a simple watchdog timer to make sure the Arduino is still waiting and working, and hasn't crashed. Note that a watchdog timer won't play nice with delay(); a simple 6-hour delay will always trigger it, and timing with millis() or an external RTC is the way to go here.

Some of these modules support the alarm function. Let your code set the time when compiling then forget about it. LOOP: When starting the cycle read the clock and calculate the alarm time needed for reversal and set it. When the alarm triggers reverse the motor and repeat the LOOP. If you put the battery in the module this will keep time even if the power fails.

Since this is for an incubator, I suspect that you don't need high precision.  So delay() will work perfectly well, if you don't want to do anything else in the meantime (like maybe monitor temperature, control a heater, and/or light LEDs for over/under temperature).  In that case you could use a loop that handled all those operations at some convenient rate like once per second or once per minute, using delay() in the loop. (I assume that your incubator is slow to respond to the heater, so slow sampling will be fine.)  Then let the loop run for 6 hours, which you can determine by simple count of the 1-minute (or whatever) loop delays.  And if you find that your 6-hour time is consistently high or low, adjust the count limit to compensate.

I have an automatic watering system that (among other things) trigger on time. I use the excellent Timer Library for this. It allows several useful timed interactions such as Pulse or Oscillate in addition to After which would solve your issue - or Every if you want a recurring 6 hour code block to execute
In the end - behind the screen - it is just as unprofessional as millis() - the library itself uses millis() and a scheduler. But the code looks cleaner and is easier to write and update.

There's nothing wrong with using delay here.
There is only a problem if you want to make the Arduino do something else as well. I that case you'd want to use millis, and use that to calculate how much time has passed (see blink without delay).


text:
Connect 12V 38A battery to SIM800C GSM Module
I have a gsm module that is rated for 12V and 1A. And I also have a drone Battery that is 12V and 38A. Would it hurt the gsm module If I connect it to this high power Battery?
I heard It's voltage that goes through forcefully, but current doesn't force it self through. So would it be safe to connect?

Your picture is of a HP server power supply. What does it have to do with the question?

@StarCat IT'S HAS THE SAME OUTPUT, WHAT'S THE DIFFERENCE?

The difference is: One is a battery, the other is a mains connected power supply. Do you have a datasheet of your battery? Are you sure your battery is 38A and not 38Ah? Because that would be much more useful information than a picture of a random power supply that has nothing to do with your question. Anyway, you can connect your battery and all will be fine (probably) because your SIM module will only use the current it needs.

@StarCat It's Turnigy LiPo pack with current upto 38A
https://youtu.be/EYkd6c6Gqyg?t=308

I really don’t want to watch a Youtube video, but it will probably do the job.

When choosing a battery there are three basic parameters that need to be considered:

Voltage
Capacity
Max. current draw

In your case you have listed the requirement as 12V 1A which means you need 12V and the maximum current need is 1 Amp.  You have said nothing about capacity, which is how much energy is stored in the battery so I assume it's not important here.
Your proposed 12V 38A battery will work just fine since it's still 12V and the 38A is simply the maximum current draw, not the minimum.  The battery will provide up to 38A but will also source less.
Be careful, though.  If you create an accidental short circuit there is a large amount of energy stored in a 38A type battery and it will be discharged very quickly indeed, possibly causing a fire.  Be sure to properly insulate your wires and connections.

I looked up the SIM800C GSM Module, and it seems it requires a Lithium Ion or Lithium polymer battery, and has a built-in charging circuit in it. (It sounds like it uses the battery to manage peak current demands.) Thus you MUST use a rechargeable lithium battery for it. Having a higher current battery should be fine as long as the voltage is correct.


text:
I2C communication between Arduino Uno and Nodemcu32-s (ESP32)
I want to send data between an ESP-32 (NODEMCU-32S) and an Arduino Uno but I haven't found any source on how to do that, so I tried this code:
ESP-32 code:
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin(21, 22);      /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop() {
  Wire.beginTransmission(8);
  Wire.write(3);  /* sends hello string */
  Wire.endTransmission();  /* stop transmitting */
  Wire.requestFrom(8, 18); /* request & read data of size 13 from slave */
  while (Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
}

And Arduino code:
#include <Wire.h>

void setup() {
  Wire.begin(8);                /* join i2c bus with address 8 */
  Wire.onReceive(receiveEvent); /* register receive event */
  Wire.onRequest(requestEvent); /* register request event */
  Serial.begin(9600);           /* start serial for debug */
}

void loop() {
  delay(100);
}

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
  while (0 < Wire.available()) {
    int c = Wire.read();        /* receive byte as a character */
    Serial.print(c);            /* print the character */
  }
}

// function that executes whenever data is requested from master
void requestEvent() {
  Wire.write("hello esp");
}

But I found that no data was sent.
I connected pin 21 to A4 and 22 to A5 directly.
I cannot find where the problem is. Also, I don't know whether the device address is correct or not, since when I tried an I2C scanner it didn't discover any device.
Also, I hope that there is a similar method to have two-way UART communication between the Arduino and ESP as I found none since I need both chips to send data to each other.

As long as a scan on the ESP doesn't find the Arduino, no point in going forward. Strip both pieces of code to the bare minimum (only I2C and whatever serial you need to debug). Make sure you didn't swap the wires. Add pullups (4.7k or 10k) to both I2C lines.

I made sure of all of that

also, an example code may be helpful please that prints hello on both cards

@Mat I edited the code so that it is easier now

"I hope if there is a similar method to have two way UART communication between the arduino and esp" - If you want to use UART, why not using UART? It's easier to use than I2C.

I'm working on something similar at the moment. Not a complete answer put some thoughts:

Have you considered that the Uno is a 5v board and the ESP32 is 3.3v? You may need a signal level shifter (there are many to chose from) something like Pololu-2595 which is breadboard friendly.

There's a good ESP32 I2C explanation at Random Nerd Tutorials.


text:
nRF24L01+ problem with receiving response
I'm sending currently data from a Raspberry to an Arduino, but I have a problem with receiving response from the Arduino back to the Raspberry:

Sent the message: ['H', 'i', '.', '.', 'A', 'r', 'd', 'u', 'i', 'n', 'o', ' ', 'U', 'N', 'O', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Timed out.

Currently message received is in "got_time", so I see numerical value. When I change it to string I see "Hi..Arduino UNO" response. Problem is with timeout on the Raspberry. Raspberry sends message, Arduino receives it, Arduino should send confirmation of receipt of the message, Raspberry shows timeout of it.
Can you guide me to the solution?
Arduino Nano code:
/*
* Getting Started example sketch for nRF24L01+ radios
* This is a very basic example of how to send data from one node to another
* Updated: Dec 2014 by TMRh20
*/

#include <SPI.h>
#include "RF24.h"
#include "printf.h"

/****************** User Config ***************************/
/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 1;

/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(9,10);
/**********************************************************/

const uint64_t addresses[2] = { 0xE1E2E3E4E5LL, 0xE6E7E8E9E0LL };
// byte addresses[][6] = {"1Node","2Node"};

// Used to control whether this node is sending or receiving
bool role = 0;

void setup() {
  Serial.begin(115200);
  printf_begin();
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));

  radio.begin();

  // Set the PA Level low to prevent power supply related issues since this is a
  // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_LOW);

  // radio.setRetries(15,15);
  radio.setPayloadSize(32);
  radio.setChannel(0x76);
  // radio.setPALevel(RF24_PA_MIN);
  // radio.setAutoAck(true);

  // Open a writing and reading pipe on each radio, with opposite addresses
  if (radioNumber) {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  } else {
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }

  // Start the radio listening for data
  radio.startListening();
  radio.printDetails();
}

void loop() {

/****************** Ping Out Role ***************************/
  if (role == 1)  { /* Not used in this case */ }
/****************** Pong Back Role ***************************/

  if (role == 0) {
    unsigned long got_time;

    if(radio.available()) {
                                                                    // Variable for the received timestamp
      while (radio.available()) {                                   // While there is data ready
        radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
      }

      radio.stopListening();                                        // First, stop listening so we can talk
      radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.
      radio.startListening();                                       // Now, resume listening so we catch the next packets.
      Serial.print(F("Sent response "));
      Serial.println(got_time);
    }
  }

/****************** Change Roles via Serial Commands ***************************/
/* Not used in this case */
} // Loop

Raspberry Pi 0 code:
import RPi.GPIO as GPIO  # import gpio
import time      #import time library
import spidev
from lib_nrf24 import NRF24   #import NRF24 library

GPIO.setmode(GPIO.BCM) # set the gpio mode

# set the pipe address. this address shoeld be entered on the receiver alo
pipes = [[0xE1, 0xE2, 0xE3, 0xE4, 0xE5], [0xE6, 0xE7, 0xE8, 0xE9, 0xE0]]
radio = NRF24(GPIO, spidev.SpiDev())   # use the gpio pins
radio.begin(0, 25)   # start the radio and set the ce,csn pin ce= GPIO08, csn= GPIO25
radio.setPayloadSize(32)  #set the payload size as 32 bytes
radio.setChannel(0x76) # set the channel as 76 hex
radio.setDataRate(NRF24.BR_1MBPS)    # set radio data rate
radio.setPALevel(NRF24.PA_MIN)  # set PA level

radio.setAutoAck(True)       # set acknowledgement as true
radio.enableDynamicPayloads()
radio.enableAckPayload()

radio.openWritingPipe(pipes[0])     # open the defined pipe for writing
radio.openReadingPipe(1,pipes[1])     # open the defined pipe for writing

radio.printDetails()      # print basic detals of radio
time.sleep(3)

sendMessage = list("Hi..Arduino UNO")  #the message to be sent
while len(sendMessage) < 32:
  sendMessage.append(0)
try:
  while True:
    start = time.time()      #start the time for checking delivery time
    radio.write(sendMessage)   # just write the message to radio
    print("Sent the message: {}".format(sendMessage))  # print a message after succesfull send
    radio.startListening()        # Start listening the radio

    while not radio.available(0):
      time.sleep(1/100)
      if time.time() - start > 2:
        print("Timed out.")  # print errror message if radio disconnected or not functioning anymore
        break

    radio.stopListening()     # close radio
    time.sleep(3)  # give delay of 3 seconds
finally:
  GPIO.cleanup() # this ensures a clean exit

Arduino console:

RF24/examples/GettingStarted
*** PRESS 'T' to begin transmitting to the other node
SPI Speedz   = 10 Mhz
STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xe6e7e8e9e0 0xe1e2e3e4e5
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xe6e7e8e9e0
RX_PW_P0-6   = 0x10 0x10 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x02
RF_CH        = 0x76
RF_SETUP     = 0x03
CONFIG       = 0x0f
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_LOW
ARC      = 5
Sent response Hi..Arduino UNO
Sent response Hi..Arduino UNO
Sent response Hi..Arduino UNO
Sent response Hi..Arduino UNO

Raspberry Pi 0 console:

STATUS   = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     =
 0xe1e2e3e4e5 0xe6e7e8e9e0
RX_ADDR_P2-5     =
0xc3
0xc4
0xc5
0xc6

TX_ADDR      =
 0xe1e2e3e4e5
RX_PW_P0-6   =
0x10
0x10
0x00
0x00
0x00
0x00

EN_AA        =
0x3f

EN_RXADDR    =
0x03

RF_CH        =
0x76

RF_SETUP     =
0x01

CONFIG       =
0x0f

DYNPD/FEATURE    =
0x3f
0x06

Data Rate    = 1MBPS
Model        = nRF24l01+
CRC Length   = 16 bits
PA Power     = PA_MIN
Timed out.
Timed out.
Timed out.

Writing to a console takes a very llng time. Perhaps the Arduino has already responded before the raspi starts listening. Try stat listening before you write out the message. Also, your Arduino code reads the whole message in a single unsigned  long variable, i.e. every new send character overwrites the last one. Then it sends only the last received charackter (a 0) back to the raspi. Is that what you want?

When I commented out print("Sent the message notthing changed (still "Timed out."). All I want to stable communication and sending messages at start Rpi to Arduino. Finally 2 way.

Next try: Perhaps the arduino still responds too fast. Use a delay before the write command. delay(5); radio.write(... in the arduino code.  Of cause, it is possible that there is a hardware problem. But why should it work in one direction but fail in the other? I think the problem is that you stop listening in order to send the message and the arduino responses before the Raspi starts listening again. A stable communication is only possible if you use a communication method with a connection management like bluetooth.

I added delay before radio.write from 5 up to 1000. Still timeout.


text:
Unable to correctly read CSC GATT data with ArduinoBLE on a Arduino Nano 33 IOT
I've set up a Nano 33 IOT as a central device and I'm attempting to read the data from a Cycling speed and cadence BLE device.
The spec for the CSC Gatt service I want is: https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.cycling_speed_and_cadence.xml
And the characteristic:
https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.csc_measurement.xml
I've tried a few different approaches, this one seems like it should get me the closest. I'm afraid I'm feeling around in the dark and hope someone can give me a definitive answer of how to read these values because I'm not even sure what they SHOULD look like even if I do somehow manage to read them correctly!
I initially tried using this code to read the values, which seemed to get me reasonably close, but seeing as there are different data types and I could just as easily read 32 values, I don't believe it to be correct.
uint16_t cscValues[16];
cscCharacteristic.readValue(cscValues, 16);

for(int i = 0; i < 16; i++){
    Serial.print(i);
    Serial.print(":");
    Serial.print(cscValues[i]);
    Serial.print(" ");
}
Serial.println("");

this gives the output:
//not moving:
10:50:49.401 -> 0:21249 1:0 2:11008 3:8314 4:556 5:8192 6:25637 7:0 8:0 9:0 10:704 11:8192 12:568 13:8192 14:22485 15:0
10:50:50.409 -> 0:21249 1:0 2:11008 3:8314 4:556 5:8192 6:25637 7:0 8:0 9:0 10:704 11:8192 12:568 13:8192 14:22485 15:0

//moving:
10:51:07.518 -> 0:24577 1:0 2:8448 3:8338 4:556 5:8192 6:25637 7:0 8:0 9:0 10:704 11:8192 12:568 13:8192 14:22485 15:0
10:51:08.513 -> 0:25345 1:0 2:36864 3:8342 4:556 5:8192 6:25637 7:0 8:0 9:0 10:704 11:8192 12:568 13:8192 14:22485 15:0
10:51:09.490 -> 0:26113 1:0 2:6144 3:8347 4:556 5:8192 6:25637 7:0 8:0 9:0 10:704 11:8192 12:568 13:8192 14:22485 15:0

The method I'm currently using is based off of a Arduino forum post I found: https://forum.arduino.cc/index.php?topic=711228.0
My full sketch:
#include <ArduinoBLE.h>

#define CSC_DATA_SIZE 16

typedef struct __attribute__( ( packed ) )
{
  int32_t cum_wheel_rev;
  int16_t last_wheel_event;
  int16_t cum_cranks;
  int16_t last_crank_event;
} csc_data_t;

typedef union
{
  csc_data_t values;
  uint8_t bytes[ CSC_DATA_SIZE ];
} csc_data_ut;

csc_data_ut cscData;

void setup() {

  Serial.begin(9600);

  //wait until the serial port is connected for debugging
  while (!Serial);

  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");

    while (1);
  }

  Serial.println("BLE Central scan");

  // start scanning for peripheral
  BLE.scanForUuid("1816"); // Cycle speed and cadence UUID
}

void loop() {
  //Read BLE devices

  // check if a peripheral has been discovered
  BLEDevice peripheral = BLE.available();

  if (peripheral) {
    // discovered a peripheral
    Serial.println("Discovered a peripheral");
    Serial.println("-----------------------");

    // print address
    Serial.print("Address: ");
    Serial.println(peripheral.address());

    // print the local name, if present
    if (peripheral.hasLocalName()) {
      Serial.print("Local Name: ");
      Serial.println(peripheral.localName());
    }

    // print the advertised service UUIDs, if present
    if (peripheral.hasAdvertisedServiceUuid()) {
      Serial.print("Service UUIDs: ");
      for (int i = 0; i < peripheral.advertisedServiceUuidCount(); i++) {
        Serial.print(peripheral.advertisedServiceUuid(i));
        Serial.print(" ");
      }
      Serial.println();
    }

    // print the RSSI
    Serial.print("RSSI: ");
    Serial.println(peripheral.rssi());

    Serial.println();

    // stop scanning
    BLE.stopScan();

    getSpeed(peripheral);

    // peripheral disconnected, start scanning again
    BLE.scanForUuid("1816"); // Cycle speed and cadence UUID
  }
}

void getSpeed(BLEDevice peripheral) {
  // connect to the peripheral
  Serial.println("Connecting ...");

  if (peripheral.connect()) {
    Serial.println("Connected");
  } else {
    Serial.println("Failed to connect!");
    return;
  }

  // discover peripheral attributes
  Serial.println("Discovering attributes ...");
  if (peripheral.discoverAttributes()) {
    Serial.println("Attributes discovered");
  } else {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }

  // retrieve the LED characteristic
  BLECharacteristic cscCharacteristic = peripheral.characteristic("2A5B");

  if (!cscCharacteristic) {
    Serial.println("Peripheral does not have CSC characteristic!");
    peripheral.disconnect();
    return;
  }

  if (!cscCharacteristic.canSubscribe()) {
     Serial.println("canSubscribe False");

  } else {
  if(!cscCharacteristic.subscribe()) {

    Serial.println("subscription Failed");
    }else {
      Serial.println("subscribed!");
    }
  }

  int totalWheelRevolutions = 0;
  int wheelDiameter = 750; // in mm

  while (peripheral.connected()) {
    //happens every second.
    if (cscCharacteristic.valueUpdated()) {
      if (cscCharacteristic.valueLength() > 0) {
          cscCharacteristic.readValue(m5600Data.bytes, M5600_DATA_SIZE);

          Serial.print(" cum_wheel_rev: ");
          Serial.print(cscData.values.cum_wheel_rev);
          Serial.print(" last_wheel_event: ");
          Serial.print(cscData.values.last_wheel_event);
          Serial.print(" cum_cranks: ");
          Serial.print(cscData.values.cum_cranks);
          Serial.print(" last_crank_event: ");
          Serial.print(cscData.values.last_crank_event);
          Serial.println("");
      }
    }
  }

  Serial.println("Peripheral disconnected");
}

The output is:
10:42:15.427 -> BLE Central scan
10:42:16.193 -> Discovered a peripheral
10:42:16.193 -> -----------------------
10:42:16.193 -> Address: df:f4:55:1e:16:27
10:42:16.193 -> Local Name: XOSS S-021477
10:42:16.193 -> Service UUIDs: 1816
10:42:16.193 -> RSSI: -72
10:42:16.193 ->
10:42:16.193 -> Connecting ...
10:42:16.703 -> Connected
10:42:16.703 -> Discovering attributes ...
10:42:17.473 -> Attributes discovered
10:42:17.508 -> subscribed!
//moving:
10:42:18.524 ->  cum_wheel_rev: 11009 last_wheel_event: -32256 cum_cranks: 251 last_crank_event: 0
10:42:19.529 ->  cum_wheel_rev: 11265 last_wheel_event: -19968 cum_cranks: 7 last_crank_event: 0
10:42:20.511 ->  cum_wheel_rev: 11777 last_wheel_event: -10752 cum_cranks: 21 last_crank_event: 0
10:42:21.520 ->  cum_wheel_rev: 12033 last_wheel_event: -512 cum_cranks: 26 last_crank_event: 0
10:42:22.636 ->  cum_wheel_rev: 12545 last_wheel_event: -6912 cum_cranks: 31 last_crank_event: 0
10:42:23.764 ->  cum_wheel_rev: 13057 last_wheel_event: 4608 cum_cranks: 37 last_crank_event: 0
10:42:24.747 ->  cum_wheel_rev: 13313 last_wheel_event: -25600 cum_cranks: 39 last_crank_event: 0
10:42:25.615 ->  cum_wheel_rev: 13825 last_wheel_event: 2816 cum_cranks: 44 last_crank_event: 0
10:42:26.631 ->  cum_wheel_rev: 14337 last_wheel_event: -11264 cum_cranks: 48 last_crank_event: 0
10:42:27.610 ->  cum_wheel_rev: 14849 last_wheel_event: -17664 cum_cranks: 53 last_crank_event: 0
10:42:28.635 ->  cum_wheel_rev: 15361 last_wheel_event: -12288 cum_cranks: 57 last_crank_event: 0
10:42:29.616 ->  cum_wheel_rev: 15873 last_wheel_event: -18432 cum_cranks: 61 last_crank_event: 0
10:42:30.642 ->  cum_wheel_rev: 16385 last_wheel_event: -29696 cum_cranks: 65 last_crank_event: 0
10:42:31.619 ->  cum_wheel_rev: 16641 last_wheel_event: -21248 cum_cranks: 67 last_crank_event: 0
10:42:32.612 ->  cum_wheel_rev: 16897 last_wheel_event: 23040 cum_cranks: 70 last_crank_event: 0
10:42:33.642 ->  cum_wheel_rev: 17665 last_wheel_event: -7168 cum_cranks: 77 last_crank_event: 0
10:42:34.619 ->  cum_wheel_rev: 18177 last_wheel_event: 18944 cum_cranks: 81 last_crank_event: 0
10:42:35.637 ->  cum_wheel_rev: 18945 last_wheel_event: 11264 cum_cranks: 86 last_crank_event: 0
10:42:36.622 ->  cum_wheel_rev: 19457 last_wheel_event: -29440 cum_cranks: 89 last_crank_event: 0
10:42:37.616 ->  cum_wheel_rev: 19969 last_wheel_event: -5888 cum_cranks: 92 last_crank_event: 0

//not moving:
10:42:38.623 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0
10:42:39.608 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0
10:42:40.624 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0
10:42:41.640 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0
10:42:42.620 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0
10:42:43.642 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0
10:42:44.622 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0
10:42:45.638 ->  cum_wheel_rev: 20481 last_wheel_event: 20224 cum_cranks: 96 last_crank_event: 0

I'm well versed in programming, but new to Arduino. Any help would be extremely valuable!
Thank you!

So I've managed to realise I was missing the flags in my data. So by adding  'int8_t flags' to the attributes I got it to work. Kind of... I still need to adjust for when fields should be read or not. and I've got some idea's but I'm not sure of the best way to do that.
typedef struct __attribute__( ( packed ) )
{
  int8_t flags;
  int32_t cum_wheel_rev;
  int16_t last_wheel_event;
  int16_t cum_cranks;
  int16_t last_crank_event;
} csc_data_t;


text:
Ignoring the first high output from the sensor
If the vibration sensor with Arduino detects two high inputs within 1 minute, I want the led to flash in one second.
My ability to write Arduino code is very low; I tried with millis() but I couldn't.
I want it to ignore the first high entrance.
Thank you for all the information you will give.
const byte sensor = 7;
const byte LED = 13;
unsigned long sensorMillis;
unsigned long ledTurnedOnAt;
unsigned long high_1 = 60000UL;
bool ledState = false;

void setup() {
  pinMode(sensor, INPUT);
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if (digitalRead(sensor) == HIGH) {
    sensorMillis = currentMillis;
    ledstate = true;
  }

  if (ledstate == HIGH) && ((unsigned long)(currentMillis - ledTurnedOnAt) <= high_1) {
    digitalWrite(8, HIGH);
    delay (1000);
    digitalWrite(8, LOW);
  }

  ledstate = false;
}

It works better if you ask a question about a specific thing you are getting stuck on.

Edit your question to show the code for your attempt, along with a description of how it fails to meet your goal. You'll also need to map out your desired logic in detail. First high reading is ignored. 2nd high reading lights LED. Then what? Do you want the LED to turn off once the vibration sensor shuts off, or after some period of time? Or do you want it to stay on forever once it turns on the first time?

I want it to ignore the first high input, I want the led to flash immediately with the second high input.

that is not a question ... it is a description of how you want the program to behave

You may want to read about The Finite State Machine.

thank you edgar Bonet

Try looking for the high in setup, it will then be ignored by your loop.

One simple solution could be:
Start by noticing the first time you get the HIGH input whit a simple if statement:
if (digitalRead(sensor) == HIGH) {
}

where sensor is the pin of the sensor according to your code.
When this statement is True, you are interested in remain here until one of two things happens:

either you interrupt some kind of loop with another HIGH input,
or the time you have set is passed.

One way of knowing elapsed times will be with the millis() function, that returns the milliseconds since the board began running.
We should get the elapsed time the first time we enter the loop:
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
}

Then, as I have said, we need to remain here for a specific amount of time. We could use the while loop, but, which condition needs to be true?
So we have a start time, lets said x and you need to stay in the loop for, let's say, y milliseconds. This is the same as saying that you want to stay in the loop until the time we enter the loop and a specific amount of milliseconds, x+y. When the millis() function gives us a greater number, we should exit the loop:
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+1000))
//                              ^ The second you are interested, 1000 milliseconds.
}

Now, we have to check if there is another interrupt during this time, by using the same statement of the beginning:
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+1000)) {
    if (digitalRead(sensor) == HIGH) {
      // 2 interrupts in less than 1000 millis!
    }
  }
}

Summarizing is nicer to declare a global with the specific time we want, instead of the 1000 value we are using now:
const long maxTimeInterval = 1000;

And changing it in our code (that is inside the loop())
if (digitalRead(sensor) == HIGH) {
  long startTime = millis();
  while (millis() <= (startTime+maxTimeInterval)) {
    if (digitalRead(sensor) == HIGH) {
      // 2 interrupts in less than 1000 millis!
      digitalWrite(LED, HIGH);
    }
  }
}

Hope this helps!

Start by noticing the first time you get the HIGH input whit a simple if statement Cannot see you your code doing so.

@DataFiddler I have all wrapped inside if (digitalRead(sensor) == HIGH) { ... }

Thank you very much. @Juan CA you are great. code works well.

@juan CA .I asked a lot of people, nobody succeeded. You succeeded easily.  You are wonderful. If you were close, I would like to give you a gift.

Thank you very much to all site administrators

const int sensor = 7;
const int LED = 13;
unsigned long sensorMillis;
unsigned long ledTurnedOnAt;
unsigned long high_1 = 60000UL;
bool ledState = false;
void setup() {
  pinMode(sensor, INPUT);
  pinMode(LED, OUTPUT);
  delay(1000); //Warm up Time
}

void loop() {
  unsigned long currentMillis = millis();

  if (digitalRead(sensor) == HIGH) {
    sensorMillis = currentMillis;
    ledstate = true;
  }

  if (ledstate == HIGH) && ((unsigned long)(currentMillis - ledTurnedOnAt) <= high_1) {
    digitalWrite(8, HIGH);
    delay (1000);
    digitalWrite(8, HIGH);
  }

  ledstate = false;
}

I haven't checked this because I don't have my hardware. However, I added a delay of 1 second in the setup as a warm up time. This in theory should ignore the first high. Hope it helped.

"N0m4d "Thank you very much for your attention and help

Or what about adding another global boolean;
bool firstTime = true;

and then amend you loop() code as follows;
if (digitalRead(sensor) == HIGH) {
    if (firstTime) firstTime = false;
    else {
        sensorMillis = currentMillis;
        ledstate = true;
    }
  }

thank you Rob W. i will try


text:
Returning to parent directory with the SD library
I have a File variable called dir and i'm building a simple file explorer for my device. Is there a way to get a reference to dir's parent directory?

Doesn't dir.name() return dir's name with the path?

Unfortunately it only returns the name

Then probably the only way is to keep a list of the directories you traversed while going to that file, or while building the directory structure from root. There may be an other way, but I don't know the SD library well enough.

I don't think there is an inbuilt function returning the parent, but you could do:
FS &file_system = SD; // pick whichever file system you use

File get_parent(File dir) {
  String dirPath = dir.path();
  int lastSlashIndex = dirPath.lastIndexOf('/');
  if (lastSlashIndex != -1) {
    String parentDirPath = dirPath.substring(0, lastSlashIndex);
    File parentDir = file_system.open(parentDirPath.c_str());
    return parentDir;
  }
  return File();
}

but there is no path function in the Arduino SD library. (and no FS type)

I only have esp32-S3 at hand here, and path() is available in framework-arduinoespressif32 -> FS.h, I don't know the situation for other platforms/architectures.


text:
Relays just switch ON and OFF on delay(), not on millis()
I use fuzzy logic for the running time of relays, but the relays just switch ON and OFF at the interval of the delay() I put at the end of loop.
This is my code:
void loop () {
  ph = -180/100.0;
  hasilec = -1.2;
  unsigned long now = millis();

  Serial.print("pH    ");
  Serial.print(ph);
  Serial.print("  ");
  Serial.print("EC ");
  Serial.print(hasilec);
  Serial.println("");
  Serial.print(ph);
  Serial.print(" ");
  Serial.print(hasilec);
  Serial.print(" ");
  Serial.println(" ");

  fuzzy->setInput(2, hasilec);
  fuzzy->setInput(1, ph);
  fuzzy->fuzzify();

  float pompa01 = fuzzy->defuzzify(1); //pHDOWN
  float pompa02 = fuzzy->defuzzify(2); //pHUP
  float pompa03 = fuzzy->defuzzify(3); //ABMIX

  long int pompa1 = pompa01 * 1000;
  long int pompa2 = pompa02 * 1000;
  long int pompa3 = pompa03 * 1000;

  Serial.println("Result= ");
  Serial.println("");
  Serial.print(" Pompa1 pHDOWN: ");
  Serial.println(pompa1);
  Serial.print(" pompa2 phUP  : ");
  Serial.println(pompa2);
  Serial.print(" pompa3 ABMIX : ");
  Serial.println(pompa3);
  Serial.println("");
  Serial.println("");
  Serial.println("");

  pump_periods[0] = pompa1;
  pump_periods[1] = pompa2;
  pump_periods[2] = pompa3;

  for (int i = 0; i < jml_pump; i++) {
    if (now - pump_last_actuations[i] >= pump_periods[i]) {
      pump_states[i] = (pump_states[i] == LOW) ? HIGH : LOW;
      digitalWrite(pump_pins[i], pump_states[i]);
      pump_last_actuations[i] = now;
    }
  }
  delay (20000);
}

The relay just switch ON and OFF on this delay delay (20000);.
What should I do?

Check the values of pompa1, pompa2, and pompa3 to see if they are always smaller than 20000. What is the delay for, anyway? It could well be messing up your timing of the toggling of the pump_states by delaying longer than the values in pompa1, pompa2, and pompa3.

i got it i just replace my delay after fuzzy, its work, let me debugging more for perfection my project thx

I will turn the comment into an answer; please accept it (if you accept it) so the question doesn't stay open.

Check the values of pompa1, pompa2, and pompa3 to see if they are always smaller than 20000 (I suspect they are).
The delay(20000) (why is it there anyway?) could well be messing up your timing of the toggling of the pump_states by always delaying longer than the values in pompa1, pompa2, and pompa3.
This would make the relays toggle every 20 s (on every loop).

i got it thx for it


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

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

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

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

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

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

Thanks alot for the answers!

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

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