text:
strcpy_P increases IROM usage by 400%
Using ESP8266 (NodeMcu 1) in Arduino IDE:
I can't upload my sketch because a single call to strcpy_P seems to increase the IROM usage by about 400%: 25% total usage without the call, 100+% with the call.
And even more strange, it depends on the second parameter of strcpy_P (the source):
If a pointer to a char array is provided, the usage increases dramatically
  char * ptr = (char *) pgm_read_word (&myArrays[index]);
  char buffer [1500];

  strcpy_P (buffer, ptr); // can't upload, uses 100+% of available IROM

Whereas with PSTR as parameter (just to test) total size of sketch is just 25% of IROM, leaving everything else unchanged:
  char * ptr = (char *) pgm_read_word (&myArrays[index]);
  char buffer [1500];

  strcpy_P(buffer, PSTR("Test")); // Ok, does not increase sketch size /IROM  usage

What's going on here ?

When its not used it willbe optimized out by the compiler.

what is char * ptr = (char *) pgm_read_word (&myArrays[index]);? you read address from flash?

I try to dynamically access  (by index) char arrays stored in PROGMEM. and these are referenced in  const char* const myArrays[] PROGMEM = { arr1, arr2, arr3}

@chrisl:  No, I commented out all referenecs to "buffer" after that call and still it uses 100% of IROM

That doesn't necessarily mean, that it would be optimized out completely. The effect just sound very like optimization. Though I'm not an expert for the optimization.

I guess the problem is not the strcpy_P function, but your array. Without that function call, the entire array can be removed by the compiler (I presume it's not used anywhere else). As soon as you add code that definitely accesses it, it is included in the code and therefore increases the size of the program so much.


text:
Arduino pro mini sampling rate
what are the possible sampling rate the user can set in Arduino pro mini using ADCSRA registers.
I want to set  my desired sampling rate through registers, is it possible?

maybe add a quote from the datasheet and explain what is what you don't understand

What sampling rate do you want, chances are you won't achieve it if you are trying to run a high level language on the device.

It depends on you accuracy requirement, as accuracy degrades with sampling speed.

The previous responders are correct; but, maybe some clarification may help. The data conversion rate determined by the ADCSRA register is the conversion rate of the hardware. There is no need to sample data readings faster than conversions are performed. Faster conversions show more jitter than slow ones. Your actual sample rate will usually depend more on the time it takes to run through your loops than on the conversion rate. Arduino library code is usually not the optimum choice for speed.
When you change the conversion rate in the ADCSRA, be sure to avoid clobbering the other bits:
ADCSRA = (ADCSRA & 0xF8) | (newRate & 7);
If you are getting the hang of writing the control registers, you might want to use the ADC's operation complete interrupt to retrieve each reading. That eliminates loop times.

source: Stack Exchange

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

sort: votes


text:
Controlling Arduino through python
How to set the registers of Arduino through python code to vary the sampling rate of Arduino?
Can we control Arduino through python?

what runs the python script?

If you mean can you run a python script on a "PC" and send messages to an Arduino then yes but you would need to write code that ran on the Arduino to receive messages from the "PC" and turn those into actions on the Arduino.
If you mean can you run a python script on an Arduino directly, well yes you can there are python implementations for Arduinos, but if you go down this route you need to remember you only have a small amount of memory and you are going off piste where there will be little or no help.
Honestly I would learn how to program the arduino in C++ and stick to that.

welcome back Code Gorilla. you could mention Firmata

Thank you very much :)  That was the one I had a quick look at, but I didn't investigate it in any detail so I didn't want to hint it might be any good.

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


text:
Why do I get different times when using analogRead() inside while loop?
I have the following code which checks the latency of another board.
    int triggerPin = 13;
    int dataPin = 9;
    int ejectorPin = A0;
    unsigned long t_start = 0;
    unsigned long t_end = 0;
    unsigned long t_total = 0;
    int value = 0;

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

    void loop() {
      t_start = micros();
      while (value < 10 ) {
        digitalWrite(triggerPin, HIGH);
        digitalWrite(dataPin, HIGH);
        delay(5.0);
        digitalWrite(dataPin, LOW);
        digitalWrite(triggerPin, LOW);
        delay(1.0);
        value = analogRead(ejectorPin);
      }
      t_end = micros();

      t_total = (t_end - t_start);
      Serial.println(double(t_total) / 1000);

Note that I'm using analogRead() inside the while loop. With this method I get 18.3 msec. However, if I use the analogRead() in the while condition:
    void loop() {
      t_start = micros();
      while (analogRead() < 10 ) {
        .
        .
        .

then I get 30.2 msec. I thought assigning value of analogRead() to a variable would take longer but here it's the opposite.
Can someone please explain the reason behind this behaviour?

What voltage are you supplying to A0? Is it consistent between runs of the program? How consistent are the printed values across loop iterations?

Your delays will be completely hiding any variance in the analog read timing. Your supposed results are meaningless to us.

@EdgarBonet As far I can tell the both the input voltage and the printed values are pretty consistent.

@Majenko I just had an experience colleague tell me the same thing. We're now using a two channel oscilloscope to visually check the time difference.

@Majenko But nonetheless, just moving analogRead() shouldn't introduce 12 msec difference.

@Farahi It won't be the analogRead. It'll be whatever is "triggering" the analogRead. The analogRead is insignificant in the scale of things.

@Majenko But the same thing which is triggering the analogRead inside the loop is also triggering the analogRead when its in the while condition.

And is the timing of that "same thing" absolutely precisely the same, or could your delays be affecting how your sampling happens? Remember: you will only ever be taking a single sample every 6 milliseconds or so whichever method you're using. Does that slow sample frequency even make sense for what you're sampling?

@Majenko I let both methods run for over 40 mins. The results were pretty much as I mentioned in the post.

@Farahi So? With a 6ms granularity of sampling you have an accuracy of ±6ms, or "within 12 ms of reality". Oh look...  30-18 is 12...  What a surprise...

@Majenko There's no need for passive aggressiveness. I'm new to all this so my questions may come across as dumb.

Both of your examples use a while loop, so the while loop is not the issue.
An analogue read, with the prescalers unchanged, takes 104 µs. So, what you are really measuring is your 6 ms delays, plus a slight amount extra for the other code.
Since your first while loop necessarily takes 6+ ms, then you will naturally get a result which is a multiple of 6 ms. This appears to be happening, so you are getting two loops (18 ms). This doesn't prove a huge amount.

You need to read up on the Nyquist frequency
To get accurate sampling results you need to sample at twice the rate at which things change. Your first results may merely be the results of aliasing. Your 6 ms delays may cause you to take one sample on one transition, and another sample (maybe) a couple of transitions later. Thus your results are meaningless.


text:
A strange bug in my Arduino ALU
I have discovered a strange error in my Arduino. It's not in the code. I think it's a hardware bug in the ALU of the microcontroller, maybe in clone only.
So there is a variable called feedLimit and its value is 30, which doesn't really matter.
When I print the answer of feedLimit301000 using this command Serial.println(feedLimit*30*1000)
The answer printed on the serial monitor is 30528, which is obviously incorrect. But when I print feedLimit*30000, the answer is correct (300000). The answer should be the same in both cases but it's not. I have attached the code as well as a screenshot of the output.
Can somebody please let me know if this is a bug in Arduino or something else? I have never experienced this kind of bug at the hardware level.
Thanks.
int interval, interval2;

int feedingTime = 3; //Must feed once every 3 minutes
int feedLimit = 30;  //If fed 10 times or more within feedingTime span, the fiesh dies
int dieAfter = 30;   //Will die if its not fed in 10 minutes
int feedCounter = 0; //Counts how many time fed in feedingTime span

void setup() {
  Serial.begin(9600);
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  Serial.println(feedLimit);
  Serial.println(feedLimit*60*1000);
  Serial.println(feedLimit*60000);
}

Not a bug. You're working with integers on an 8 bit microcontroller. The maximum they can hold is 32767.

This is not a bug. It's just that you are working with signed 16 bit integers on an 8 bit microcontroller. The maximum an int can store is 32767, and literals are 16 bit signed by default.
Your three prints are:
  Serial.println(feedLimit);

Print 30.
  Serial.println(feedLimit*60*1000);

Multiply  feedLimit by 60 = 1800. Multuply 1800 by 1000 = 1800000. Fit 1800000 into 16 bit signed = 30538. Also works the other way: preprocessor multiplies two 16 bit ints to create a new 16 bit int constant: 60 * 1000 = 60000, which is too big to fit in an int and truncates to 27232. Multiply by 30 = 30538 when truncated to 16 bits.1
  Serial.println(feedLimit*60000);

Multiply 30 by 60000. 60000 is too big to store in an int so it is implicitly promoted to a long. 30 * 60000 = 1800000. The result is a long because you have an implicit long in your calculation.
You have to take care with big numbers on small microcontrollers and keep in mind the limits of each variable type, along with what the default data type for literals is.

char: -128 to +127
unsigned char / byte: 0 to 255
int: -32,768 to +32,767
unsigned int: 0 to 65,535
long: -2,147,483,648 to 2,147,483,647
unsigned long: 0 to 4,294,967,295

You can force literals to be a specific data type by adding a suffix to them:

L: Long
UL: Unsigned long

(There are others too but less often used).
So your first (failed) calculation can be fixed by forcing one of the values to be a long:
  Serial.println(feedLimit*60*1000L);

1: It seems avr-gcc isn't clever enough to do this, instead it's always treating each operation separately, and each time it works from int-to-int using two 8-bit registers to represent each value or result.

This was very helpful. Thank you :)

Alternatively, one can use the types with explicit sizes: int8_t, int16_t, int32_t etc. These will have the expected size regardless of what CPU is used.

I don't think that a folded constant of 60000 is truncated to 27232. Did you check that in compiled code?

@thebusybee It seems avr-gcc isn't clever enough to fold 60 * 1000 as constants into a single 60000 constant. Instead it does individual mul calls at runtime - <variable> * 60 followed by <result of previous> * 1000. And at each stage it's working with just 2 8 bit registers per value (or just 1 in the case of 60 of course, it's not that stupid) and all results go into two registers every time. Everything truncates and truncates again. But it doesn't think to coalesce literals like that though...

Re “It seems avr-gcc isn't clever enough to fold 60 * 1000 as constants into a single 60000 constant”: It can't do that: that would break the rules of the language about implicit typing. But it is clever: it notices feedLimit doesn't change and folds feedLimit*60*1000 into 30528. No runtime mul calls.

@EdgarBonet Not according to the output of avr-gcc -S in my tests. There was a long list of mul instructions to get the result.

Mmm... weird. The avr-g++ 7.3.0 shipped with Arduino 1.8.15 does the optimization. Did you compile with -Os -flto?

@EdgarBonet No, I didn't. I wouldn't expect -flto to have any effect since there's no linking. -Os might but who knows? It doesn't really matter anyway, since the exact "why" is irrelevant. Whatever the compiler decides to do or doesn't decide to do, it's still 16 bit integers unless there's a good reason for it to promote to long.

@Majenko last night I also had trouble trying to replicate what you saw in folding. But my thoughts on it were more that regardless of what it does, you're asking it to do something undefined and it's hard to have expectations of the optimizer in such cases. I would have tested -fwrapv to check for a change. But, no original problem, no test. As you said not ultimately relevant. About the only thing I thought to add is that the literal's specified base affects whether unsigned types are considered candidates. E.g. 32768 is long, but 0x8000 is unsigned int with 16-bit systems.


text:
How does Arduino board separate USB traffic (uploading code vs. communication)?
A beginner in Arduino programming here (learning Arduino programming while waiting for my board to arrive).
I am trying to understand how Arduino board is able do these two things using only one USB port it has:

receive compiled code from a PC (from Arduino IDE: Sketch > Upload)
serial communication between a PC application and the Arduino board (e.g. our own Windows application communicates with the Arduino board)

I just cannot wrap my mind around how does it distinguish between these two cases. I have used boards which have 2 USB ports: one is for programming (uploading your code) and the other one is for serial communication between any PC application and the board.
In my opinion there has to be some way for Arduino to detect when is it being flashed, and when is it being used as a regular serial port.

https://learn.adafruit.com/bootloader-basics?view=all#types-of-bootloaders

It doesn't distinguish anything. It's all down to what code is running on the board at any moment.
When you reset or power up the bootloader runs. It listens for uploaded code. If it doesn't get an upload signal from the pc after a short timeout it starts executing your code instead.


text:
Arduino as Multiplexer
This is a kind of an experiment, I just have a question on how Arduino ports work. Consider this sample: there is this target device that I'm trying to control with Arduino. The device uses a typical scanned keyboard (8 output columns and 5 input rows which make contact whenever a user presses a key). I am trying to emulate that keyboard with Arduino. Of course, a standard way to do it would be to read 8 columns and produce appropriate output on the 5 rows. However, Arduino is not fast enough to make it work. So, I am going with multiplexer idea. 8 Arduino's digital pins are connected to columns and 5 Arduino digital pins are connected to rows. GND rail is NOT connected.
So the idea is this. By default all Arduino pins are set to INPUT in init() routine. Whenever I need to emulate a key press, I just set a corresponding row pin to OUTPUT and LOW, same for the column pin. So, that should work as some kind of a multiplexer, since Arduino pins are driven by Mosfets and input state is high impedance, and during output state both pins would be tied to Arduino's GND which makes a hardlink connection between them (setting to HIGH should work to, there's no difference).
Here is the test code which should make a keypress every 5 seconds:
pinMode(ROW0_PIN,OUTPUT);
digitalWrite(ROW0_PIN,LOW);
pinMode(COLUMN0_PIN,OUTPUT);
digitalWrite(COLUMN0_PIN,LOW);
Sleep(5000);

pinMode(ROW0_PIN,INPUT);
pinMode(COLUMN0_PIN,INPUT);
Sleep(5000);

Now, the thing IS working. However, it only works if one column pin is connected. When I connect any two pins, the target device stops responding. What I found is that actually, when I do
pinMode(COLUMN0_PIN,OUTPUT);digitalWrite(COLUMN0_PIN,LOW);,
the neighboring pins somehow get activated too, which results in all column outputs connected together and sending signal to row inputs.
If all pins are set to INPUT, it works fine, meaning, no connection between rows and columns.
My qustion is: why is it happening? Let me rephraze it: somehow setting a digital pin to OUTPUT makes other digital pins lose their high impedance state, although all of them are set to input. I haven't checked if this is happening within a hardware port or not, just consider schematics, please.

it is unclear what you are trying to do ... emulating a keyboard does not involve using a matrix ... are you trying to programmatically "press keys" on a real keyboard?

There is a vintage device that uses a typical keyboard matrix circuit. I am trying to emulate keypresses on that keyboard with Arduino. Usually you do this by following outputs and producing data on inputs. But Arduino is too slow in this case and that approach is not working. So, I'm looking for a simple way to do it. Of course, I can use add-on multiplexers, but the point is to keep it "Arduino only."

The Arduino is probably plenty fast enough - you just have to be more clevererer with your programming.

the device activates only one of the column lines at a time ... it reads the status of the row lines to determine if any of the keys are pressed in the selected column .... your code has to determine which of the column lines is being read and it has to activate only one of the row lines for the duration of the time the column is being addressed

I am not looking for advice or explanation on how keyboard matrix works or how to program it, it's textbook simple. I am trying to implement a crossbar-matrix multiplexer with Arduino. The keyboard matrix was just an example to illustrate the idea, forget the keyboard matrix. :) The actual quesion is about pinMode() behavior and why changing pin state to OUTPUT somehow affects other pins.

The difficulty is in the internal circuitry of the AVR, I don't think that your idea will work. So this is more an X-Y-problem.-- Would you mind to [edit] your question and add some timing information, please? Did you measure the times the device activates its scanning outputs? A diagram of a complete cycle would be optimal. And did you measure the times your program needs? Hint: the standard Arduino library's pin function are quite slow because of the "universal" pin numbers.

Thanks for elaborating, actually, I am talking about ZX Spectrum keyboard, the outputs are address lines of the Z80 CPU. Many people attempted doing it programmatically already, the Atmega 328 is not fast enough. It will work if Xtal is replaced by 24 Mhz, also using interrupt to read the IORQ line (which is active exactly when the CPU reads the keyaboard). What I'm trying to do here is achieve all this with bare Arduino. Just trying to find new simpler ways. Apparently the best way to do it is use a bunch of CD4051BE's.

How fast would be fast enough?   What do you mean by "the neighboring pins somehow get activated too"  Maybe they need some small physical pull-up resistors? You could speed things up by writing to your row pins in parallel with PORTC/DDRC/PINC and reading in parallel using PIND & PINB.  Changing the pinMode on A0-A4 to OUTPUT,  or not is just fiddling with bits in DDRC and PORTC -- see https://arduino.stackexchange.com/a/81338/6628 and https://arduino.stackexchange.com/a/22985/6628

I have no certainty about what is happening, but I suspect you are
seeing the effects of the input clamping diodes. Each digital pin has
clamping diodes that keep its potential between GND and Vcc, ±the diode
threshold.

As long as all pins are set to INPUT, they can freely float with
respect to one another, provided the potential differences stay within
Vcc+2×diode_threshold.

When you set one pin to OUPUT LOW, you are tying to to GND. The
other pins can still float above this one, but only very slightly
below it. The clamping diodes provide unidirectional current paths
from this pin (which is now GND) to every other pin.

Yes, that must be it. Any idea how to get around it, please? Maybe add external diodes to create voltage offset?

@JimmyFalcon: Sorry, but no idea. Connecting nodes to GND of a floating IC is a very unconventional way of achieving electrical contact.


text:
Why is the IR transmitter tied to one pin
I'm using IRremote.h  (https://github.com/Arduino-IRremote/Arduino-IRremote).  The receiver allows you to change the pin it is connected to but the transmitter does not.  Is there any reason why this is hardcoded in IRremoteInt.h.  If it just a PWM pin, can't any PWM pin be used?
#if defined(CORE_OC2B_PIN)
#define TIMER_PWM_PIN        CORE_OC2B_PIN  /* Teensy */
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN        9  /* Arduino Mega */
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN        14 /* Sanguino */
#else
#define TIMER_PWM_PIN        3  /* Arduino Duemilanove, Diecimila, LilyPad, etc */
#endif

There is not much documentation on this.

have you tried using another pin?

Where are those pin definitions? Just have found some pin numbers in IRTimer.hpp. Though by default you can use any pin for sending since the timing is done via software. The pin definitions come only to play when you want to use a hardware timer in PWM mode. Then you can provide the corresponding defines to tell the library which Timer to use. Thats important,  since it will directly access the corresponding registers of that Timer

So in short, I need to modify the header and source if I wish to use any pin for sending.  No idea why the author designed the receiver to take any pin but not the sender.  I'll just change it to accept any pin and send the mods to the author.

@cup I would guess the author did it that way because thats the way most Arduino libraries are.  "There is not much documentation on this" adds weight to that assumption.  IMO a lot of libraries are generated because the author needs the functionality and then they are published because the authors are just nice people and are willing to share.  In this case the author probably never thought about using a different pin, the wire was connected to port 9 why would 'he' need it on port 8.

@cup ... There is also the chance that there is a hardware restriction that was in force at the time that meant it could only be on port 9, it was the only port that supported PWM? Maybe now the limitation is no longer there.
But anyway you have the right idea, if you can improve a library do so and feed it back into the repo.

I'll do the changes, test it and then feed it back to the author.  Can someone close this?

Got to the bottom of it.  As mentioned in the comments, this is tied to the timers.  The list is given in Secrets of Arduino PWM.  The code can be changed to use a different timer but it will still be tied to a specific pin.


text:
SMS with Uno in 2022
I'm trying to develop a simple sensor-triggered SMS message to mobile service from an Uno as a learning project in North America.
I initially thought that it might be wise to purchase a GSM/3G compatible board and follow a tutorial such as this one: https://docs.arduino.cc/tutorials/mkr-gsm-1400/gsm-send-sms or go with Arduino's IoT SIM card package: https://store-usa.arduino.cc/products/arduino-sim-mkr-gsm-1400-cellular-kit (though this one is not exactly what I want since its SIM card only works with Arduino's IoT Cloud service and is not direct SMS to mobile capable).
However, after a bit of further research, it seems as though 2G (GSM)/3G networks are effectively phased out (by this year) and so I'm concerned that the above options won't work.  I'm also generally confused as to the best low-cost SIM cards for those options above (my service will be sending only tens of messages per month).  I have to yet to find similarly well supported shields/boards/SIM cards for 4G/5G networks in North America in the Arduino community.
Can anyone recommend a solution or point out where I may be incorrect in my analysis of current options?
I've considered postponing this particular project and instead accomplishing the same task with WiFi and IFTTT...
If not evident already: I'm new to working with SMS and IoT.

Unless you need SMS I wouldn't bother with it. Or at best use WiFi and an online SMS gateway service. If you need remote connectivity then a 4G WiFi hotspot will connect you to the internet.

Have you tried searching for terms like "Arduino LTE board"? A quick search seams promising. Though it is definitely easier to build when you use wifi and - if necessary - a standard wifi hotspot.

@chrisl Yes and I concluded that the Botletics SIM7000A Shield (along with a Hologram SIM card) is the likely the best way to go for 4g support on Arduino based on these resources: https://www.instructables.com/LTE-NB-IoT-Shield-for-Arduino/ and https://github.com/botletics/SIM7000-LTE-Shield.  Do you agree?

Looks good to me

any luck on getting SMS to work with the hologram sim and SIM7000?

@trevor haven't gotten around to it yet.  I decided for the time being to just use a wifi board


text:
No SPIFFS data upload in Arduino IDE 2.0.0-rc3 (ESP32 & TTGO) - Ubuntu
I tried adding esp32fs.jar to /home/myname/Arduino/tools/ESP32FS/tool (and a few other places as it looked likely that the jar file wasn't loading).  I've definitely got the correct board selected, and can upload Sketches.  I can also run the demo that writes to SPIFFS.
But the Tools menu doesn't have an option for ESP32 Sketch data upload.
Is SPIFFS data upload not available so far in V2?

FS upload plugins for ESP are not available in IDE 2 yet (2022-01-07).
IDE 2.0 doesn't run on Java so it can't use the java plugins of the IDE 1. You have to use IDE 1 for FS upload and exception decoder until new plugins are written for IDE 2.
It is tracked here: https://github.com/arduino/arduino-ide/issues/58

I've created a utility that provides a web-based ESP32 interface for

OTA
File system formatting
FS directory listing
File uploading
File editing
File deletion

It can be found at https://github.com/palmerr23/ESP32-OTA-and-File-Manager

ESP32-OTA-and-File-Manager does not yet support FFAT, a good start, but 10 months later still to be done? You should point that out in the above.

Thanks for the comment Timothy, I've changed the FFAT status to "Not implemented" as the utility isn't as necessary as before now that Arduino 2.X has file upload capability. If you want to do the work, please feel free to create a pull request.


text:
Why is my SPI clock voltage lower at higher frequencies?
I measured that the SPI-Clock of my Arduino Nano in my project didn't reach near 5V. So I quickly tested with a new one, nothing attached except a (mydaq) scope.
I measured the SPI clock:
2.5 V @ 8 Mhz;
3.6 V @ 4 Mhz;
5 V @ 1 Mhz.
I think the graph looks like that because the low max sample of the mydaq, so I dont worry to much about that. The MISO could reach about 5V but why is the clock voltage lower at higher frequencies? And how to reach 5V?

#include <SPI.h>

void setup() {
  SPI.begin();
  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
}

void loop() {
  SPI.transfer(1);
}

I also tried SPI mode 2 or 3 @8Mhz, idle state was 4,7 V but Vp-p again only 1,9 V.

It's not a lower voltage. You're just trying to measure it with something that is not capable of measuring it. To read a signal of 4MHz you need minimum 8Msps. For 8MHz you need minimum 16Msps. You cannot get the voltage with just a fraction of the samples you need to recover the waveform. Plus there will be a certain amount of low pass filtering happening massively reducing the frequencies this "mydaq" thing can read.

@Majenko I wondered why I can reach 5V at MOSI then? but now I transfered binary 1010 1010 @ 8Mhz and the MOSI line reading also "dropped". Thank you, that made a lot of sense actually :) Time for upgrade

You can use a peak detector to get an idea of the maximum voltage, and another one for the minimum, if you don't have a high enough sampling rate.

This is the second time the Nyquist frequency has come up in the last couple of days.
In order to accurately measure a changing signal, like you are doing, you need to sample at, at least, twice the frequency of the signal. If you don't your samples may give incorrect results because you are sampling partway up or down the curve.
To measure an 8 MHz signal, you therefore need to sample at 16 MHz, which you don't appear to be doing.

According to the MyDAQ specifications the analogue input has a pass-band filter of "DC to 400kHz". That means that at 400kHz the signal will be reduced by -3dB, and anything above that will be reduced even further, and the higher the frequency the more it will be reduced.
Further to that the MyDAQ samples at up to 200ksps, which means it can only capture a maximum frequency component of 100kHz.
The MyDAQ is little more than an educational toy. It's just a glorified sound card and really not worth wasting your time with.


text:
Arduino Pro Mini doesn't align nor connect in fritzing
When using fritzing (0.9.6) I notice that the Arduino Pro Mini 3.3 V component doesn't align nor connect to breadboard pins like other components.
Is this a bug or a feature?
I've tried to wiggle the board/component, disable/enable 'Align to Grid', but this doesn't help.
For comparison, a PIC or M1 blue pill aligns/connects fine, even after rotating both the board and components.
Update: To illustrate the issue:

Note on the left how the Arduino Mini Pro doesn't connect and doesn't align, i.e. its pins are between the rows.
For comparison, on the right a blue pill whose pins do align and auto-connect.

Mini has pins on all sides. it fits into breadboard if the pin headers on short sides are not installed or there are on the upper side.

@Juraj, ok, so a sane default would be to just have those pins on the short side disconnected/unaligned?

but in fritzing it doesn't matter if you have it in breadboard or next to it

@Juraj, it's a matter of convenience, with auto-connect you save to make some manual connections.

doesn't it snap to board pins too?

@Juraj No, it doesn't. It snaps (or aligns) them between the rows. I've added a screenshot to illustrate this. Btw, to add to my previous comment - it's not just a matter of convenience, i.e. the breadboard view is mainly about showing how the components are really placed on a real breadboard. And in reality the Mini Pro usually isn't placed besides the bread-board when it has standard headers. Being more abstract is the job of the schematic.

I asked about wire snapping to a board pin. I worked with Fritzing in the past, but I don't have it installed now and the download is not free.

@Juraj FWIW, it's available from the main Fedora repository (under the GPLv3) and likely from other distribution repositories as well. So under Linux it's just a dnf install fritzing or so away.

so the component is just bad. https://forum.fritzing.org/t/pins-not-aligning-with-board/9142/5

To the close voters: this question has been closed two times and was already re-opened one time. See also https://arduino.meta.stackexchange.com/a/2706/13174 for some arguments why it's on-topic. Previous comments arguing it being on-topic here were deleted, unfortunately. See also the help-center which explicitly states: 'Feel free to ask about anything related to Arduino.'

If it were a schematic you would have it finished, no alignment of pins.

There is a mostly corrected part available here:
https://forum.fritzing.org/t/arduino-mino-pro-3-3-v-doesnt-align-connect/15221/2
as noted it needs more corrections before being added to core parts (which will also require obsoleting the current part.)

The Pro Mini component you try to use in Fritzing has a bug in alignment possibly because of position units not specified.
You can fix it by editing the source code of the component as mentioned in this Fritzing forum thread: https://forum.fritzing.org/t/pins-not-aligning-with-board/9142/4

Short Answer...
I’m not an expert on the Fritzing sketch tool, however I’ll guess that the graphical anchor point on the board component shown in your question has been specified incorrectly and that if that bug was corrected, the long edge pins would snap to a breadboard component the same way as your comparative example. Noting that this would almost certainly leave some internal or short edge pins out of alignment with the breadboard grid (depending on the component PCB layout).
More information ...
(I'm pretty sure OP already knows this, but adding for a more generally usable answer)
Arduino Pro-mini was designed for “installations where space is premium and projects are made as permanent set ups”. Some of the design choices can be somewhat incompatible with breadboard which has a 0.1” (2.54mm) pitched square grid either side of a 0.3” (7.6mm) centre notch.
The open-source Pro-mini board has been immensely popular and there are many versions of PCB layout in circulation. Just three examples are shown below. There are many more.

When attaching headers for breadboard use, various configurations of pin headers placed above or below the PCB are used to bring out (predominantly) the long edge connections for the breadboard, while allowing the others to be accessible by leads.

Yes, I think the last assembled variant (i.e. down-facing headers on the long side, 90 degrees side-facing on the short side) is how it's used by most. Fritzing even has 2 revisions of the Arduino Pro Mini: Rev13 and Rev14. Whereas Rev13 does properly align and connect, but is only available as 5 V variant. Rev14 doesn't align/connect but is available in both 3 V/8 MHz and 5 V/16 MHz variants. Modeling it with down-facing headers on the long sides seems to be most flexible, since you still can put it beside the breadboard and connect wires.

Since we've established that this is likely a bug and that there isn't an easy way to change how the headers behave, I'll try to report it upstream such that perhaps the model gets fixed.

My bug report: https://forum.fritzing.org/t/arduino-mino-pro-3-3-v-doesnt-align-connect/15221

Fritzing parts only auto-connect if some pins are declared as male. This can be checked by looking at the part's XML file (search for <connector.*type=) or by opening the part in the 'new parts editor' (i.e. right-click->edit).
Note that it's ok for a part to have heterogeneous connector types. For example, male ones on the long sides and female ones on the short side. Which is what's used commonly with these parts, in reality. This is how for example the M1 Blue Pill or even the Arduino Pro Mini Rev13 (5V) Fritzing parts are defined, which thus auto-connect fine, as expected.
One can only speculate why the Arduino Pro Mini Rev14 (8 MHz/3.3 V and 16 MHz/5 V) parts were defined differently. Might be a bug or a deliberate design choice. However, for being a deliberate choice it would be only consequential to also draw female up-facing headers on the underlying SVG (cf. the Arduino UNO part, where this is done).

To work around this, one can edit the part, change all the connector types on the long sides from female to male and save it as new part - say - using the 'new parts editor', directly inside Fritzing. After that change the new part shows up under the 'MINE' parts category.
After that change the part auto-connects to the bread-board. However, the alignment is still broken, thus, for auto-connection one has to disable View->'Align to Grid'.

So to also fix the alignment some more sophisticated part editing is necessary.


text:
'PinStatus' does not name a type
I bought an "off-brand" ESP32 board. I can upload blinky without a problem using platformio with the following platformio.ini file:
[env:humidious]
platform = espressif32
board = nodemcu-32s
framework = arduino

However, as soon as I add lib_deps = grafana/PrometheusArduino@^0.3.0 the compiler throws the following errors:
In file included from .pio/libdeps/humidious/WiFiNINA/src/WiFiStorage.h:23:0,
                 from .pio/libdeps/humidious/WiFiNINA/src/WiFi.h:38,
                 from .pio/libdeps/humidious/PromLokiTransport/src/clients/ESP32Client.h:7,
                 from .pio/libdeps/humidious/PromLokiTransport/src/PromLokiTransport.h:8,
                 from .pio/libdeps/humidious/PrometheusArduino/src/PromClient.h:4,
                 from .pio/libdeps/humidious/PrometheusArduino/src/PrometheusArduino.h:5,
                 from src/main.cpp:4:
.pio/libdeps/humidious/WiFiNINA/src/utility/wifi_drv.h:293:12: error: 'PinStatus' does not name a type
     static PinStatus digitalRead(uint8_t pin);

It was suggested on another thread that the board was out of date, but updating this didn't help.
Adding typedef int PinStatus before #include <PrometheusArduino.h> didn't help either.

What Majeko said was correct. PIO was using WifiNINA instead of the ESP32's WiFi library. To solve this, I added lib_ignore = WiFiNINA to platformio.ini and #include <WiFi.h> before including the prometheus libraries in main.ino.
I tested this by pointing PrometheusArduino at my desktop with this example:
$ ncat -l 9090
POST /api/prom/push HTTP/1.1
Host: 192.168.0.45
Content-Type: application/x-protobuf
Content-Encoding: snappy
User-Agent: prom-arduino/0.2.2
Content-Length: 209

F

%
__name__uptime_milliseconds_total

job
esp32-test

hostD   @/@%@<@@/

heap_free_bytes
0

foobar
        0xA6..(0xA/

The problem here is that PlatformIO is picking up the wrong WiFi library. It has decided that the WiFi.h provided by WiFiNINA is the correct one to use, rather than the WiFi.h provided by the ESP32's bundled WiFi library.
You could try removing all traces of the WiFiNINA library from your PlatformIO installation, or maybe you need to manually specify which WiFi library should be used to preempt the autoselection routine.
I don't know how you do that in PlatformIO.


text:
Atmega2560 PWM on PH4
I am trying to convert the following code to output to pin 7 (PH4, OC4B) on an Arduino Mega. The code outputs to pin 6. This code is from a GitHub for the GRBL on the Mega "https://github.com/fra589/grbl-Mega-5X" out of the cpu_map.h It is clear that PH6 and PH7 are on the same PORTH but I just do not know what bits need changing to get GRBL to output on pin 7.Any help would be welcome.
#elif defined (SPINDLE_PWM_ON_D6)

    // Set Timer up to use TIMER4C which is attached to Digital Pin 6 - Ramps Servo 2
    #define SPINDLE_PWM_MAX_VALUE     255.0 // Translates to about 1.9 kHz PWM frequency at 1/8 prescaler
    #ifndef SPINDLE_PWM_MIN_VALUE
      #define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
    #endif
    #define SPINDLE_PWM_OFF_VALUE     0
    #define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)

    //Control Digital Pin 6 which is Servo 2 signal pin on Ramps 1.4 board
    #define SPINDLE_TCCRA_REGISTER    TCCR4A
    #define SPINDLE_TCCRB_REGISTER    TCCR4B
    #define SPINDLE_OCR_REGISTER      OCR4A
    #define SPINDLE_COMB_BIT          COM4A1

    // 1/8 Prescaler, 16-bit Fast PWM mode
    #define SPINDLE_TCCRA_INIT_MASK (1<<WGM41)
    #define SPINDLE_TCCRB_INIT_MASK ((1<<WGM42) | (1<<WGM43) | (1<<CS41))
    #define SPINDLE_OCRA_REGISTER   ICR4 // 8-bit Fast PWM mode requires top reset value stored here.
    #define SPINDLE_OCRA_TOP_VALUE  0xFF // PWM counter reset value. Should be the same as PWM_MAX_VALUE in hex.

    // Define spindle output pins.
    #define SPINDLE_PWM_DDR   DDRH
    #define SPINDLE_PWM_PORT  PORTH
    #define SPINDLE_PWM_BIT   3 // MEGA2560 Digital Pin 6

You want to replace pin 6 (PH3, OC4A) with pin 7 (PH4, OC4B). There are
three things you have to change. First, the output compare register,
which is OCR4A for pin OC4A and OCR4B for pin OC4B. Thus:
-#define SPINDLE_OCR_REGISTER      OCR4A
+#define SPINDLE_OCR_REGISTER      OCR4B

Then, the configuration bit that enables the output:
-#define SPINDLE_COMB_BIT          COM4A1
+#define SPINDLE_COMB_BIT          COM4B1

Last, the bit to set in the data direction register, which is 3 for PH3
and 4 for PH4:
-#define SPINDLE_PWM_BIT   3 // MEGA2560 Digital Pin 6
+#define SPINDLE_PWM_BIT   4 // MEGA2560 Digital Pin 7

Note: as in diff -u format, the prefix - means “remove this”, the
prefix + means “add this”.

Thanks for the help. I spent hours trying to figure out the datasheet.


text:
Having issues Connecting to a web server and pulling the data back
I have some arduino code where I am trying to pull information from four different locations.  Three are working great and the fourth I am not getting any response.
These two strings work perfect in a browser and I get the proper data response.
http ://10.196.1.163:8086/query?db=Garden&q=SELECT * FROM "Station" WHERE station = 61 ORDER BY DESC LIMIT 1
Or
http://10.197.1.57:8086/query?db=Garden&q=SELECT%20*%20FROM%20%22Station%22%20WHERE%20station%20=%2091%20ORDER%20BY%20DESC%20LIMIT%201

{"results":[{"statement_id":0,"series":[{"name":"Station","columns":["time","altitude","humid","moist","press","rainfall","soiltemp","station","temp","type","vbat","winddir","windspeed"],"values":[["2022-01-08T21:13:58Z",1269,29.2,0,28.5,0,0,91,73.4,9,4.32,0,0]]}]}]}

The code below is what I am trying to use.  It appears to make the connection but brings nothing back.
What I see in the console is:
  19:55:42.024 -> Starting connection to server: 10.196.1.163 InfluxDB Garden DB...
  19:55:42.024 -> connected to server
  19:55:42.024 ->

The next line is starting to connect to the next server which brings back the JSON data fine.
I have been assuming that I was having issues because of the alternate port 8086 I was connecting to, but I am not sure.  I have been looking and finding examples similar to what I am doing.
I must be just missing something, but I am not sure what. I have been working off and on for this issue for a couple of months.
void getLocalDataQuery2() {
  Serial.println("\nStarting connection to server: 10.196.1.163 InfluxDB Garden DB...");
  if (client.connect(server2, 8086)) {
    Serial.println("connected to server");
    client.print("GET /query?");
    client.print("db=Garden");
    client.println("&q=SELECT%20*%20FROM%20%22Station%22%20WHERE%20station%20=%2091%20ORDER%20BY%20DESC%20LIMIT%201");
    client.println("Host: 10.196.1.163");
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("unable to connect");
    while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
      // unsuccessful, retry in 4 seconds
      Serial.print("failed ... ");
      delay(4000);
      Serial.print("retrying ... ");
    }
  }
  String line = "";

  while(client.available())
  {
    line = client.readStringUntil('\n');

    Serial.print("Line : ");
    Serial.println(line);
  }
}

My solution to this was to setup a webserver running php code in a Docker container. The php code ran the influxdb query and sends the results

A client doesn't receive data immediately after sending a request. So client.available() returns 0 at first and your while loop is skipped.
The readStringUntil is one of the functions which wait for the next byte until timeout (1 second by default). So you can call readStringUntil first and it will wait for the data to arrive.
One way would be to replace the while loop with a do while loop, but the do while loop is strange and even experienced programmers don't like to use it.
In real application the first line of a HTTP response is important, because it contains the response status. The rest of the response header lines can be skipped.
So why not add reading of the first line before the while loop? This way readStringUntil will wait for the response and read the first line.
  String line = client.readStringUntil('\n');
  line.trim();
  Serial.print("Status line : ");
  Serial.println(line);

  while (client.available())
  {
    line = client.readStringUntil('\n');
    line.trim();
    Serial.print("Line : ");
    Serial.println(line);
  }

I tried this suggestion and still get no data back.  I see the following:
17:04:36.537 -> Starting connection to server: 10.196.1.163 InfluxDB Garden DB...
17:04:36.582 -> connected to server
17:04:37.558 -> Status line :
17:04:37.558 ->


text:
ESP32 stack error when reading from BLE device
I'm using this code here to read data from a BLE thermometer using an ESP32.
The code sometimes works fine and i can get the data:
+ Connect : a4:c1:38:69:0c:ff
 * Connected a4:c1:38:69:0c:ff
 + Found our service
 + Found our characteristic
 + Notify callback for characteristic ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6
temp = 21.8 C ; humidity = 48.0 % ; voltage = 2.564 V
 * Disconnected a4:c1:38:69:0c:ff

Other times i get a CPU panic, related to a stack error:
+ Connect : a4:c1:38:69:0c:ff
 * Connected a4:c1:38:69:0c:ff
 + Found our service
 + Found our characteristic
 + Notify callback for characteristic ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6
temp = 21.8 C ; humidity = 47.0 % ; voltage = 2.564 V
Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (btuT)
Core 0 register dump:
PC      : 0x4000c472  PS      : 0x00060a36  A0      : 0x8012b791  A1      : 0x3ffcf7e0
A2      : 0x3ffcf7f4  A3      : 0x00000000  A4      : 0x00000268  A5      : 0x3ffcfa14
A6      : 0x3ffde1ad  A7      : 0x00000026  A8      : 0x8012987e  A9      : 0x3ffd0270
A10     : 0x3ffdb99c  A11     : 0x3ffddca8  A12     : 0x3ffd050a  A13     : 0x00000001
A14     : 0x00000004  A15     : 0x00000000  SAR     : 0x00000010  EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000003

ELF file SHA256: 0000000000000000

Backtrace: 0x4000c472:0x3ffcf7e0 0x4012b78e:0x3ffcf7f0 0x40129815:0x3ffcfa80 0x40125e62:0x3ffcfd10 0x401286e8:0x3ffcfd30 0x4012987b:0x3ffcffc0 0x40125e62:0x3ffd0250 0x401286e8:0x3ffd0270 0x4012987b:0x3ffd0500 0x40125e62:0x3ffd0790 0x401286e8:0x3ffd07b0 0x4012940a:0x3ffd0a40 0x40125e62:0x3ffd0a60 0x40129621:0x3ffd0a80 0x40125e62:0x3ffd0aa0 0x4012933d:0x3ffd0ac0 0x40129359:0x3ffd0ae0 0x40125e62:0x3ffd0b00 0x40125fa1:0x3ffd0b20 0x4012fb36:0x3ffd0b40 0x401042a6:0x3ffd0b60 0x4008ff9e:0x3ffd0b90

Rebooting...

I'm using an ESP-WROOM-32 with PlatformIO, what could be the issue?

the issue could be a software bug

Same problem, but I fix it. Use lib https://github.com/h2zero/NimBLE-Arduino

To help others. I resolved this issue by using the ArduinoBLE lib instead of the ESP32_BLE one I was using.

Usually we're looking for a little internal structure to answers rather than one-liners. So, if you have any useful details to add, that would be nice. But, otherwise if that resolved it cool. Welcome to ASE.


text:
Power saving configuration of unconnected pins
By default, all Arduino (ATmega328P) pins are configured for input without the internal pull-up enabled. This default seems to come from the AVR microcontroller itself.
When it comes to saving power - is this an optimal configuration for unused (and thus unconnected) pins?
Section 14.2.6 Unconnected Pins of the ATmega328P datasheet (page 88) recommends to configure pull-ups in order to save power:

If some pins are unused, it is recommended to ensure that these pins have a defined level. Even though most of
the digital inputs are disabled in the deep sleep modes as described above, floating inputs should be avoided to
reduce current consumption in all other modes where the digital inputs are enabled (Reset, Active mode and
Idle mode).

The simplest method to ensure a defined level of an unused pin, is to enable the internal pull-up. In this case,
the pull-up will be disabled during reset. If low power consumption during reset is important, it is recommended
to use an external pull-up or pull-down.

So I'm tempted to call something like
for (uint8_t i = first_unused_pin; i < 20; ++i)
    pinMode(i, INPUT_PULLUP);

during setup.
Although, I don't understand where an increased power-consumption would come from when the INPUT pin is unconnected and no pull-up is active. I mean, since the pull-up is connected to VCC, there definitely is some current flowing, whereas without the pull-up I don't see where current would flow, since the pin is unconnected ...
However, Nick Gammon reports in his extensive article on power saving techniques (Section Configuring pins as inputs/outputs, Sketch D) an increased power consumption when 6 unused pins are configured as inputs with internal pull-ups attached:

All pins as inputs, and LOW (in other words, internal pull-ups disabled): 0.35 µA (same as before).
All pins as inputs, and HIGH (in other words, internal pull-ups enabled): 1.25 µA.

So the datasheet's statements seem to conflict with these results.
Is this an error in the datasheet are am I missing something?

Re “since the pull-up is connected to VCC, there definitely is some current flowing”: some current flowing where? For current to be able to flow, there must a complete path from Vcc to GND. The pull-up connects the pin to Vcc, what does connect it to GND?

@EdgarBonet leakage current that is. See also page 323 of the data sheet where max ' Input Leakage Current I/O Pin' is specified as 1 µA.

FWIW, "Input leakage current". https://electronics.stackexchange.com/a/325619/165322

Similar question on electronics SE: How should unused I/O pins be configured on ATMega328P for lowest power consumption?

Current is consumed when an input pin switches from HIGH to LOW or from LOW to HIGH. An unconnected "floating" input pin can change randomly depending on the local environment (EMI, noise, etc). That is unpredictable. The "it will consume more" is erroneous - it should be "it could consume more". The could is important, as I mentioned, it is unpredictable. By pulling up or down it is no longer unpredictable, as you have a defined steady state, and the input pin will not switch randomly.
Yes, you will get some leakage current through the pullup and the low-side MOSFET, but it is a defined predictable amount which you can incorporate into your design. If you want to reduce it then use larger external pullups (or pulldowns) to reduce the leakage current (note: using too large will start to encroach on the "floating" teritory again).
But when you're dealing with such small currents you're usually below the self-discharge equivalent current of your battery anyway, so saving a few nA isn't going to actually make the slightest bit of difference.

ok, yes, these are small amounts - re: '[..] so saving a few nA isn't going to actually make the slightest bit of difference'. Perhaps I'm missing something here, but isn't such leakage additive? I mean the self-discharge of a battery I have in any case - and on top of that I have to account for any additional leakage current, right? Also, what would be the worst-case that could happen when no pull-up is configured/attached to an unconnected input pin in terms of power usage (or something else)?

@maxschlepzig It's not quite as simple as that, since self discharge isn't a current per se, it's an effect of the chemistry of the battery. For example an NiMH can lose 30% of its charge in a month (NiMH is one of the worst for self discharge). But of course what current you draw is drawn from what is left in the battery, which is constantly depleting, and the less you draw the longer it will last, but when you've got (as in the NiMH example) about 3 months of potential runtime anyway trying to save enough power to last 6 months just isn't going to happen.

You could try feeding a high frequency (few MHz) signal into all the unconnected pins when set as INPUT and measure the sleep current to see how (if) it increases.

That's a great idea Majenko!

Although, I don't understand where an increased power-consumption would come from when the INPUT pin is unconnected and no pull-up is active.

This part of your question already has 2 answers, so I'll just answer the "power saving part".
The data sheet says "If some pins are unused, it is recommended to ensure that these pins have a defined level.". Configuring them with pinMode() to OUTPUT, then driving them LOW using digitalWrite() is perfectly acceptable, and MAY offer the greatest power saving / noise immunity of all.
If you look at "14.3 Alternate Port Functions" on page 89, you get a glimpse of the internal digital logic circuitry. When set to OUTPUT, the internal circuits provides a low impedance path to ground to sink current. What ever part of the internal circuitry that was "oscillating due to a floating input pin", causing the extra power consumption, is now connected to ground, or it's input is ignored, or how ever Microchip did it.
When you follow the I/O pin on Figure 14-2, it shows the INPUT_PULLUP circuitry at the top of the diagram, followed by the tri-state control lower down, then the SLEEP circuitry comprised of an analogue switch OR transmission gate if you prefer, inverter gate and N channel FET. When the Arduino is in some sleep modes, it "disconnects" the pin with the analog switch, and also grounds the Schmitt trigger input at the same time. What would be cool is if you could write "Arduino code" in the IDE to toggle this ON/OFF programmatically.

From the data sheet:

14.2.5 Digital Input Enable and Sleep Modes
As shown in Figure 14-2, the digital input signal can be clamped to ground at the input of the Schmitt Trigger. The signal denoted SLEEP in the figure, is set by the MCU Sleep Controller in Power-down mode, Power-save mode, and Standby mode to avoid high power consumption if some input signals are left floating, or have an analog signal level close to VCC/2.

The bottom line is, you don't want unused pins set as INPUT (Tri-state (Hi-Z) mode). See "Table 14-1. Port Pin Configurations".

My earlier testing would seem to confirm that setting the pins to OUTPUT and LOW probably has the lowest power consumption. In my tests setting them to INPUT also had low consumption, but that would probably vary depending on what is going on around the pins.

Ok - one issue with that approach (setting an unconnected pin to OUTPUT+low) is perhaps the behavior during reset, i.e. where the pin is set to INPUT for a short time. So, connecting external pull-ups to unused pins (and keeping them as INPUT) would help with that. However, I guess if you don't reset much, the savings (of OUTPUT+low vs. INPUT+pull-up) offset the potential 'waste' during reset by a large margin. I don't know, connecting all unused pins to external pull-ups feels a bit excessive.

@maxschlepzig - I don't recommend connecting the unused pins to anything. Are you commenting on something I've written in my answer, or on the comment above yours made by Nick Gammon?

@maxschlepzig - Page 619 of the data sheet may shed some light on how much current is used during the re-set process. See: 35.12 Current Consumption in Reset and Reset Pulsewidth

@VE7JRO I didn't say that you did. In my comment I just wanted to discuss the trade-offs of the method described in your answer (i.e. OUTPUT+low). So reset-behavior is - arguably - its only drawback, AFAICS - so, I just mentioned INPUT+external pull-up since it's the only alternative that yields a defined level also during reset. What I mean with reset behavior is this: during reset an unconnected pin (previously set to OUTPUT+low) is reset to INPUT until setup() runs. During that time-window of 1 s or so the level isn't defined, yet. 35.12 doesn't deal with that scenario, right?

@maxschlepzig - Have you tested to see if those inputs are floating for one second? If they are, then I would say the answer to your question, is in your question - "If low power consumption during reset is important, it is recommended to use an external pull-up or pull-down.". The data sheet also says not to tie the pins directly to power or ground because of damage "IF" you happen to set the pins to input/output with "code" by mistake. If there is no possible way for you code to set the un-used inputs to VCC or GND, then connect them directly to ground.

@VE7JRO no, I haven't tried to measure those inputs, yet. See also Majenko's answer and comments on how measuring the consequences of an unconnected INPUT (without pull-up) isn't exactly trivial.

@maxschlepzig - In that case, just do what the data sheet recommends.

The theory here is that an pin without a pull-up will probably float somewhere around the switching voltage. A bit of noise from the surroundings or whatever might push the pin up or down slightly, which will cause the internal circuitry to "flip" from high to low (or vice versa). All that flipping consumes quite a lot of power. The little tiny trickle from a pull-up resistor is so much smaller than the "flip cost" that it's worth using them.
I should also mention that it's very hard to test for a floating pin's consumption of power. Whenever you test it, you'll find it behaving very nicely, but as soon as you put it into a proper application it'll go crazy and won't work anywhere near your expectation. Putting in pull ups avoids this uncertainty, and lets you work with whatever the power consumption is when they're present.
I don't have the results any longer, but a while back I tried measuring the power consumption of the Arduino in various "idle" modes. The theory and practice did't match up terribly well.
It's possibly worth doing some tests, but IIRC, the lowest power setup was to set all pins as inputs and pull them low. In practice that's a lot of work to arrange, so setting them as inputs and using the internal pull-ups works nearly as well.
What you'll also find is that almost anything else will save far more power than the little trickle in the internal pull-ups. Here are some guides which might help:

https://learn.sparkfun.com/tutorials/reducing-arduino-power-consumption/all
https://www.makeuseof.com/tag/arduino-power-saving-tips/
https://docs.arduino.cc/learn/electronics/low-power
https://arduino.stackexchange.com/a/50734/26212


text:
How many bits long,at most, is the seed in the randomSeed() function?
I can not find a concrete reference to how many bits long the (input) seed for the  randomSeed() function is for Arduino given here
https://www.arduino.cc/reference/en/language/functions/random-numbers/randomseed/
In the above webpage , though it is the official Arduino document for randomSeed(), it does not concretely say if the maximum bit length of the seed is 8,16 or 32 bits.
I think it is 16 bits long (in other words the seed is in the
range of integers 0 and 65535). So for example the maximum input to randomSeed would be expressed as randomSeed(65535).
But I do not know for sure if the seed input is 16 bits at most.
So my question is the seed used in randomSeed() 16 bit length at most  (thus having a maximum value of 65535).
32 bits is comparable to a 32bit windows desktop computers so I think 32 bits is too large for the input seed to randomSeed(). I am also using an Arduino Uno with Arduino IDE version 1.6.7 (if that matters regarding the input bit length of the seed).

As stated on the page you link to:

seed: number to initialize the pseudo-random sequence. Allowed data types: unsigned long.

Therefore it's 32 bits, since that is what unsigned long is.


text:
How to prevent an alarm which checks minutes from going off many times within one minute?
How do I prevent an alarm, which checks if the current time matches an alarm time in hours and minutes, from going more than once within one minute?
I am using the DS3231 RTC module and RTClib from adafruit. I want to check if the current time equals to the alarm time, then set the alarmFlag variable. I want to clear alarmFlag when a button on pin D5 is pressed.
The code below works fine as long as I don't press the button within about a minute from the start of the alarm. If I press the button within about a minute from the start of the alarm, the alarmFlag will be 0 for one loop() cycle, but then (almost immediately, I don't have much in loop()) will be back to 1. I want for the button to stop the alarm completely, so it fires again only on the next day.
uint8_t alarm[2] = {19, 30}; // hour (24), minute

// other code ...

void loop() {

  currTime = rtc.now();

  // check if current time matches alarm time
  // if it matches, it matches for a whole minute, which is the problem here
  if (!alarmFlag && alarm[0] == currTime.hour() && alarm[1] == currTime.minute()) {
    alarmFlag = true;
  }

  // clear alarmFlag on button press (this is a shortened version, excuse the lack of debouncing/other stuff)
  if (digitalRead(5) == HIGH) {
    alarmFlag = false;
  }

}

Notes:

I can not use the RTC's built-in alarms because I need them elsewhere.
I don't want to just add currTime.seconds() == 0 to the first if statement, because that would skip the alarm if the loop() cycle takes more than a second.
I know that the way I detect a button press in the example code is suboptimal, I wrote a better way to deal with this in my main code, but I don't want to clutter up this question.

Have you tried adding the current seconds to your first if statement? Something like this: alarm[2] == currTime.seconds(). Oh, and maybe this too: uint8_t alarm[3] = {19, 30, 0};.

store the minute when the alarm triggered ... do not trigger alarm if stored minute equals current minute ... or use another flag to signify that an alarm already raised

You might want to read about "finite state machines" because this is what you have here. Granted, a really simple one, but this knowledge will be valuable in your future life as a developer. You will need at least 3 states: armed, triggered, muted. The transition conditions and how to implement it is left as an exercise for you.

Make your alarmFlag have three states, 0 for false, 1 for alarming, 2 for muted.

I'd prefer to make a comment rather than an answer; however, I'm not allowed to do so. I use a single RTC interrupt to service any number of actual alarms. Each time I activate a new alarm it is sorted into a linked list with the earliest scheduled alarm at the head. Then I setup the RTC hardware to interrupt when that time is reached. The listhead is discarded once its interrupt occurs and the next one on the list is setup in the RTC.

@MarkLossner But you actually made a comment...

As suggested by the busybee, this is a textbook application of the
concept of finite state machine. Below is a state diagram that
hopefully captures the desired behavior. Its meaning is hopefully
obvious at first sight.

Here your alarmFlag is replaced by the TRIGGERED state. Please note
that, with this state machine, the only way to turn the alarm off is to
press the button. If nobody is there to press it, is goes on forever.
This kind of issue is quite obvious when looking at the state diagram,
less so when looking at the code. This is why it is advisable to draw a
state diagram before you start coding. If this behavior is a not
desirable, you may add an extra transition out of the TRIGGERED state,
which would happen on a timeout.
It is also worth noting that, with this state machine, pressing the
button multiple times in quick succession has the same effect as
pressing it once. In other words, there is no point in debouncing the
button.
For implementing this in C++, I suggest you follow the steps of this
tutorial on finite state machines.

If you add a delay(60*1000) to your button press function, then you will essentially have a cool off period before the alarm is checked again.  The alarm cannot go off again during that delay;
For non-blocking code, you could store the time you pushed the button, and then check that time before checking it's the alarm time.
    //code to add to your button press
    lastbuttonpress = millis();

    //code to add before your alarm check
    if (lastbuttonpress - millis() > 60*1000) {
        //do your alarm check
    }

does it mean you can't stop the alarm until it runs one minute?

no, the alarm would be stopped immediately on button press.  These recommendations only prevent the alarm from being triggered again within one minute of the alarm being silenced

but the time for the end of the problem is known and why have a 4 byte variable instead of a 1 byte bool and wait more than necessary


text:
I am trying to use Arduino Uno as a hid device to login Windows but I cannot use Modifier keys to Lock Windows
uint8_t buf[8] = { 0 };
#include <SPI.h>
#include <MFRC522.h> // RFID library
#define SS_PIN 10 //RX slave select
#define RST_PIN 9
int gled = 7; // optional
int rled = 4;// optional
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
String card_ID=""; //
String password="" ; // Change It To Your Windows / fb / any Account's Password
String rfid="8";// UID (unique Id Code Of Your Rfid Tag)
void setup() {
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin();  // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card
  pinMode(gled,OUTPUT);
  pinMode(rled,OUTPUT);
}
void loop() {
  //look for new card
   if ( ! mfrc522.PICC_IsNewCardPresent()) {
  return;
 }
 if ( ! mfrc522.PICC_ReadCardSerial()) {
  return;//if read card serial(0) returns 1, the uid struct contians the ID of the read card.
 }
 for (byte i = 0; i < mfrc522.uid.size; i++) {
   card_ID += mfrc522.uid.uidByte[i];
 }
// Serial.println(card_ID);
       if(card_ID==rfid){digitalWrite(gled,HIGH);
      typeLiteralString(password);
      pressKey("enter"); releaseKey("enter");
     digitalWrite(gled,LOW); delay(200);digitalWrite(gled,HIGH); delay(200);digitalWrite(gled,LOW);
      }
      if(card_ID!=password){
digitalWrite(rled,HIGH);    digitalWrite(rled,LOW); delay(200);digitalWrite(rled,HIGH); delay(200);digitalWrite(rled,LOW);  }      else{ goto cont;}
delay(1000);
cont:
delay(1000);
card_ID="";
}
boolean isModifier(int keycode) {
    boolean result = false;
    if (keycode >= 224 && keycode <= 231) { // if the keycode is a modifier key
        result = true;
    }
    return result;
}

void pressModifier(String keyname) {
    pressModifier(getKeycode(keyname));
}
void pressModifier(int keycode) {
    int modifiermask = 0;
    if (isModifier(keycode)) { // if the keycode represents a modifier key
        modifiermask = getModifierMask(keycode);
        buf[0] = buf[0] | modifiermask;
        Serial.write(buf, 8); // Send key report
    }
}

void releaseModifier(String keyname) {
    releaseModifier(getKeycode(keyname));
}
void releaseModifier(int keycode) {
    int modifiermask = 0;
    if (isModifier(keycode)) { // if the keycode represents a modifier key
        modifiermask = getModifierMask(keycode);
        buf[0] = buf[0] & (~modifiermask);
        Serial.write(buf, 8); // Send key report
    }
}
void releaseAllModifiers() {
    buf[0] = B00000000;
    Serial.write(buf, 8); // Send key report
}

void pressKey(String keyname) {
    pressKey(getKeycode(keyname));
}
void pressKey(int keycode) { // TODO: cycle the 6 key spots in the report buffer instead of just using buf[2] each time.
    buf[2] = keycode;
    Serial.write(buf, 8); // Send key report
}

void releaseKey(String keyname) {
    releaseKey(getKeycode(keyname));
}
void releaseKey(int keycode) {
    // find the keycode in the report buffer, then set it to zero.
    int i=0;
    for (i=2; i<8; i++) {
        if (buf[i] == keycode) {
            buf[i] = 0;
        }
    }
    Serial.write(buf, 8); // Send key report
}
void releaseAllKeys() {
    int i=0;
    for (i=2; i<8; i++) {
        buf[i] = 0;
    }
    Serial.write(buf, 8); // Send key report
}

void pressSequenceOfKeys(const char * keySequence[], int numberOfKeys) {
    // This function can be good for pressing a few keys while holding a modifier down for example.

    int i = 0;
    for (i=0; i<numberOfKeys; i++) {
        pressKey(keySequence[i]);
        releaseKey(keySequence[i]);
    }
}

void typeLiteralString(String string) {
    char charArray[string.length()+1];
    string.toCharArray(charArray, string.length()+1);
    typeLiteralString(charArray, string.length());
}
void typeLiteralString(char string[], int stringLength) { // stringLength is the length of the printable string without considering the null byte.
    // This function will type the given string exactly as given, automatically pressing left_shift where necessary for capitals and symbols.

    // just in case:
    releaseAllKeys();
    releaseAllModifiers();

    boolean charNeedsShift = false;
    boolean shiftIsPressed = false;

    int i=0;
    for (i=0; i<stringLength; i++) {
        charNeedsShift = characterNeedsShift(string[i]);
        if (charNeedsShift && !shiftIsPressed) {
            pressModifier("left_shift");
            shiftIsPressed = true;
        }
        else if (!charNeedsShift && shiftIsPressed) {
            releaseModifier("left_shift");
            shiftIsPressed = false;
        }
        pressKey(String(string[i])); // without converting the char in string[i] to a String, arduino would prefer the pressKey(int) function instead of the pressKey(String) function, casting the char to a keycode (int) instead of a keyname (String).
        releaseKey(String(string[i])); // same as previous comment, but with releaseKey().
    }

    releaseAllModifiers();
}

boolean characterNeedsShift(char character) {
    int needsModifier = false;
    if ( // look up an ascii table and this will make sense.
        (character >= 33 && character <= 38)
        || (character >= 40 && character <= 43)
        || (character == 58)
        || (character == 60)
        || (character >= 62 && character <= 90)
        || (character >= 94 && character <= 95)
        || (character >= 123 && character <= 126)
    ) {
        needsModifier = true;
    }
    return needsModifier;
}

int getKeycode(String keyname) {
    String key = String(keyname); // Use a copy so that we don't mutate the user's String. Not sure if this is needed, but just in case. TODO: find out.
    key.toLowerCase();

    int keycode = 0; // keycode of zero means nothing pressed.

    // non-modifier keys
    if      (key == "a") { keycode =  4; }
    else if (key == "b") { keycode =  5; }
    else if (key == "c") { keycode =  6; }
    else if (key == "d") { keycode =  7; }
    else if (key == "e") { keycode =  8; }
    else if (key == "f") { keycode =  9; }
    else if (key == "g") { keycode = 10; }
    else if (key == "h") { keycode = 11; }
    else if (key == "i") { keycode = 12; }
    else if (key == "j") { keycode = 13; }
    else if (key == "k") { keycode = 14; }
    else if (key == "l") { keycode = 15; }
    else if (key == "m") { keycode = 16; }
    else if (key == "n") { keycode = 17; }
    else if (key == "o") { keycode = 18; }
    else if (key == "p") { keycode = 19; }
    else if (key == "q") { keycode = 20; }
    else if (key == "r") { keycode = 21; }
    else if (key == "s") { keycode = 22; }
    else if (key == "t") { keycode = 23; }
    else if (key == "u") { keycode = 24; }
    else if (key == "v") { keycode = 25; }
    else if (key == "w") { keycode = 26; }
    else if (key == "x") { keycode = 27; }
    else if (key == "y") { keycode = 28; }
    else if (key == "z") { keycode = 29; }

    else if (key == "1" || key == "!") { keycode = 30; }
    else if (key == "2" || key == "@") { keycode = 31; }
    else if (key == "3" || key == "#") { keycode = 32; }
    else if (key == "4" || key == "$") { keycode = 33; }
    else if (key == "5" || key == "%") { keycode = 34; }
    else if (key == "6" || key == "^") { keycode = 35; }
    else if (key == "7" || key == "&") { keycode = 36; }
    else if (key == "8" || key == "*") { keycode = 37; }
    else if (key == "9" || key == "(") { keycode = 38; }
    else if (key == "0" || key == ")") { keycode = 39; }

    else if (key == "enter" || key == "return")     { keycode = 40; }
    else if (key == "escape" || key == "")    { keycode = 41; }
    else if (key == "backspace" || key == "") { keycode = 42; }
    else if (key == "tab" || key == "  ")      { keycode = 43; }
    else if (key == "space" || key == " ")      { keycode = 44; }

    else if (key == "-" || key == "_")  { keycode = 45; }
    else if (key == "=" || key == "+")  { keycode = 46; }
    else if (key == "[" || key == "{")  { keycode = 47; }
    else if (key == "]" || key == "}")  { keycode = 48; }
    else if (key == "\\" || key == "|") { keycode = 49; }
    else if (key == ";" || key == ":")  { keycode = 51; }
    else if (key == "'" || key == "\"") { keycode = 52; }
    else if (key == "`" || key == "~")  { keycode = 53; }
    else if (key == "," || key == "<")  { keycode = 54; }
    else if (key == "." || key == ">")  { keycode = 55; }
    else if (key == "/" || key == "?")  { keycode = 56; }

    // TODO: Fix these keycodes. V
    else if (key == "capslock")         { keycode = 58; }

    else if (key == "f1")      { keycode = 59; }
    else if (key == "f2")      { keycode = 60; }
    else if (key == "f3")      { keycode = 61; }
    else if (key == "f4")      { keycode = 62; }
    else if (key == "f5")      { keycode = 63; }
    else if (key == "f6")      { keycode = 64; }
    else if (key == "f7")      { keycode = 65; }
    else if (key == "f8")      { keycode = 66; }
    else if (key == "f9")      { keycode = 67; }
    else if (key == "f10")     { keycode = 68; }
    else if (key == "f11")     { keycode = 69; }
    else if (key == "f12")     { keycode = 70; }

    else if (key == "print_screen")    { keycode = 70; }
    else if (key == "scroll_lock")     { keycode = 71; }
    else if (key == "pause")           { keycode = 72; }
    else if (key == "insert")          { keycode = 73; }
    else if (key == "home")            { keycode = 74; }
    else if (key == "page_up")         { keycode = 75; }
    else if (key == "delete")          { keycode = 76; }
    else if (key == "end")             { keycode = 77; }
    else if (key == "page_down")       { keycode = 78; }

    else if (key == "right_arrow")     { keycode = 79; }
    else if (key == "left_arrow")      { keycode = 80; }
    else if (key == "down_arrow")      { keycode = 81; }
    else if (key == "up_arrow")        { keycode = 82; }

    else if (key == "numlock" || key == "clear")   { keycode = 83; }

    //TODO: keypad and miscellaneous keys if you want them.

    // modifier keys.
    else if (key == "left_control")  { keycode = 224; }
    else if (key == "left_shift")    { keycode = 225; }
    else if (key == "left_alt")      { keycode = 226; }
    else if (key == "left_gui")      { keycode = 227; }

    else if (key == "right_control") { keycode = 228; }
    else if (key == "right_shift")   { keycode = 229; }
    else if (key == "right_alt")     { keycode = 230; }
    else if (key == "right_gui")     { keycode = 231; }

    return keycode;
}

int getModifierMask(String keyname) {
    return getModifierMask(getKeycode(keyname));
}
int getModifierMask(int keycode) { // return value of 0 means key is not a modifier.
    int modifiermask = 0;

    // NOTE: these are not the usage keycodes like for other keys, but rather the bit masks.
    if      (keycode == 224) { modifiermask = B00000001; } // left ctrl
    else if (keycode == 225) { modifiermask = B00000010; } // left shift
    else if (keycode == 226) { modifiermask = B00000100; } // left alt
    else if (keycode == 227) { modifiermask = B00001000; } // left gui
    else if (keycode == 228) { modifiermask = B00010000; } // right ctrl
    else if (keycode == 229) { modifiermask = B00100000; } // right shift
    else if (keycode == 230) { modifiermask = B01000000; } // right alt
    else if (keycode == 231) { modifiermask = B10000000; } // right gui

    return modifiermask;
}

The Uno cannot be used as HID. It has no native USB support. Your code relies on some program running on the PC

Or have you reflashed your USB chip with some HID firmware?

what are you using on windows side to press keys?

are you able to type text into a notepad window?


text:
Arduino diagrams
I would like to document some of the experiments I have been doing with the arduino.
In many of the internet posts on Arduino projects, they have a similar diagram of the Uno or Mega with breadboards and resistors.  Some with more detail than others.  I've been looking at many of these articles to see if they mention what drawing package they are using but nobody seems to do so.
I could take one of them and just colour out the wires but I can't get the right shade of grey or green.

What diagramming tool can be used for drawing these diagrams?
Where can I get hold of a blank Arduino Mega/Uno/Nano template.

https://fritzing.org/

Found that you can also do this on https://www.tinkercad.com  Currently, it only does Uno.  This one has a built in simulator.

As Juraj commented, those kinds of pictorial diagram are often made using a program called Fritzing.
You should also try producing a more traditional and useful diagram called a schematic. Fritzing can do that at the same time. There are also free programs that are better. See KiCAD, Eagle, EasyEDA etc.
You might find online emulators like Wokwa to be usefull.

Related:
Many of the Rules and guidelines for drawing good schematics also apply to Fritzing's pictorial diagrams.


text:
servo motor and l298n motor driver doesn't work together with esp32
so basically I am using 4 servo motors for our robotic arm and 1 l298n motor driver for 2 motor drive for base of the arm. when I individually tested robotic arm and controlled 4 servo motors, it worked perfectly fine, at the same time when i tested linear motion with motor driver individually it also worked fine. But when I combined them only servos are working but l298n doesn't. when I comment out servos.attach() line, then again motor driver works. Pins are different. That's why even I couldn't figure out why am i getting this issue.
#include <WiFi.h>
#include <WebServer.h>
#include <Robojax_L298N_DC_motor.h>
#include<Servo.h>

WebServer server(80);
Servo myservo,shoulder,elbow,wrist;
int grippos=0,shoulderpos=0,elbowpos=0,wristpos=0;

// motor 1 settings
#define CHA 0
#define ENA 19 // this pin must be PWM enabled pin if Arduino board is used
#define IN1 18
#define IN2 5

// motor 2 settings
#define IN3 15
#define IN4 2
#define ENB 4// this pin must be PWM enabled pin if Arduino board is used
#define CHB 1

const int CCW = 2; // do not change
const int CW  = 1; // do not change

#define motor1 1 // do not change
#define motor2 2 // do not change

String prev="";

Robojax_L298N_DC_motor robot(IN1, IN2, ENA, CHA,  IN3, IN4, ENB, CHB);

void gripopen()
{
  Serial.println("open");
  grippos+=30;
  if(grippos>180)
  {
    grippos=180;
  }
  myservo.write(grippos);

}

void gripclose()
{
  grippos-=30;
  Serial.println("close");

  if(grippos<0)
  {
    grippos=0;
  }
  myservo.write(grippos);

}

void wristleft()
{
  wristpos-=30;
  Serial.println("wristleft");
  if(wristpos<0)
  {
    wristpos=0;
  }
  wrist.write(wristpos);
}

void wristright()
{
  Serial.println("wristright");
  wristpos+=30;
  if(wristpos>180)
  {
    wristpos=180;
  }
  wrist.write(wristpos);
}

void elbowup()
{
  Serial.println("elbow up");
  elbowpos+=15;
  if(elbowpos>180)
  {
    elbowpos=180;
  }
  elbow.write(elbowpos);
}

void elbowdown()
{
  Serial.println("elbow down");
  elbowpos-=15;
  if(elbowpos<0)
  {
    elbowpos=0;
  }
  elbow.write(elbowpos);
}

void shoulderup()
{
  Serial.println("shoulder up");
  shoulderpos+=15;
  if(shoulderpos>180)
  {
    shoulderpos=180;
  }
  shoulder.write(shoulderpos);
}

void shoulderdown()
{
  Serial.println("shoulder down");
  shoulderpos-=15;
  if(shoulderpos<0)
  {
    shoulderpos=180;
  }
  shoulder.write(shoulderpos);
}

void forward()
{
    Serial.println("forward");
    robot.rotate(motor1,100,CW);
    robot.rotate(motor2,100,CCW);

Serial.println("end reached");

}

void backward()
{
    Serial.println("backward");
        robot.rotate(motor1,100,CCW);
    robot.rotate(motor2,100,CW);
  Serial.println("end reached");

}

void left()
{
    Serial.println("left");
        robot.rotate(motor1,100,CW);
    robot.rotate(motor2,100,CW);
Serial.println("end reached");

}

void right()
{
    Serial.println("right");
      robot.rotate(motor1,100,CCW);
    robot.rotate(motor2,100,CCW);
Serial.println("end reached");

}

void stopbot()
{
  Serial.println("stopbot");
  robot.brake(1);
  robot.brake(2);
  prev="";
  Serial.println("end reached");
}

void reset()
{
  myservo.write(0);
  shoulder.write(0);
  elbow.write(0);
  wrist.write(0);
}

void handleRoot() {
  server.send(200, "text/plain", "Ready");
}

void handleGet() {
  if (server.hasArg("data")) {
    String data = server.arg("data");
    if(data=="gripper_open")
    {
      gripopen();
    }
    else if(data=="reset")
    {
      Serial.println("Reset");
    }
    else if(data=="Stop")
    {
      stopbot();
    }
    else if(data=="Forward")
    {
     // forward();
      if(prev!=data)
      {
        forward();
        prev=data;
      }
    }
    else if(data=="Backward")
    {
     // backward();
      if(prev!=data)
      {
        backward();
        prev=data;
      }
    }
    else if(data=="Left")
    {
      //left();
      if(prev!=data)
      {
        left();
        prev=data;
      }
    }
    else if(data=="Right")
    {
      //right();
      if(prev!=data)
      {
        right();
        prev=data;
      }
    }
    else if(data=="gripper_close")
    {
      gripclose();
    }
    else if(data=="elbow_up")
    {
      elbowup();
    }
    else if(data=="elbow_down")
    {
      elbowdown();
    }
    else if(data=="shoulder_up")
    {
      shoulderup();
    }
    else if(data=="shoulder_down")
    {
      shoulderdown();
    }
    else if(data=="Wrist_left")
    {
      wristleft();
    }
    else if(data=="Wrist_right")
    {
      wristright();
    }
    Serial.println("Data: " + data);

  }
  server.send(200, "text/plain", "Data Received");
}

void handlePost() {
    if (server.hasArg("data")) {
    String data = server.arg("data");
    Serial.println("Data: " + data);
  }
 // server.send(200, "text/plain", "Data Received");
  server.send(200, "text/plain", "Processing Data");
}

void handleUpload() {
  HTTPUpload& upload = server.upload();
  if (upload.status == UPLOAD_FILE_START) {
    Serial.println("Receiving data:");
  } else if (upload.status == UPLOAD_FILE_WRITE) {
    Serial.write(upload.buf, upload.currentSize);
  } else if (upload.status == UPLOAD_FILE_END) {
    server.send(200, "text/plain", "Data: ");
  }
}

void setup() {
  Serial.begin(9600);
  WiFi.softAP("ESP32");
  myservo.attach(13);
  shoulder.attach(12);
  elbow.attach(14);
  wrist.attach(27);

  myservo.write(0);
  shoulder.write(0);
  elbow.write(0);
  wrist.write(0);

  // motordriver pins
  robot.begin();

  server.on("/", handleRoot);
  server.on("/get", HTTP_GET, handleGet);
  server.on("/pot", HTTP_POST,handlePost);
  server.begin();
}

void loop() {
  server.handleClient();
}

I am receiving correct data from the app. That also I had cross-checked. If anyone can help with this or guide me how can i solve this issue.

How do you power everything?

12v lithium polymer battery 2200mAh. @chrisl

And I guess you have connected the 12V from the battery directly to the L298N for powering the motor with 12V, am I right? I don't see an obvious error. Is the Serial output as expected? Have you checked the voltages (if they really stay as expected and not go down when running the motor)?

yes input voltage to l298n shows to be around 12v. also I have kept ground common with esp32. Serial monitor also gives correct output indicating that right function is being called. that's why I also don't understand where the issue lies. @chrisl

This tutorial states that you cannot use the standard Servo library for an ESP32. Honestly I would think that this isn't a problem anymore, but you could try the library, that is mentioned there.

honestly the library that I have used is for servo with esp32 only. library isn't a problem i guess @chrisl

Hi I have the same problem here, and everything is pointing the issue could be related with the channels shared for PWM. In the Robojax lib there is control of channels want to assign for each motor, but in the ESP32Servo the channels are assigned automatically by the library in consecutive order (see ESP32PWM.cpp). I would try use different channel when calling Robojax that doesn't make conflict with the amount of Servo controlled, maybe could help. For instance in my case I have one servo and 2 DC motors controlled by LN98. So the servo is using channel 0 for PWM, the other two motors on Robojax I will try CHA= 2 and CHB = 3. Maybe this could help.
There are timers shared is explained on the ESP32PWM.cpp, line 259, but I believe the channels conflicts is what is causing this issue.
I will try and let you know. Thanks
I already finished, and for me it is working now. Just need to change CHA and CHB to different PWM channel number (0-15), but > than the amount of servo you have. thanks

actually even I felt the same and I was going to try that today. I guess it will work. Thank you bro


text:
Arduino not rebooting with watchdog enabled
I have a custom board that is switching an inductive load through a 10A@230V ac relay.
Due to a poor design, voltage spikes are causing the board to reboot from time to time (brown-out, watchdog and "unknown reason")
The problem here is that from time to time, the microcontroller freezes and no longer executes code (or at least, it seems so), even if the watchdog should be running.
I programmed the WDTON and BROWN-OUT fuses, so the watchdog should be always on.
Once the microcontroller is frozen, an external reset makes it work again.
My questions:
Is there any SOFTWARE fix to guarantee that the device never freezes. Am I using the watchdog incorrectly?
I read in the Atmega 328P datasheet about the 4 cycle restriction between the WDE writing and the prescaler bits writing (page 44), but It´s not clear to me if this restriction applies when WDON fuse is programmed.
Also, I couldn´t find what the "wdt_enable (WDTO_2S);" instruction is doing under the hood.
Is it possible that the watchdog oscillator stops due to a voltage spike?
This is my code (the part to illustrate the watchdog problem)
Hardware: Custom board
microcontroller: ATmega 328P
Brown-out fuse: programmed
WDTON fuse: programmed

#include <avr/wdt.h>

#define R0          3 // Relay output 16A @ 230Vac (10A @ 230Vac)
#define R1          4 // Relay output 10A @ 230Vac (10A @ 230Vac)
#define R2          5 // Relay output 10A @ 230Vac (10A @ 230Vac)

byte outputs;

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

void test() {

#define TEST_SWITCHING_INTERVAL  500

  static unsigned long previousMillisTest;
  static int count;

  unsigned long actualTemp = millis();
  if ((actualTemp - previousMillisTest) >= TEST_SWITCHING_INTERVAL) {
    bitWrite (outputs, 0, !bitRead (outputs, 0)); Serial.print ("R0 = ");    Serial.print (bitRead (outputs, 0));
    bitWrite (outputs, 1, !bitRead (outputs, 1)); Serial.print ("   R1 = "); Serial.print (bitRead (outputs, 1));
    bitWrite (outputs, 2, !bitRead (outputs, 2)); Serial.print ("   R2 = "); Serial.print (bitRead (outputs, 2));
    Serial.print ("   count: "); Serial.print (count++);
    Serial.print ("  millis: "); Serial.println (previousMillisTest);
    previousMillisTest = actualTemp;
  }
  digitalWrite (R0, bitRead (outputs, 0));
  digitalWrite (R1, bitRead (outputs, 1));
  digitalWrite (R2, bitRead (outputs, 2));
}

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

void setup() {

  uint8_t MCUSR_save;

  MCUSR_save = MCUSR;
  MCUSR = 0;
  wdt_enable (WDTO_2S);

  Serial.begin (9600);

  if      (MCUSR_save & 0x01)  Serial.println ("*********Restarting . Power-on Reset*********");
  else if (MCUSR_save & 0x02)  Serial.println ("*********Restarting . External Reset*********");
  else if (MCUSR_save & 0x04)  Serial.println ("*********Restarting . Brown-out Reset*********");
  else if (MCUSR_save & 0x08)  Serial.println ("*********Restarting . Watchdog Reset*********");
  else if (MCUSR_save & 0x10)  Serial.println ("*********Restarting . JTAG Reset*********");
  else                         Serial.println ("*********Restarting . Unknown reason*********");
  Serial.print ("MCUSR = 0x"); Serial.println (MCUSR_save, HEX);

  initPins();
  initDevice();

  if (DEBUG) showConfig();

  // prevents flooding the RS485 bus if the device is continuously restarting
  delay (100);

  sendFrame (RESTARTED, 0); // sends the "restarted" event through the RS485 port

}

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

void loop() {
  wdt_reset();
  test();
}

You can choose to either reset the processor or execute an interrupt routine. Example code:
#include <avr/wdt.h>

// watchdog intervals
// sleep bit patterns for WDTCSR
enum
{
  WDT_16_MS  =  0b000000,
  WDT_32_MS  =  0b000001,
  WDT_64_MS  =  0b000010,
  WDT_128_MS =  0b000011,
  WDT_256_MS =  0b000100,
  WDT_512_MS =  0b000101,
  WDT_1_SEC  =  0b000110,
  WDT_2_SEC  =  0b000111,
  WDT_4_SEC  =  0b100000,
  WDT_8_SEC  =  0b100001,
 };  // end of WDT intervals enum

void setup()
  {
  wdt_disable ();
  Serial.begin(115200);
  Serial.println ();
  Serial.println("After reset");
  watchdogSetup(WDT_4_SEC);
  }

volatile bool watchdogFired = false;

ISR(WDT_vect) // Watchdog timer interrupt.
  {
  watchdogFired = true;
  }

void watchdogSetup(byte interval)
  {
  cli(); // disable all interrupts

  // Enter Watchdog Configuration mode:
  WDTCSR = bit (WDCE) | bit (WDE);
  // Set Watchdog settings:
  //  WDTCSR = bit (WDIE) | interval;   // set WDIE, and requested delay - for an INTERRUPT
  WDTCSR = bit (WDE) | interval;    // set WDIE, and requested delay - for a RESET
  wdt_reset(); // reset the WDT timer
  sei();  // enable interrupts again
  }

void loop()
  {

  if (watchdogFired)
    {
    watchdogFired = false;
    Serial.println ("Watchdog fired.");
    }

  // wdt_reset();  // if you want to reset the watchdog

  } // end of loop

This example resets the processor, however if you uncomment the line WDTCSR = bit (WDIE) | interval; and comment the one below WDTCSR = bit (WDE) | interval; then it interrupts instead. You can see that in the example output.
If you want an interrupt then you have to supply an interrupt routine (ISR).

Responding to comments:

But there´s little documentation about how to adequately recover from a reset when the fuse is programmed.

The processor resets, which is what you want, right? You don't need to "recover" from a reset. It's like saying how do you recover from powering it on.

Do I still need to re-enable the watchdog, even if it should be enabled by the fuse?.

I doubt it. In my code the watchdog keeps firing, even after you get the message the first time (the interrupt one).
However you might want to change the interval to the one you want. And you might want to reset the watchdog (wdt_reset ()) if things are going OK.

Also, with the WDTON fuse enabled, the ISR mode is not valid (only the reset mode).

Well, there is not necessarily an ISR for the ISR mode (yet, if ever). The datasheet specifically says that you get the reset mode and not the ISR mode.
It is unclear from the datasheet what the time interval is, with the WDTON fuse programmed.

Thank you for your answer. I try to ensure that the watchdog is ALWAYS running to prevent freezing. In your example, the watchdog is disabled in the setup function. This is the reason why I chose to program the WDTON fuse. But there´s little documentation about how to adequately recover from a reset when the fuse is programmed. Do I still need to re-enable the watchdog, even if it should be enabled by the fuse?. Also, with the WDTON fuse enabled, the ISR mode is not valid (only the reset mode).

See my amended answer which answers your questions.

"The processor resets, which is what you want, right?" -> The point is that the processor DOES NOT reset sometimes. It gets freezed even with the WDTON programmed. 99,9 % of the time it works fine, but still I have some freezing cases. My previous version was very much alike as your code but my guess was:  voltage spike -> uC resets -> setup function executes -> disable watchdog -> program counter jumps elsewhere in the code because of EMI -> program freezed because watchdog is disabled. I know maybe this is too much guessing, but I changed to WDTON and it improved

Now I am thinking that maybe one voltage spike stops the watchdog oscillator and also the uC oscillator. Do you know if this would be possible?. The fact is that only with a external restart the uC comes to live again

A voltage spike might conceivably set the thing into high-voltage programming mode. If you can reach the thing enough to press Reset, can't you wire in a spike protection? Like, a zener diode which redirects high voltages to earth.

I already tried placing a zener diode between Vcc (at the ISP connector) and GND. No luck with that. The spikes are already there (I see them with the scope) and also the reboots. I also tried with snubbers, emi filters, optocoupled relays, etc. The only thing that really worked was an SSR. But still, I would like to avoid installing them. But it seems my only option, as It looks impossible to solve this with only a software change. Thank you for your help, anyhow.


text:
Why analogRead's value decreases when I decrease the value of resistor?(I use digitalWrite(high) to positive terminal of resistor)
Basically, my circuit contains only 1 resistor(like the basic LED circuit).
I tried to know what is the actual voltage of digitalWrite(High). I don't understand why the value of analogRead does not fix to 1023 but instead decreases when I decrease the value of the resistor. Moreover, the value comes to zero when my resistor value comes to 1 ohm. Really appreciate any helps here.

if you open a valve on the left side the pressure on the right side falls.

This blog post of mine will help you understand what is happening: https://majenko.co.uk/blog/our-blog-1/what-exactly-is-a-gpio-pin-10

A digital output pin can only provide a specific current: 20mA max recommended, 40mA absolute max. When you get near and over that these values the voltage will go down, as the internal driver hardware cannot provide enough current to hold the voltage.
With the resistor you are providing a direct current path to ground. For high values of R it doesn't make much different (as the current through the resistor to ground is lower than the max current of the digital pin drivers max current). When you lower R the current through it to ground gets bigger. Thus the digital pin driver has to provide more current to hold the voltage. When it gets too low the driver cannot provide enough current, the voltage will fall.
With R at 1Ohm you are basically shorting the digital output pin to ground as 1Ohm really isn't much resistance. At 5V (which is the output voltage of the Uno) you will get U/R = 5V / 1 Ohm = 5A current through it. The driver cannot provide this. In real life the pin driver would most likely be killed by this current draw.

As a complement to chrisl's answer, it is worth noting that the
datasheet of the microcontroller (here the ATmega328P), under a section
named “Typical characteristics”, has a subsection named “Pin Driver
Strength”. This subsection has some typical voltage-vs-current curves
showing that:

the curves are not quite linear, although the non-linearity is small
at 5 V supply voltage
they depend strongly on temperature
near ambient temperature, the pin behavior is close to an ideal
voltage source in series with a 25 Ω resistor.

The curves go only up to 20 mA, as the behavior for higher currents
is not characterized.
From this, you can guess the voltage reading you expect. For example, if
you use a 470 Ω resistor (which is safe), the output pin resistance
and the external resistor make a voltage divider. The expected voltage
you read is
(5 V) × (470 Ω) / (470 Ω + 25 Ω) = 4.747 V


text:
How to transmit DTMF signal to Arduino
I'm trying to read an incoming DTMF signal through the A0 input pin. I want to do this programmatically and not with the MT8870 module. This library (https://github.com/Adrianotiger/phoneDTMF) is supposed to do just that but I can't figure out how to connect my incoming DTMF signal to Arduino's A0 pin to receive the signal. Basically, my laptop produces the DTMF signal and I want to attach the line out, which is two wires, the positive and ground, to Arduino.  None of the configurations I've tried work.  I've tried to attach the positive to A0 and the ground to ground, but A0 doesn't seem to be detecting anything.  I also don't want to use a microphone on the A0 pin to detect the DTMF. A simple Fritzing type diagram showing how to connect the incoming DTMF signal to A0 would be helpful. Thanks.

Not an expert on DTMF, but have you made sure to get the signal range into the 0 to 5V range of the Arduino? Line Out is symmetrical around ground and I think the peak to peak range might also be wrong. The linked library also has a circuit for adjusting the range, though it is designed for the landline voltage levels

I was thinking of trying to connect an LM386 amplifier to boost the incoming signal, but I still don't know how to configure the two wires to Arduino.

Your problem is that you think there's a "positive" signal. In audio there isn't a "positive" signal, there is just a signal that swings around 0V.
You have to convert said signal to a "positive" signal by adding a DC offset to it.
The simplest way is with one capacitor and two resistors:

simulate this circuit – Schematic created using CircuitLab
That schematic will remove any DC offset that your laptop may add ("AC couple") and then add a 2.5V DC offset of your own to the signal.  The audio signal will then be alternating around 2.5V.
You may need to boost the audio signal's volume with an op-amp (note: do not use a "power" amplifier like the LM386, it is not suitable; use an op-amp) to increase the sensitivity of the input.  You could do this with a simple inverting amplifier arrangement with the DC offset being injected into the non-inverting input:

simulate this circuit
Here the gain of the amplifier is the ratio between R3 and R4 - in this case a 10:22 ratio (or a 2.2x gain).
From a software point of view you now remove 512 from each analog read value to give you a range of +/-511 for your sampled values. You then probably (maybe with the library you link to) take a block of samples at a defined frequency and perform an FFT analysis to find what dominant frequency components are present.

I set up the first schematic, and was able to detect the DTFM tones.  Thanks! The only problem, though, is that the program seems to be detect the wrong tone.  Using the tone generator here, https://onlinetonegenerator.com/dtmf.html, whatever button I push, the program detects the button down one row and to the right one column. Eg. I push 1 and 5 is detected. Or I push 5 and 9 is detected. I will post a question about this because it seems to be a software problem.