text:
Order of Evaluation for #define Macros
EDIT: I think this fits better in the C++ Stack Overflow, so I'm going to re-post this there.
I am working on a menu system with #define macros (inspired by the Marlin firmware on my 3D printer) I am attempting to generalize each menu item with the macro #define MENU_ITEM_EDIT(). The full code is really long, so I am leaving out chunks of code of compactness. However, you can find the full code here: https://pastebin.com/h24itG9y
void draw_row(int row, char* value) { /* Stuff here*/ } // Draws row
char* uiToStr(int x) { /* Stuff here*/ } // Converts unsigned int to a string

#define disp_array(display, value)  display[value]
#define disp_func(display, value)   display(value)
#define disp_char(display, value)   display

#define MENU_ITEM_EDIT(min, max, rate, display, displayType, width, label, value) \
    // A bunch of stuff
    draw_row(rowNum, disp_ ## displayType(display, value)); \
    // More stuff

Using the code macro would look like:
// Values
const char item1[] = "Item 1", item2[] = "Item 2", item3[] = "Item 3";
const char* const itemList[] = {item1, item2, item3};
int currentItem = 0;
uint8_t item1Val = 10;

void menu1()
{
   START_MENU();
       MENU_ITEM_EDIT(0, 3, 1, itemList, array, 6, "Item:", currentItem);
       MENU_ITEM_EDIT(0, 255, 1, uiToStr, func, 3, "Item 1 Value:", item1Val);
   END_MENU();
}

Which displays as:
Item:     Item 1
Item 1 Value: 10

For convenience in the declarations of my menus, I am trying to use common menu types, such as an uint8_t that ranges from 0 to 255. Then, in the menu, I would use __u255_t instead of the first 6 arguments.
#define __u255_t 0, 255, 1, uiToStr, func, 3

void menu2()
{
    int item2Val = 10;

    START_MENU();
        MENU_ITEM_EDIT(__u255_t, "Item 2 Value", item2Val);
    END_MENU();
}

Previously, I had it set up such that every time I wanted a different type of menu, even if I would only use it once, I had to define a type for it and how it should evaluate in the macro. This way, I can use 1 argument instead of 6 for commonly recurring types in rows. However, I still want the ability to use the 6 argument option when I have a row that has a unique set of arguments, such as a different range or list of display strings.
However, in this example, the program won't compile because it places __u255_t into min in the MENU_ITEM_EDIT() macro, rather than expanding __u255_t into its 6 values and placing them into the first 6 arguments of MENU_ITEM_EDIT(). The macro evaluates as:
MENU_ITEM_EDIT(__u255_t, "Item 2 Value", item2Val);
// Evaluates as:
MENU_ITEM_EDIT( (0, 255, 1, uiToStr, func, 3), "Item 2 Value", item2val, , , , , );

Note: I put an extra set of parentheses to make it more clear to understand.
But I want:
MENU_ITEM_EDIT(__u255_t, "Item 2 Value", item2Val);
// Evaluates as:
MENU_ITEM_EDIT(0, 255, 1, uiToStr, func, 3, "Item 2 Value", item2Val);

I thought about using a struct, however I'm not sure that I can because depending on the row, the value string in draw_row() could be a function or an array. Does anyone have any advice on how to solve this problem?
Also, please let me know if I need to add any more code to make my problem more clear.

I agree - this is a language question, not an Arduino one - but the short answer is that macros are not part of the language (C or C++); they are a preprocessor feature (standard on C and C++ compilers, to be sure) that is evaluated at compile time, so they must be completely evaluable at that time. Therefore, being evaluated before the compiler ever sees your code, they also don't have the overloading capability, including variable-length parameter lists, that C++ provides.

including variable-length parameter lists -- actually they do: __VA_ARGS__ and #define foo(...)

C/C++ precompiler macros are a hot mess. (Especially macros that take parameters, like the ones you're using.) They're not type-safe, and they get resolved at compile-time in ways that are quite confusing. There are other ways of solving this sort of problem

You need to turn your macro itself into a macro. Sounds odd, I know.  But take the following example:
#define foo bar, baz
#define foobar(X, Y, Z) something(X, Y, Z);
#define boofar(...) foobar(__VA_ARGS__)

boofar(foo, 4)

boofar is a macro that takes a variable argument list.  That expands out into a call for your actual macro call, expanding foo in the process.  Then your actual macro gets expanded out with the real arguments already in here. The point here is that foo is expanded before being passed to the macro that needs the multiple arguments that are inside foo.
So the expansion chain is actually:
boofar(foo, 4) ->
foobar(bar, baz, 4) ->
something(bar, baz, 4);

Running it through cpp and you get:
# 1 "t.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "t.c"

something(bar, baz, 4);

Gak. Props for explaining how to make it work, but gak just the same.

Yeah, it is confusing, but your explanation makes sense. Thanks!


text:
Arduino HID keyboard does not work
I'm using a ItsyBitsy 32u4, Adafruit says it can act as a USB HID keyboard. The mc is based on the 32u4 which the Keyboard docs say are supported.
I have a simple sketch that prints "A" every second and should press "A". When I upload the sketch and connect to the serial port I see the print output but I don't get any key presses.
Any ideas? I'm on linux, I suspect that the controller doesn't register as a HID device, maybe I need UDEV rules or drivers?
EDIT: the keyboard works on a different computer.
#include <Keyboard.h>
void setup() {
  Serial.begin(9600);
  Keyboard.begin();
  Serial.println("Start");
}

void loop() {
  Serial.println("a");
  Keyboard.write('a');
  delay(1000);
}

you shoukd read the reference and study the examples

@Juraj I have, what do you think I missed?

it seemed you missed what is in the Answer. do you have a text editor open in foreground?

Yeah, I have a window focused that accepts and displays keyboard input. Typing on my actual keyboard displays the keys.

next I would try removing Serial from the sketch

removing serial didn't make a difference.

check the Device Manager if it has the HID device

There was some issue with my laptop, not controller or the sketch.
I tried the my board with another computer and it worked. I tried a commercial keyboard on my first computer it also didn't work.
Both keyboards work after a reboot.

Keyboard.press() expects a character, but you are passing a character array. Also Keyboard.press() only presses but does not release the key. Keyboard.releaseAll() can be used to release all keys.
I would try:
Keyboard.press('A') ;  //note the ' instead of "
Keyboard.releaseAll();

or preferably:
Keyboard.write('A');   //handles press and release of basic keys

I made an error when I created my simple repo sketch, but I have tried Keyboard.press('A') and Keyboard.write('A'). Neither work.

I also tried Keyboard.write('a') after reading keyboard.cpp and realizing that writing 'A' sends keypesses for a and the shift modifier.

source: Stack Exchange

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

sort: votes


text:
Sparkfun Pro-Micro stuck on uploading
I have read multiple posts on how to reset the sparkfun pro-micro when it gets stuck during upload, and this seems to work to get it back to a state where I can upload new code again - However, I am here to ask if it is possible that it is something in my code that is causing this issue?
The reason I suspect it is my code is because I have tried:

Different pro micro
Different USB cable
Downloaded latest IDE
Downloaded latest AVR boards package
Tried reverting back to an older AVR boards package as suggested in a different post

Not sure if this is a coincidence, but when I upload a simple blink sketch I don't have any trouble, but as soon as I upload my code (below), it gets stuck on uploading...
I can get it to eventually upload after many attempts using the reset during upload trick, but it seems to be unstable. I say unstable because sometimes it will print out the values requested, and other times it will print nothing...
int clampVal = 0;

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

void ClampReading()
{
    const int numRead = 400; //amount of calibration values we will average
    double vals[numRead];      // the readings from the analog input
    int readIndex2 = 0;                 // the index of the current reading
    double total2 = 0;                  // the running total
    int calibration2 = 0;               // calibration incrementer

    for (int thisReading2 = 0; thisReading2 < numRead; thisReading2++) {
    vals[thisReading2] = 0;
    }
    while(calibration2<numRead)
    {
      int rawClamp = analogRead(A0);
      total2 = total2 - vals[readIndex2];
      vals[readIndex2] = rawClamp;
      total2 = total2 + vals[readIndex2];
      readIndex2 = readIndex2 + 1;
      if (readIndex2 >= numRead) {
        readIndex2 = 0;
     }
      clampVal = total2 / numRead;
      calibration2++;
    }

}

void loop() {
 ClampReading();
 Serial.println(clampVal);
}

EDIT:
Once I reset and upload an EMPTY sketch, I can upload the empty sketch with no problems. I did it 5 times in a row with no issues. Then tried to upload the code above once, and it worked..but then tried to upload second time, and stuck in uploading again... it has to be the code, but I can't narrow down what it is.

Uno's Mega's and so on have a separate MCU (u3) that contains the boot loader and is responsible for the USB connection and for driving the virtual serial port. Micros ( and also Leonardos and Esploras ) have built in USB support in the main MCU (u4). So if your program does something that breaks the USB part of the MCU the communication breaks also. This  happens for instance if you disable the interrupts.
The only thing you use in your program that might cause a problem is the Serial connection. The blink example has no serial output.
If you add a Serial.begin(115200) and a Serial.println("Hello") to the blink example, I guess the problem occurs also.
The IDE establishes the programming connection by connection to the selected com port at 1200 Baud. The boot loader recognizes that, performs an auto reset and opens a second (programming port) from then the IDE has access to this port and uses it to communicate with the boot loader. On a UNO this is handled by the separate MCU and on the Micro the main CPU is responsible for that.
Perhaps it helps if you add a time delay, before the Serial.begin(). Then you will have more time to start the programmer.
There is also a trick to enlarge the time you can start the programming after a reset to 8 seconds. https://forum.arduino.cc/index.php?topic=224416.msg1643210#msg1643210
And one additional hint:
Your code is unnecessarily complicated. If you want, you can try the program below. I think it does the same as yours. I have no compiler and no micro at the moment so it's complete untested.
You used a calibration variable. I guessed that it is for skip the first calibration values. If you need the values you can store them in a separate array.
My prog. has a lower memory footprint because I store the integer values from the analog input into an integer array. You used a double array.
You also did a lot of unnecessary computations after you read an analog value. This can slow down the readings. Perhaps therefore you missed some values you expected to see.
//amount of calibration values we will average
const int valueCount = 400;
const int calibCount =   0;

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

void loop()
{
  // the readings from the analog input
  int vals[ valueCount ];

  for (int idx = 0; idx < valueCount + calibCount; idx++)
  {
    int rawValue = analogRead( A0 );
    if ( idx >= calibCount )
    {
      vals[ idx - calibCount ] = rawValue;
    }
  }

  double total = (double) 0.0;

  for (int idx = 0; idx < valueCount; idx++)
  {
    total += (double) vals[ idx ];
  }

  Serial.println( total / valueCount );
}

Thanks @peter Paul Kiefer for the very thorough explanation! When I get back in front of my micro later I will try your suggestions and code, fingers crossed it works!

That seems to have done the trick. I put in a delay of 500ms between serial prints and now it uploads repeatably. Thanks for the help!

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


text:
Why sometimes parsed data is null in WiFiEsp?
I'm setting up web server with args. As host.com/?pin=9. I parsed the response by indexOf and substring functions. In first connection response has been successfully
parsed and  number has been parsed too. But in second connection it is null. Why I don't know.
And sometimes it writes TIMEOUT: 25/625 and m.
code:
/*
 WiFiEsp example: WebServer

 A simple web server that shows the value of the analog input
 pins via a web page using an ESP8266 module.
 This sketch will print the IP address of your ESP8266 module (once connected)
 to the Serial monitor. From there, you can open that address in a web browser
 to display the web page.
 The web page will be automatically refreshed each 20 seconds.

 For more details see: http://yaab-arduino.blogspot.com/p/wifiesp.html
*/

#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif
String response = "";
char ssid[] = Twix";            // your network SSID (name)
char pass[] = "123456789";         // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status
int reqCount = 0;                // number of requests received

WiFiEspServer server(5000);

void setup()
{
  // initialize serial for debugging
  Serial.begin(115200);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
  printWifiStatus();

  // start the web server on port 80
  server.begin();
}

void loop()
{
  // listen for incoming clients
  WiFiEspClient client = server.available();
  if (client) {
    Serial.println("New client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {

        char c = client.read();

        Serial.write(c);
        response += c;

        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          Serial.println("Sending response");
                  int f= response.indexOf("turnon")+11;
        int s = f+2;
        String sh = response.substring(f,s);
        int pin = sh.toInt();
      if(pin !=0){
       pinMode(sh.toInt(),OUTPUT);
      digitalWrite(sh.toInt(),HIGH);
      }
          // send a standard http response header
          // use \r\n instead of many println statements to speedup data send
          client.print(
            "HTTP/1.1 200 OK\r\n"
            "Content-Type: text/html\r\n"
            "Connection: close\r\n"  // the connection will be closed after completion of the response
                  // refresh the page automatically every 20 sec
            "\r\n");

          client.print("<!DOCTYPE HTML>\r\n");
          client.print("\r\n");
          client.print("
Hello World!
\r\n");
          client.print("Requests received: ");
          client.print(++reqCount);
          client.print("
\r\n");
          client.print("Analog input A0: ");
          client.print(analogRead(0));
          client.print("
\r\n");
          client.print("
\r\n");
          client.print("pin is: ");
          client.print(sh);
          client.print("
\r\n");
          client.print("\r\n");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(10);

    // close the connection:
    client.stop();
    Serial.println("Client disconnected");
  }
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in the browser
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}

you call the variable for storing the request response?

Yeah. I'm crazy

I have got only 2.0.0 and 3.0.0 SDK Version.

I can use it with 2.0.0 SDK?

AT firmware? OR SDK?

OK..............

It ssays Communication wih module failed

Let us continue this discussion in chat.

if hit from a browser, favicon.ico will also be requested, without any query params.

Yes it requested.

But I created Telnet server it says me TIMEOUT too.


text:
SD card creating "extra" file?
So, maybe I'm too tired to see the obvious issue here, but my SD card script is causing a "blank" file to be created, then a secondary file to be correctly created.
I'm trying to store data logs, and I don't want to overwrite old logs, I just want to "move" them to the back of the queue.  So I start with six files on the SD card:

DATA.TXT
  DATA~1.TXT
  DATA~2.TXT
  DATA~3.TXT
  DATA~4.TXT
  DATA~5.TXT

Everything writes to DATA.TXT, and DATA~1.TXT through DATA~5.TXT are "old" logs, from oldest to newest.  This means that, the next time I boot up the Arduino, I want the contents of DATA.TXT to be read into a new file called DATA~6.TXT, I want the old DATA.TXT to be deleted, and I want a new DATA.TXT to be created for the rest of the program.  It should look like this:

DATA.TXT     <=== New, blank file, primed for logging new data
  DATA~1.TXT
  DATA~2.TXT
  DATA~3.TXT
  DATA~4.TXT
  DATA~5.TXT
  DATA~6.TXT   <=== "Old" DATA.TXT

In reality, it's creating two files: instead of DATA~6.TXT holding the contents it should, it's blank -- and a file called DATA~7.TXT is created with the contents of the "old" DATA.TXT.  After that, it's writing to the "new" DATA.TXT as it should.  Something is lost (or added) in shifting the data, for some reason, looking like this:

DATA.TXT     <=== New, blank file, primed for logging new data
  DATA~1.TXT
  DATA~2.TXT
  DATA~3.TXT
  DATA~4.TXT
  DATA~5.TXT
  DATA~6.TXT   <=== Blank, unused "new" file?
  DATA~7.TXT   <=== "Old" DATA.TXT

EDIT: Each file contains test data ( e.g. - file DATA~1.TXT contains a line like This is "DATA~1.TXT") So I can track which files are "moved," and where they go. That's how I know where the "old" DATA.TXT file is going, and how I know DATA~6.TXT is "blank." It's actually a blank file, with no data in it.
EDIT #2: As stated in the comments below, the Uno doesn't actually wait for a serial connection.  I just tested this, and it is true... that being said: I'm still getting a blank DATA~6.TXT and DATA.TXT is being moved into DATA~7.TXT without cause.
Now that you know the goal, and (probably) see the issue, here's the code:
/*
 * Tests the SD card slot, assuring no functional code is missing
 * for BIB process to correctly log data.
 *
 */

#include <SPI.h>
#include <SD.h>

String fileName = "DATA.TXT";                       // Declare a filename with FAT 8.3 naming conventions
File dataLog;                                       // Store our "opened" file in an object

void setup(){
    Serial.begin( 115200 );
    while( !Serial ){                               // Wait for serial port to open before doing anything
    }

    Serial.println( "\nInitializing SD card..." );  // Start SD card
    if( !SD.begin( 4 ) ){
        Serial.println( "Initialization failed!" );
        while( 1 );
    }
    Serial.println( "Initialization done." );

    Serial.println( "\nChecking if we have a unique filename..." );
    if( SD.exists( fileName ) )                     // Give our data log a unique filename if the current filename already exists
        moveFiles();

    dataLog = SD.open( fileName, FILE_WRITE );      // Open our file for editing if it doesn't already exist
    Serial.println( "Created save file!" );

    // Write to file the first time
    if( dataLog ){
        Serial.println( "\nWriting int test to file..." );
        dataLog.println( "Testing Sequence1..." );
        dataLog.println( "\tSequence1 complete." );
        Serial.println( "\tFirst test written!" );
        dataLog.close();
        Serial.println( "\tData log closed." );
    }
    else
        Serial.println( "---Error opening data log file!---" );
}

void loop(){
}

// Moves the last `DATA.TXT` to `DATA~x.TXT` where `x` is the largest integer.
// This makes the "highest" numbered file the last data log, and `DATA.TXT` the current data log.
// Follows SFN8.3 standards of naming, with 8 chars for filename, 4 chars for extension, and preceeding
// periods converted to `~` chars.
// This leaves us with only 999 possible "backup" data logs.
void moveFiles(){
    bool sdCardFull = false;                            // Keep track of if our SD card is "full" or not
    byte num = 1;
    File newFile;

    String existingFile = String( "DATA~" ) + String( num ) + String( ".TXT" );     // Creates a filename of `DATA~num.TXT` to test

    // Check if this filename exists, too.  Iterate `num` to avoid overwriting currently existing files
    while( SD.exists( existingFile ) ){
        if( num == 999 ){          // If the SD card is full
            sdCardFull = true;
            noMoreRoom( sdCardFull );
        }

        num++;
        existingFile = String( "DATA~" ) + String( num ) + String( ".TXT" );
    }

    dataLog = SD.open( fileName );
    // Create the new file, with the new filename
    newFile = SD.open( existingFile, FILE_WRITE );

    // Move the old data log into the new filename
    while( dataLog.available() )
        newFile.write( dataLog.read() );

    // Close, remove, then re-open the data log
    newFile.close();
    dataLog.close();
    SD.remove( fileName );                          // Deletes the old data log
}

// We cannot find a good filename for the SFN8.3 format, since all of the available filenames have been
// used up, so we will stop the program from running until the SD card is cleaned up, before we "destroy"
// the last backup file.
void noMoreRoom( bool sdCardFull ){
    /*
    lcd.setCursor( 0, 0 );
    lcd.print( "   SD card is   " );
    lcd.setCursor( 0, 1 );
    lcd.print( "   too full!!   " );
    */

    Serial.println( "The SD card is full and we will not proceed until it is cleaned up." );

    while( sdCardFull ){}       // Do absolutely nothing until the SD card is "cleaned up"
}

Let me guess... you plug the board in (or program the board), then you open the serial terminal, and the program "starts running"...?  What about the period between plugging it in (or programming it) and you opening the serial terminal? It runs then too you know... (assuming an Uno - but you don't specify which board you are using...)

Yes, it's an Uno... and a Nano... and a Pro-Mini.  And the sketch should be caught in the while( !Serial ) loop until the Serial Monitor is attached, right?

No, that line is only for native USB boards as I remember. It will not wait for anything on an Uno or Nano

Maybe you should first test for the file to actually contain data, before you move it.

while (!Serial) works only for MCU with native USB (32u4, SAMD), not for Uno, Nano, Mega, Mini. Uno & co. reset on new connection. they start to run and then they are reset on new connection

All files contain data with their respective filenames ( e.g. - File "DATA~1.TXT" ).  They're being moved correctly.  That's how I know that DATA~6.TXT is blank.

Even if the MCU runs without delay, DATA.TXT should still be going to DATA~6.TXT, a new DATA.TXT should be created with the "test data" per the code, then the Serial Monitor should reset things, moving the "test data" file to DATA~7.TXT and duplicate "test data" to DATA.TXT, right? But this isn't happening... I still can't explain what's happening.

Do you also see that behavior with a complete new setup? (Meaning all files deleted, letting the code start from the known startpoint) Maybe the Arduino was once interrupted by a reset, before he could write the actual data to the file

On a fresh setup (formatted SD card with no files on it), I get two files: DATA.TXT and DATA~1.TXT, with both having the "test sequence data" written to both.  Other than filename, they're identical, according to cmp and md5sum.  I'm still not 100% sure why it's creating two files... usually one is blank, but they're identical in this instance.

You can do multiple resets, by pressing the reset button or reopening the serial monitor, to check, if it works under the correct circumstances. A reset during writing to the SD card can lead to corrupt data. Maybe it is suitable to disable the reset from serial by adding a capacitor between Reset and ground. That prevents the serial interface to reset the microcontroller. Though it also prevents programming, so you would have to remove the capacitor again for programming

try to use - instead of ~

@Juraj I was following the SFN8.3 format, which is recommended by Arduino.  It should work with the ~, but it should also work with the - as well.  Trying both, neither are producing the desired outcome.


text:
Delay stops execution forever sometimes
I have an arduino to control an irrigation system, consisting on one pump (called "bomba" on the code) and 5 12V water valves.
Each valve controls one irrigation circuit and the idea is to open each one sequentially during one minute and then move on to the next one.
The code is this:
const int TIEMPO_RIEGO = 64; // seconds

const int TRIGGER = 5;

const int BOMBA = 6;
const int CIRCUITO_1 = 8;
const int CIRCUITO_2 = 9;
const int CIRCUITO_3 = 10;
const int CIRCUITO_4 = 11;
const int CIRCUITO_5 = 12;

const int CIRCUITOS_ACTIVOS[] = {
  CIRCUITO_1,
  CIRCUITO_2,
  CIRCUITO_3,
  CIRCUITO_4,
  CIRCUITO_5,
};

void _abrirValvula(int circuito, int t) {
    digitalWrite(circuito, HIGH);
    digitalWrite(BOMBA, HIGH);
    unsigned long waitTime = t * 1000L;
    delay(waitTime);
    digitalWrite(BOMBA, LOW);
    digitalWrite(circuito, LOW);
}

void cicloRiegoCompleto() {
  int numeroDeCircuitos = sizeof(CIRCUITOS_ACTIVOS) / sizeof(CIRCUITOS_ACTIVOS[0]);
  for (int i=0; i<numeroDeCircuitos; i++){
    _abrirValvula(CIRCUITOS_ACTIVOS[i], TIEMPO_RIEGO);
  }
}

void setup() {
  pinMode(BOMBA, OUTPUT);
  pinMode(CIRCUITO_1, OUTPUT);
  pinMode(CIRCUITO_2, OUTPUT);
  pinMode(CIRCUITO_3, OUTPUT);
  pinMode(CIRCUITO_4, OUTPUT);
  pinMode(CIRCUITO_5, OUTPUT);
  pinMode(TRIGGER, INPUT);
}

void loop() {
  if (digitalRead(TRIGGER) == HIGH) {
   cicloRiegoCompleto();
  }
}

On the pin 5 (TRIGGER) I have a raspberry pi connected that is connected to the internet also, so, when I send it a message from mi phone, it puts 3.3V on that pin and starts the process.
It has been working great for like a month or so but, a few days ago, the pump didn't stop when it should, and was still working hours after it started.
I pull the plug and, when I turn it on again, it worked correctly again for another 2 or 3 days.
But today it hasn't stop again. I have check that the pump has been working for around 15 minutes until I pulled the plug, and the first valve (CIRCUITO_1) has been opened the whole time, looks like the for loop is stuck in the first iteration.
So can it be some problem with the delay function?
For some reason it is waiting way more than it should?
It works sometimes and sometimes it doesn't so it makes me think: can it be some weird overflow issue?

The code seems legit to me. Can you log on the pi, when exactly it turns it's output on and off? Just to see, if that works correctly.

When you have this problem, what is the state of the logic output of the Pi?

The pi turns its output HIGH during only one second, and then it is LOW again. But, even if it were HIGH the whole time, it should loop through each valve instead of being stuck in the first one forever.

How are you interfacing the pumps to the Arduino? Can you post a circuit diagram?
Also, how are you powering the pumps? Are they powered separately from the Arduino, or is the Arduino sourcing its power from the same circuit that the pumps are?

The valves are controlled via mosfets IRL510 (or IRL540? don't remember right now), the pump with a 5V arduino relay. Everything is powered from a 15A 12V power supply, using a step-down for the raspberry and the relay power. I'll try to upload a diagram this evening.

Is it a cheap $1 Chinese nano or a genuine Arduino nano?

Bought it on amazon.es in a pack of 6 for around 15€, so it is probably the Chinese version. I'm not sure how to spot the differences, here is a photo: https://imgur.com/03C2WyB

Cheap Chinese crap. Do you know how they get them so cheap? Simple: the MCUs come out of the reject bin. Instead of the factory in China throwing them out they sell them cheap on the local market. So you can expect them to be substandard and fail randomly...

Based on your experience with the system and the source of the Nanos, the best and quickest test I can think of is to swap in a another Nano to find out whether if the problem remains or disappears.

Do you have 10k resistors between gate and ground on your MOSFETs? You might be suffering from residual charge on your MOSFET gate keeping it on when it should be off.

Yep, and also flyback diodes on each valve.

You may have a problem in the casting of the variable t vs the variable waittime.  t is an int and waittime is a long so when you multiply t by 1000L you may be picking up a couple of extra bytes used by other parts of the code:
For instance if t is stored at location 0x100:0x101 in RAM, and some other variable or random data is stored at 0x102:0x103, you pass 100 to the function in variable t which you expect multiplies into waittime as 100,000mS or 100S, but if the data stored at 0x102:0x103 for instance is randomly 0xFFFF, the multiplication into waittime actually works out to (100*65536)+65535 = 6,619,135mS or 1.83 hours.
The way around this is to either pass a long in the function or recast t to match waittime:
waittime = (long) t * 1000L;
Note that the order of the bytes depends on how the compiler handles variable storage.

Compilers don't overwrite memory just because you cast something. That would be pretty bad behaviour if they did. Maybe if you cast a pointer into a different sort of pointer, but this is just an ordinary variable.

The cast and multiply are almost certainly done in registers, and the variable waitTime is unlikely to ever have any discrete existence, as the product of the multiply will be left in registers or immediately pushed onto the stack as the argument to delay(), and is never referred to again.

It has been working great for like a month or so ... it makes me think: can it be some weird overflow issue?

It's hardly a software issue then. Nothing in your code would change after a month of operating. And if you turn the power off and on again then it would "forget" about the previous month.

So can it be some problem with the delay function?

No.

I suggest looking at the hardware, or the code on the Pi.

That makes sense. The pi code looks fine but, should I just check the mosfet circuit part or the arduino itself too? What I mean: Is it possible for an arduino to break in some way that it gets stuck randomly on a line of code? Or if the arduino was broken it wouldn't work at all?

I doubt it would get "stuck" on a line of code. The processor runs or it doesn't. I would use a meter to test that the output is being set in the way you expect.


text:
How to detect V-SYNC on the SparkFun MicroView?
Is there a way to detect the start of the OLED screen refresh cycle (V-SYNC) on the SparkFun MicroView? There is no code for this functionality in the Arduino library; in fact it looks like the Arduino library is only set up to send data over SPI to the display, and not receive any data/status back.
Do you know how to access the internal state of the OLED screen directly, by polling some kind of status bit over SPI?
The only datasheet I can find of this OLED screen does not have SPI command details.
Update: here's a movie taken with an iPhone on "slo-mo" video, showing a full screen (all pixels on). There is clearly a screen refresh going on, which interlaces with the video frame rate.

What do you need that for? I'm not even sure "screen refresh" is a term that applies to OLED displays.

@Gerben when I photograph the screen with a fast shutter speed, it is clear that there is a periodic refresh going on. I'd like to synchronize some things with that.

The scenario you describe is called the Tear Effect. On the SSD1306, which the device you are interested in is based around, a Frame Synchronisation pulse can be emitted on the FR pin.
However it would appear that the specific SSD in use by SparkFun does not provide this pin from the SSD1306 on the external FPC connector, so there is no way of getting it.  Probably owing to the small size of the display a reduced size connector without extra pins like FR was used.
So no, you can't combat the Tear Effect with that display.
There is nothing you can do over SPI, either. That is simply because SPI is just too slow for such things. You would use the FR pin because it's instantaneous.  With SPI you would have to make a request to read a register, then read that register's value back. In that time, coupled with the question of exactly when would the register say it was at the start of a frame, the information would be completely meaningless anyway.

Thanks @Majenko, I learned a lot today. For completeness here's the SSD1306 datasheet. It turns out that this controller is write-only over SPI, so no status queries possible anyway. There is a section in the datasheet about FR synchronization (section 8.4) so maybe for the next bigger project this will be a possibility. Cheers!


text:
send data from serial to client
I am using Arduino Yun to send data from serial to client, and it's partially working because I only get short data delivered, while long data (like more than 100Byte) get the most of them lost.
on the other hand when I use the softwareSerial example in the IDE to send from serial to serial it works with no data lost. I am trying to do like the example as possible with the serial to client code using client.write(mySerial.read()) but not working as expected!
what am I missing? I guess client.write doesn't hold long data or is too slow to transmit. How can I solve this or even another way to achieve my point?
I am sending the data (as a file content on one time, not in sequence- it's a must) from pc using terminal Programm sscom32e. I am receiving the data as client using netcat on the same pc (Yun and PC connected with RS232-USB and are on the same network).
#include <SoftwareSerial.h>
#include <Bridge.h>
#include <BridgeClient.h>

#define PORT 9000
// Make the client connect to the desired server and port
IPAddress addr(192, 168, 0, 100);

//not all pins on the yun are assignable as rx/tx
SoftwareSerial mySerial(10, 11); // RX, TX

// Define our client object
BridgeClient client;

int led = 4;
bool Connected;
void setup() {
 pinMode(led, OUTPUT);

 // set the data rate for the SoftwareSerial port
 mySerial.begin(9600);
 mySerial.println("Hello, world?");
 mySerial.setTimeout(20000);

 // Start Bridge
 Bridge.begin();
 //delay(1000);

 // Start Console communications and wait for port to open:
 //Console.begin();
 //delay(1000);

 //Console.println("Client connecting on port 9000");
 Connected = false;

 //delay(1000);
 //connectToClient();
 connectToClient();
}

void loop() // run over and over
{
 while (mySerial.available()) {

 client.write(mySerial.read());

 //mySerial.read();
 }

}

void connectToClient() {

 // is a connection currently active?
 if (!Connected)
 {
 // not currently connected, try to establish a connection
 client.connect(addr, PORT);
 delay(1000);

 if (client.connected())
 {
 // send something to the client
 client.println("hello server!");
 digitalWrite(led, HIGH);
 }
 else
 {
 connectToClient();
 digitalWrite(led, LOW);

 }
 }
}

Why not use hardware serial?

what do you mean by hardware serial?

The Serial class of the arduino environment (commonly used to print to serial monitor) makes use of the chips hardware serial. In this case the communication is entirely handled by the hardware, software serial kind of emulates a serial in software which is more prone to errors. As you seem to be barely able to reproduce the problem in a consistent way, this could be worth a try

because I am using an RS232-Shield to receive data

Maybe try to first buffer a full message and then sending it as complete message in one request. Currently you are sending many 1 byte requests. Can it be, that the netcat client can not receive that many requests for whatever reason

no it's not a netcat -or in general- a connection problem(cause II tried to send big data from SD and it had no problem- but this solution wasn't also good because writing to the SD from Serial had the same problem). I tried buffering it in a string, using
String content
character = myserial.read();
content.concat(character);
``` but this didn't work either to send from serial to client, although worked for serial to serial.
I tried to buffer it in char array, but char arrays are just like 250Bytes long!

I believe now that serial.read and client.write cann't work together at the same time efficiently. when client.write starts, serial.read stops and therefore data get lost. Now I am saving the serial.read in 3 arrays of each 255Byte, when they are full or I receive an end-marker I call client.write to send them and Serial stops anyway. This works but for max. 765 Byte data. I can't do more arrays to save the serial data due to the limited memory of the module, which means it's not the best solution right now. I will post the code for this later when I optimate it. the other Idea coming to my mind is to send orders to the serial to wait until client.write finishes and then continue receiving and so on. Is this possible? Is Serial that flexible? How could I communicate with Serial to wait and to continue?


text:
How to speed up
I found that using more float variable in arduino uno(atmega328p) slows it down (very muck that i can get slow response)
so, how to speed up it processing ?
my data are euler's angle with 2 digits and 2 decimals like give below
XX.XX , where X is number Eg.(85.63,34.65,etc) (from MPU6050)
How to process it fast?

Add the code for the slow procedure (or add your whole program) into the question.  Details make differences.  To tell markdown that a section is code, highlight it and press ctrl-K

i just found by multiplying raw value by 100 (85.63 * 100 = 8563),it is still integer so it will be fast in arduino uno. And divide it by 100 to get processed value

A technique commonly used in digital signal processing is using fixed-point arithmetic instead of floating point.  In fixed-point arithmetic, one calculates using numbers multiplied by some power of two or ten, and in effect mentally positions a binary or decimal point several bits or digits up while calculating. Numerical analysis may be needed to determine if the arithmetic is accurate enough and whether numbers will stay in bounds, or overflow.
The question doesn't say what's being calculated; it's possible fixed-point arithmetic might work, or might not.  A short self-contained fixed-point calculation that starts with MPU6050 sensor readings is likely to be ok, but long-term calculations (eg, integration of accelerations to get velocities and positions) that let error accumulate without reset may go too far astray.  In such a case, numerical analysis can indicate what intermediate results need to be stored most accurately.
Typically, when slow code is posted someone can point out speedups, from a few percent up to dozens of times faster.  Changes may range from adding or removing parentheses or temporary variables, to refactoring, to substitution of a new algorithm.

yeah i am now modifying code .

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


text:
USB to TTL with switchable 5v and 3.3v in one
are there any USB to TTL with switchable 5v and 3.3v
i need to use it for raspberry pi and arduino

Many 3.3V FTDI based devices are 5V tolerant and will work with both:

Adafruit's FTDI friend
Sparkfun FT231X Breakout

Here is general information about logic levels: https://learn.sparkfun.com/tutorials/logic-levels

so the HIGH for arduino is 3v to 5v and LOW is 0v to 1.5v , can i used USB to 3.3v TTL for both arduino and RPI

Yes, in general 3.3V logic output is compatible with 5V input.  Some, but not all 3.3V devices are tolerant of 5V input. Check the datasheets to be sure. Always be careful when combining 3.3V logic and  5V logic it is possible to damage components.

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


text:
Flickering LCD when using > 5v power supply on a Pro Mini
I have a Pro Mini wired up to an LCD via an I2C board. At http://www.arduino.cc/en/Main/ArduinoBoardProMini it says the pro mini can accept up to 12v on the RAW pin as it has a voltage regulator on board. When I plug a 12v power supply into the raw pin, the LCD works fine initially, then slowly degrades into flickering more and more. It also does this with a 9v power supply. At 5v it works perfectly. Any ideas what's going on?

If the LCD has a backlight you are absolutely over heating the regulator on that board by running it at 9 or 12V: At 12V with 100mA for the backlight and using 175C/W thermal resistance for the regulator:
Tj = 25C + ((12V - 5V) x 100mA x 175C/W) = 147C
That regulator goes into thermal limit at 125C.


text:
Send Arduino data to PHP inorder to upload in MySQL database
I'm trying to send arduino data to my online web server using a Arduino Uno and a Ethernet shield. I used POST method for sending data and tried sending data to my sever (add.php) using a online POST request generating  site (https://www.codepunker.com/tools/http-requests) . That works perfect and it updated my database with sent data. But my database doesn't get any data when I try to send data with Arduino and Ethernet shield. Any suggestions to make this work? What changes should I do to my arduino code?
Database

Serial Out
Initialize Ethernet with DHCP:
DHCP assigned IP 192.168.1.102
connected to 145.14.145.94
still working here
temp1=10&hum1=24
Successfull
Client Stopped

Arduino Code
  #include <SPI.h>
  #include <Ethernet.h>

  byte mac[] = { 0x00, 0xAB, 0xBA, 0xBC, 0xDD, 0x02 };
  EthernetClient client;
  String data;
  int t;
  int h;
  IPAddress ip(192, 168, 1, 177);
  IPAddress myDns(192, 168, 1, 1);
  char server[] = "lattalottaroom2.000webhostapp.com";

  void setup() {
    Serial.begin(9600);
    Serial.println("Initialize Ethernet with DHCP:");
    if (Ethernet.begin(mac) == 0) {
      Serial.println("Failed to configure Ethernet using DHCP");
      // Check for Ethernet hardware present
      if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
        while (true) {
          delay(1); // do nothing, no point running without Ethernet hardware
        }
      }
      if (Ethernet.linkStatus() == LinkOFF) {
        Serial.println("Ethernet cable is not connected.");
      }
      // try to congifure using IP address instead of DHCP:
      Ethernet.begin(mac, ip, myDns);
    } else {
      Serial.print("  DHCP assigned IP ");
      Serial.println(Ethernet.localIP());
    }

    // if you get a connection, report back via serial:
    if (client.connect(server, 80)) {
      Serial.print("connected to ");
      Serial.println(client.remoteIP());
    } else {
      // if you didn't get a connection to the server:
      Serial.println("connection failed");
    }

    Serial.println("still working here");

  }

  void loop() {
  t = 10;
  h = 24;

  data = "temp1=";

  data.concat(t);

  data.concat("&hum1=");

  data.concat(h);

    if (client.connect("lattalottaroom2.000webhostapp.com",80)) {
      Serial.println(data);
      client.print("POST /add.php HTTP/1.1");
      client.print("Host: lattalottaroom2.000webhostapp.com");
      client.print("Connection: close");
      client.print("Content-Type: application/x-www-form-urlencoded");
      client.print("Content-Length: ");
      client.println(data.length());
      client.println();
      client.print(data);
      Serial.println("Successfull");

    }

    if (client.connected()) {
      client.stop();
      Serial.println("Client Stopped");

    }

    delay(20000);
  }

connect.php
<?php

        function Connection(){
            $server="localhost";
            $user="id10666900_arduinodata";
            $pass="thunder";
            $db="id10666900_arduinodata";

            $connection = mysqli_connect($server,$user,$pass,$db);

            if (!$connection) {
                die('MySQL ERROR: ' . mysqli_connect_error());
            }

            return $connection;
        }
    ?>

add.php
<?php
      include("connect.php");

      $link=Connection();

      $query = "INSERT INTO `tempLog` (temp, hum) VALUES ('".$_POST["temp1"]."','"$_POST["hum1"]."')";

              if (mysqli_query($link, $query)) {
                 echo "New record created successfully";
              } else {
                 echo "Error: " . $query . "" . mysqli_error($link);
              }

              $link->close();

      header("Location: index.php");
  ?>

All your headers are on one long line. You need to split them. Use println instead of print when your header is a complete string.

Thanks for your quick response  Majenko . I changed those to println and still doesn't get any data to database.

What do you see when you echo the $query variable?

If I directly feed the data using the url like https://lattalottaroom2.000webhostapp.com/add.php?temp1=40&hum1=50 it echo INSERT INTO tempLog (temp, hum) VALUES ('40', '50') and updates the DB. However after I changed the arduino code as follows, I was able to upload data to local database with add.php using my arduino and ethernet shield. client.print("GET /arduino/add.php?");           client.print("temp1=");           client.print(t);           client.print("&hum1=");           client.println(h);

I have the same problem as you and I would like to know if you already know the answer? If you do, can you please share your knowledge. It would be very helpful. Thank you.


text:
What hardware do I use to detect an electric current going to a lightbulb and tell if it is turning on and off
I’m doing a project where you have to detect a lightbulb coming on through the electrical current and was wondering what Hardware and what the program is? Can y’all help? Very much appreciated if y’all do.

What kind of Arduino will you be using?

What about a current sensor? The code depends on the sensor. Choose a fitting one and try to interface it with an Arduino. You can always come back with a specific question

I am using an Arduino uno

I never thought about a current sensor. Thank you very much

this part of the title is redundant and it turning on and off

A suitable piece of hardware would be a ACS712 Current Sensor which can be used with any Arduino which runs on 5 volts -for instance an Arduino Uno.
You may find this guide useful in writing the program.


text:
How to work with a pulled high input pin where it needs to read a value from an analog sensor?
I have a small ESP32 module, that has some in-built features, like a TFT, and has few available pins for general use.
It has some input only pins (GPIO36 to 39) that are used by buttons soldered in the pcb, and they are all pulled high by 4.7k resistors, in the schematics below:

I won't use these pins as buttons (and I won't press them), and I need to connect the analog output (0-3.3V) of one sensor in one of these inputs and use analogRead() to get the results.
Is is possible to use a pulled high pin to read an analog voltage from a sensor? It just inverts the readings of the output voltages? When the sensor outputs 3.3V the pin will read 0V and when the sensor outputs 0V the pin will read 3.3V?
It's just a matter of inverting the values read in the code? Or anything else?
Thanks!

Do these pins have external pullups on the PCB or are the builtin ESP32 pullups used (which can be activated and deactivated via software)?

There will be no inversion because of the on board button's external pullup resistor.
The impedance of an analog pin is extremely high (say 10Mohms) so a 4.7k series resistor in series will make little difference.
Any required inversion of the analog result can be done in software.
Don't press the connected button though if a sensor is applying a voltage.

@chrisl these pull-ups are wired in the pcb, not inside the chip. I'll update the question

@6v6gt, so nothing happens? It acts as a normal analog input?

@Rodrigo Can you add how you would be connecting the sensor to the drawing?

You need to remove the pull-up resistor if you want to use it as analog ADC pin.

@Rodrigo My previous comment may not be correct under all circumstances. If your sensor is say a light dependent resistor, then you need a pullup to form part of a potential divider. If the sensor, however, delivers a voltage (say some types of  microphone), then you need to remove the pullup resistor (or cut a track)  as already mentioned by hcheun . It depends on the sensor. What sensor are you using ?


text:
How can I declare an array of variable size (Globally)
I'd like to make three arrays of the same length. According to the documentation, Arrays must be defined as int myArray[10]; where 10 can be substituted for a known length (another integer), or filled with an array {2, 3, 5, 6, 7}.
However, when I attempted to declare a value int arrSize = 10; and then an array based on that size int myArray[arrSize];, I get the following: error: array bound is not an integer constant.
Is there a way to variably determine array sizes, or do I just need to hardcode them? (I was taught hardcoding is bad and something to avoid at all costs.)

I had a similar problem and did this. I am learning too so can't say if it is valid solution or not but it worked. See below part of code using vectors, it took me quite a bit to start to understand them and I am still not an expert by no means: #include  #include  #include  #include  #include <string.h> using namespace std; int main() { string name; string address; string town; string country; string answer; vector<vector> personData; for(;;) { vector myTempData; cout<<"enter name or n to exit"<<endl; getline(cin, name); if(name=="n") { bre

Your question has 2 parts actually.
1/ How can I declare the constant size of an array outside the array?
You can either use a macro
#define ARRAY_SIZE 10
...
int myArray[ARRAY_SIZE];

or use a constant
const int ARRAY_SIZE = 10;
...
int myArray[ARRAY_SIZE];

if you initialized the array and you need to know its size then you can do:
int myArray[] = {1, 2, 3, 4, 5};
const int ARRAY_SIZE = sizeof(myArray) / sizeof(int);

the second sizeof is on the type of each element of your array, here int.
2/ How can I have an array which size is dynamic (i.e. not known until runtime)?
For that you will need dynamic allocation, which works on Arduino, but is generally not advised as this can cause the "heap" to become fragmented.
You can do (C way):
// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source)
if (myArray != 0) {
    myArray = (int*) realloc(myArray, size * sizeof(int));
} else {
    myArray = (int*) malloc(size * sizeof(int));
}

Or (C++ way):
// Declaration
int* myArray = 0;
int myArraySize = 0;

// Allocation (let's suppose size contains some value discovered at runtime,
// e.g. obtained from some external source or through other program logic)
if (myArray != 0) {
    delete [] myArray;
}
myArray = new int [size];

For more about problems with heap fragmentation, you can refer to this question.

ARRAY_SIZE = sizeof myArray / sizeof myArray[0];, this way you can change the type of myArray without introducing bugs. For the same reason, myArray = realloc(myArray, size * sizeof *myArray);. BTW, casting the return value of malloc() or realloc() is useless also. 2) Checking for myArray != 0 in the C version is useless, as realloc(NULL, sz) is equivalent to malloc(sz).

const int ARRAY_SIZE = 10;
int myArray[ARRAY_SIZE]; Do you really think it is possible?. This would give variably modified array error in C.

@ArunCheriyan in C I don't know, but in C++ it compiles and runs perfectly. Since Arduino is C++ based, then there is no issue here.

There could be one reason to use dynamic memory safely on an Arduino, which is when you DON'T delete that memory and reuse it anymore, so just for 'initialization' purposes. You just have to make sure that the total amount of dynamic memory is enough to leave space for other dynamic memory (including function/methods arguments which land on the stack).

I know I'm a little late here, but in theory regular arrays can't be created using a variable to define the amount of elements the array is going to have as in:
int arrSize;
int myArray[arrSize];

This will display an error since when declaring the array, the program expects for the value between the brackets to be a constant. Yet, there is a way in which you could create an array with a variable defining the amount of values this arrays is going to have through dynamic memory allocation for value sets (this method has been tested with monodimensional arrays only, haven't tried for multidimensional yet), and it goes something like this:
//First you create a pointer for the memory space to be separated for the set you're creating
int* myArray;
int arrSize; //Then you define the variable that will determine the amount of elements the array is going to have, you can give it a value whenever you want as long as this int is defined before the values in myArray are set
myArray=(int*)calloc(arrSize,sizeof(int)) //Here, you establish that the instance myArray (whose memory space has already been separated through the creation of the pointer) will be separated into arrSize amount of elements of type int with a maximum memory value (in bytes) equal to the maximum available for the int type variables

After this, all that's left to do is assign a value for every element created in the instance myArray (which is already an Array by now) as you would for a normal array created as myArray[arrSize].

If you know the maximum length of array, just initialize the array to that length and use an integer to tell the program how much of that array to use.  If it's the difference between 7,10 bytes then you are not wasting that much memory allocation.

The coderwall explains in Some detail the theory of how best to get the size of an array in C++ https://coderwall.com/p/nb9ngq/better-getting-array-size-in-c

Hi John, welcome to Arduino Stack Exchange! We have a general rule that answers should not just be links, as links do (unfortunately) go down and then the answer is useless. Please summarize, or re-post, the information in the answer right here (I notice it is quite short) so that the usefulness of it doesn't go away. I suggest you give credit by linking to the site, or the name of the author, or both.

It's better to include your own short answer and only referencing the source. Otherwise the answer is of no help when the website you link to gets removed.

The size of the array must be known at compile time. Otherwise you should allocate memory dynamically using:
char *chararray = malloc(sizeof(char)*x);

where x(an integer) can be set in the application code (you could load it from eeprom if you wanted it be a persistent but configurable setting).

However if you just want to declare some arrays of the same size, you just have to declare the number a constant like this:
const int arrsize = 10;
char array1[arrsize];
int array2[arrsize];

I think not hardcoding things only makes sense if you would reasonably expect the user to want to change the setting at some point. I don't know if that's the case.

Coding sizes symbolically instead of literally can provide two benefits: 1) A well chosen symbol documents, or at least suggests, the reason for the choice; and 2) when other parts of the program or module need to be tailored to that choice, an expression using the same symbol can make that automatic, making maintenance much easier.

[A bit off topic, but] "user" is ambiguous as it can mean one of a number of people. It usually implies the end user, the consumer of final product, if not stated otherwise. It could be the next programmer, the immediately next consumer of your code, who might, in fact, be you (typical, in my own experience) a year or more after I've forgotten the nitty-gritty internal details of it). Or a system designer who includes your code as a ready-to-go module in his/her product. I suspect you meant the second "user".


text:
how to make arduino as mind thought reader?
I'm trying to create arduino base mind reader... And for that I thought that EEG electrode connected to arduino and then the data send to arduino in 01 form .. But I facing problem in how to convert this or which wave (alpha, beta,delta)give very high or acutrate result.

Even if the answer provided by Mike is really doable and can be implemented you should really think about what you want to reach and what is your goal.
The big difference between EEG and mind readers is that the process of thinking, even if you can record all that waves: alpha, gamma,... can be never decoded to get useful informations. I mean: you can record and get a confirm that you have more gamma waves when you are doing meditation. Or that aplha and beta wave are going to be much more present when waking up or in particular hours of the days, but you never get an image of what the person is thinking or what are its emotions... That because you can get some waves coming from the brain but you cannot reconstruct the billion of processes that are happening inside the brain.
A lot of researcher are trying to decoder those informations to move as an example an arm or a leg. But it is the front edge of the reasearch really not doable with an Arduino....
Anyway good luck!

And to add to that - the cheap way of getting alpha/beta/gamma etc. is VERY unreliable. A real EEG would have several dozens of electrodes connected directly to the head's skin, as oppose to a single metal functioning as a voltage detector, that needs to handle too much noise.

You could hack an existing device like the Mattel Mind Flex ($20-50 on Ebay).
There have been a number of projects that do exactly what you have described - there's even an arduino library: https://github.com/kitschpatrol/Brain
http://frontiernerds.com/brain-hack


text:
Setting EN_AA (auto ACK) to 0x01 or 0x02 makes nRF24L01+ stop sending/receiving
Test case:
2 arduino nodes with nRF24L01+ transceivers. Using maniacbug's RF24 library. Using pipes 0 and 1. (Auto-ACK is ON for all pipes by default)
When I set Auto-ACK ON for all pipes rf24.setAutoAck(true): it works.
When I set Auto-ACK OFF for all pipes rf24.setAutoAck(false): it works.
But when Auto-ACK is ON for pipe1 and OFF for pipe0 (I want pipe0 for broadcasting) rf24.setAutoAck(0,false):it stop working (no packet is received or sent).
Same thing with Auto-ACK ON for pipe0 and OFF for pipe1
Couldn't find anything about it on the datasheet neither other forums nor here. Is there something I'm missing?
Test sketches:
Node 1
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 rf24(9,8);

uint64_t pipe0 = 12312312LL;
uint64_t pipe1 = 11111111LL;

int data[2];

void setup()
{
    Serial.begin(115200);
    data[0] = 123;
    data[1] = 456;

    rf24.begin();
    rf24.setChannel(109);
    rf24.setPayloadSize(2);
    rf24.setDataRate(RF24_2MBPS);
    rf24.openReadingPipe(0,pipe0);
    rf24.openReadingPipe(1,pipe1);
    rf24.openWritingPipe(22222222LL);
    rf24.setAutoAck(0,false);
}

void loop()
{
    delay(1000);
    Serial.print("ACK: ");
    Serial.println(rf24.write(data,sizeof(data)));
}

Node 2:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 rf24(9,8);

uint64_t pipe0 = 12312312LL;
uint64_t pipe1 = 22222222LL;

int data[2];

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

    rf24.begin();
    rf24.setChannel(109);
    rf24.setPayloadSize(2);
    rf24.setDataRate(RF24_2MBPS);
    rf24.openReadingPipe(0,pipe0);
    rf24.openReadingPipe(1,pipe1);
    rf24.setAutoAck(0,false);
    rf24.startListening();
}

void loop()
{
    if(rf24.available())
    {
        Serial.println("Got somethin");
        int incoming;
        rf24.read((byte *) &incoming,2);
        Serial.println(incoming);
    }
}

Workaround: enable|disable auto-ack on all pipes just before sending on the pipe you want, reestablishing previous state afterwards

You could try using the new for of RF24 maintained by TMRh20 and submit an issue if it is caused by the library.


text:
Cannot connect with online arduino editor but I can with Arduino IDE to an Arduino Nano
As the title says I have a Nano with CH340G and 168 that connects properly to Arduino IDE but not to Arduino online editor, it does not detect the board "Error uploading, check if the board is available"
What can I do?
EDIT: The IDE online I am using is https://create.arduino.cc/ I am using the same computer and exactly the same board model in both IDEs (both of them have the same options available so both of them should be in the same version)
EDIT 2: I can connect correctly from the online IDE to an Arduino UNO. The problem is just with the Nano.

Which exact online editor? I know several.

Does the browser run on the same computer as the IDE? Did you select the right board in the Online Editor? Nano comes with a new and an old version of it's firmware. Did you select the same firmware in the IDE and the Online Editor? Have you configured your browser to not connect to external periphery like COM ports?

@FilipFranik:  added information requested

@PeterPaulKiefer:  added information requested


text:
Impossibility to open a file for modification in ESP32
Consider the following code:
#include "SD.h"
#include "Fs.h"

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

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

  // see if the card is present and can be initialized:
  if (!SD.begin(5)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  File file = SD.open("/test.txt", FILE_WRITE);
  file.write((const uint8_t*)"is a test", 10);
  file.close();

  file = SD.open("/test.txt", FILE_WRITE); <-- Tested with APPEND too
  file.seek(0);
  file.write((const uint8_t*)"this", 4);
  file.close();

  file = SD.open("/test.txt", FILE_READ);

  while (file.available()) {
    Serial.write(file.read());
  }
  file.close();
}

void loop() {
  // put your main code here, to run repeatedly:

}

If I open the file with FILE_WRITE the contents of the file are zeroed and I get as output:

"this"

And if I open the file in mode FILE_APPEND then seek() does not work and I get as output:

"is a testthis"

How to modify this program so I get any of both?

"thisis a test" [insert] (or) "thistest" [overwrite]

Using an ESP32 here as I think the File or the SD objects are different than the Arduino ones.

"FILE_WRITE" should be just FILE_WRITE.  It's a macro that equates to "w"

Good catch but that was a paste error, the code was fine. I've fixed the code here but the problem remains.

The ESP32 implementation is somewhat convoluted. It goes through multiple layers of compatibility wrappers to use the underlying SDK calls. If write always truncates, and append never seeks, then there is something wrong or lacking in those compatibility layers. You should open an issue on Github, https://github.com/espressif/arduino-esp32/issues

Thanks, issue opened: https://github.com/espressif/arduino-esp32/issues/4028


text:
How to modify values inside a file
I am writing a wav file to an SD card on a ESP32 and that requires that every time I append data to the the end of the file I modify the header to set the right size in some fields.
I cannot find how to replace a value inside a file, I tried to write the new values with the seek function but unless I'm missing something looks like this deletes everything after the new value added.
I do not want to create a new file and to delete the old one as I will storing potentially large wav files and looks like wasting resources.
Is there a way to overwrite one value inside a file. I'm using SDlib but I'm open to others too.
Here the code I use to create the file and to update it:
#include "WavFileWriter.h"

void WavFileWriter::createFile(char const* filename, WavFileHeader* wavFileHeader)
{
  byte headerBuffer[44];
  wavFileHeader->getHeaderData(headerBuffer);
  File file = SD.open(filename, FILE_WRITE);
  file.write(headerBuffer, 44);
  file.close();
}

void WavFileWriter::appendData(char const* filename, WavFileHeader* wavFileHeader, byte* data, int dataLength)
{
  File file = SD.open(filename, FILE_WRITE);
  file.write(data, dataLength);

  byte headerBuffer[44];
  wavFileHeader->setFileSize(file.size());
  wavFileHeader->getHeaderData(headerBuffer);

  file.seek(0);
  file.write(headerBuffer, 44);
  file.close();
}

After calling appendData I end up with a file with just the header size (with the right header for a file with data but the data is gone).

why do you need to store the sound data in wav format?

can you identify the position of the sector on the SD card where the header is stored, keep a copy of it in RAM, keep this copy updated and write it to SD from time to time?

just store the raw data ... if you need a wav file then use something like Audacity to convert raw to wav

show your code.

added the code. I should have done from the beginning, my bad.

issue: if I have an fixed size file (8MB in my case), and I seek somewhere
an the file and do a write, the file size is truncated to the end of the block that I write. I am emulating a disk using a file and trying to write "sector data"
at various locations. Read using the same strategy works fine, but the writes destroy any data after the sector I write by truncating the file size. // running on an ESP32 using arduino IDE 1.8.13 environment // start with a file called CPM000.DSK on an SD card that is 25664512 bytes #include "FS.h" // file system support #include "SD_MMC.h" // uSD card suppo

The FILE_WRITE in SD library is 'append' (for historical reasons)
#define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

so use
 File file = SD.open(filename, O_WRITE);

Looks like the ESP32 uses a different library and the definitions are different: #define FILE_READ       "r"
#define FILE_WRITE      "w"
#define FILE_APPEND     "a"

Should I use SPIFFS instead of SD?

SD.seek() is the API you're looking for.  It allow you to position the read/write pointer within a file.   In standard C++ the fseek() API is used.

OP is using seek()

I added the code so you can see if this is the expected usage.

It looks like you're not seek'ing to the end of the file when you attempt to append data.  Try:  file.seek(file.size()) between the SD.open() and file.write() in the WavFileWriter::appendData() method.


text:
Error while sending message using gsm sim900a module interfaced with arduino uno
The code used for interfacing the gsm module with arduino for sending a message is as follows :-
#include <GSM.h>

#define PINNUMBER ""

// initialize the library instance
GSM gsmAccess; // include a 'true' parameter for debug enabled
GSM_SMS sms;

// char array of the telephone number to send SMS
// change the number 1-212-555-1212 to a number
// you have access to
char remoteNumber[20]= "12125551212";

// char array of the message
char txtMsg[200]="Test";

void setup()
{
  // initialize serial communications
  Serial.begin(9600);

  Serial.println("SMS Messages Sender");

  // connection state
  boolean notConnected = true;

  // Start GSM shield
  // If your SIM has PIN, pass it as a parameter of begin() in quotes
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }
  Serial.println("GSM initialized");
  sendSMS();
}

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

void sendSMS(){

  Serial.print("Message to mobile number: ");
  Serial.println(remoteNumber);

  // sms text
  Serial.println("SENDING");
  Serial.println();
  Serial.println("Message:");
  Serial.println(txtMsg);

  // send the message
  sms.beginSMS(remoteNumber);
  sms.print(txtMsg);
  sms.endSMS();
  Serial.println("\nCOMPLETE!\n");
}

the error is found on the 3rd line
    GSM_SMS sms;
as GSM_SMS is not a name type.
what point am i missing here...??
thank you in advance.

Which version of the Arduino IDE are you using?

Update your IDE software. You need IDE 1.0.4 or later.
I copied your code into my 1.0.5 IDE and compiled it without any error. So it is most probably your version of the Arduino IDE.


text:
Can I use 1-byte datatypes to store digital input?
I am reading the docs on DigitalRead() and wondering why it stores seemingly boolean HIGH and LOW inputs in int data type variable.
I have two issues with that:

int is 2-byte, while bool and uint8_t are 1-byte so it seems like a waste of memory for no benefit whatsoever.
It gets me confused when reading the code about whether the input came from digital or analog since int can have a wide range.

Is there any particular reason for storing digital inputs as int?
EDIT: bool and uint8_t are out of the question as per the answer below. int8_t still looks suitable for the purpose though.

Note that the value returned by a function is passed in internal CPU registers, so no waste of RAM here. If I ever had to store the returned value in memory, I would indeed use an uint8_t.

You receive the data as int, but you store it as byte.
For example, when you call the serial library function to receive a data byte, the library will return either the data or a -1 if a problem has occurred.
The binary value of -1 is a byte 11111111 or int 1111111111111111.
The binary value of 255 is a byte 11111111 or int 0000000011111111.
I think that you can see the problem if you use byte data and the data is 255.
So, if you receive an int -1, then you do not process the data.  Otherwise you cast the int to uint8_t.
You could receive byte data, but then the value of 255 would be undefined.

I suspected there was something hidden going on. What about int8_t? It can store -1, 0, and 1 and still takes up 1 byte

int8_t stores values of -128 to 127 .... uint8_t stores values of 0 to 255 ... the two data types both store 8 bits ... they are just there so that the compiler will throw a warning if the limits are exceeded

So I just replaced all ints storing digital inputs in my program with 1-byte int8_ts. It seems to work fine so far.

Neither digitalRead() nor analogRead() ever return -1.
There is no reason why digitalRead() is a int function instead of uint8_t, and it indeed needlessly wastes space. The compiler will probably optimize it away though, if you store the result as uint8_t or int8_t

I did not check the internals a while, but in early days there was a
 #define HIGH 1

meaning that HIGH is a const int.
Perhaps someone did not want to disable some TRI-STATE digital logic in the beginning, and since then nobody wanted to change the basics.
But of course bool is a more appropriate data type for HIGH/LOW and of course you can always treat them this way, for example like
if (! digitalRead(pin) ) { // pin is LOW
   ...
}

jsotola's answer why Serial.read() returns  an int is a different issue. And correct of course.

The smallest unit in most languages is a byte (8 bits), whether signed or unsigned.
So returning a byte, even if it only returns three different values, is the smallest and most efficient unit available, that I'm aware of.
If you want to store later, you can assign each bit of a byte as a high or low, thus giving you 8 storage spots.

One could always store the value of digitalRead() as a bit in a variable, compacting the data from say 8 pins down into 1 byte
// read an input and store it, say the reads of D2 thru D9 are stored in byte bits9to2
// 9,8,7,6,5,4,3,2
// first clear the state for 2
bits9to2 = bits9to2 && 0b11111110; // two && for bit manipulation? Or just 1?
// then map in the new value
if (digitalRead(D2) == HIGH){
bits9to2 = bits9to2 || 0b00000001;// two || for bit manipulation? Or just 1?
}
else{
// leave it as 0
}

Then to use it later on:
if ((bits9to2 && 0b00000001) != 0){
// bit is set (HIGH), do whatever
}
else {
// bit is clear (LOW), do whatever, or maybe do nothing
}

Can use an unsigned int and store 16 bits compacted that way, or unsigned long for 32 bits.


text:
arduino circuit review/ safety review
I have the following circuit
It has a simple dc motor that is OFF, and switches ON once a day for 2 seconds.
I use MOSFET IRF540N as a switch
I use L7805CV as a voltage regulator
I would like to have a review and to ask whether it is safe to connect this circuit to a 9v 1A (center+) DC wall plug.
I have measured the dc motor and it takes 60 mA when it is on with 5V.

The "Arduino" part of your schematic looks OK. 9 VDC to VIN on the Uno is OK. Connecting the MOSFET directly to the Arduino is OK.
Personally, I would connect a 1000 ohm resistor in series between the Arduino pin and the gate of the MOSFET. If you like to live dangerously like I do, and change wiring connections with power supplied to your Arduino, then a 1k resistor will limit the maximum current flow to around 5 mA. This is not going to "fry" anything if you inadvertently connect an output to power or ground.
The question about the L7805CV is off-topic, but a quick look at the datasheet suggests an input and output capacitor should be used.
I’m sorry to be the bearer of bad news, but the IRF540N is a poor choice as a MOSFET to use with a micro-controller. While it’s true that you are only drawing 60 mA, the VGS specified for this MOSFET is at 10 VDC, not the 5 VDC supplied by the Uno. A "logic level" MOSFET would be better suited for your application.
For more information regarding MOSFETs, please read: How to control a 12V solenoid valve with a mosfet?

You should not use a "naked" L7805CV. That voltage regulator requires a couple of capacitors in order to build a functioning voltage regulator out of it. You should be able to find instructions online for how to build one. Search on "L7805CV circuit" and you should find quite a few sample circuits.
That said, 9V is a good unregulated voltage to provide to the Vin line on the Arduino. Its built-in voltage regulator should be able to regulate that to 5V quite well, even with "bobble" caused by motor. (The built-in voltage regulator is able to handle input voltages from 7.5V to 12V, although if you feed it 12V and draw a lot of current out of the 5V line you may have overheating problems.)
You should also use a "logic level" MOSFET that can be driven with a 5V gate voltage.

In general your circuit is fine, but the parts are pretty overpowered.
If there is a reasonable voltage drop at the IRF540N you better choose a mosfet with a lower gate-source threshold voltage, if it works I'd say it's fine.


text:
Can I connect esp32 to a phone USB charger?
I have a USB charger. Is it ok to connect it as a power supply for esp32?
Edit: i have a dev board esp32

In principle yes (see also comment in update).
The voltage is ok (5V), typically USB, and it doesn't differ from the output of a computer USB port.
The output current is max 2000 mA, so check if your project (ESP + related hardware powered by this USB), is not exceeding 2000 mA. The ESP needs much less than 2000 mA, so if you didn't have a lot of external components or motors than you will be safe.
Update
Important omment from Sim Sson: The bare esp32 is not 5V-tolerant, so using a usb-charger is only ok for esp modules that have a voltage regulator onboard.

I think you might have missed a zero there. The charger says "2000mA".

@hooskworks Thanks for the notification, and yes I did (updated my answer).

The bare esp32 is not 5V-tolerant, so using a usb-charger is only ok for esp modules that have a voltage regulator onboard.

@SimSon I was assuming he will connect the USB cable into the plug (thus having some kind of development board). But I will add it to the answer, thanks a lot.

@yuria Hopefully he does, but he didn't tell. Thanks for adding that point, it might be useful for others having this question in future!

@SimSon True, a year ago I possibly wouldn't realize it myself

@SimSon Bare esp32 is only the rectangle right?if i have a micro usb,then it is the dev board?

@yuria yes, a device with usb socket is always supposed to be 5V tolerant as that's part of the standard


text:
LCD screen won't stop printing the same characters twice
I'm hoping that someone might be able to help me figure out how to prevent my LCD from giving me double digits (i.e. 55, 66, 77 - instead of 5,6,7);
I have 2 functions that are printing, so I'm expecting the issue to be related to this.
Here's the code:
#include <Wire.h>

#include <Adafruit_LiquidCrystal.h>
#include <Keypad.h>

unsigned int deBounce = 100;
int curs = 0;

Adafruit_LiquidCrystal lcd(8, 9, 3, 10, 11, 12, 13);

const byte numRows = 4; //number of rows on the keypad
const byte numCols = 4; //number of columns on the keypad

char keymap[numRows][numCols] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'.', '0', '#', 'D'}
};

char keymap2[numRows][numCols] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'.', '0', '#', 'D'}
};

//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {25, 27, 29, 31};
byte colPins[numCols] = {17, 19, 21, 23};

//initializes an instance of the Keypad class
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
Keypad myKeypad2 = Keypad(makeKeymap(keymap2), rowPins, colPins, numRows, numCols);

char enteredDigits[10]  = " ";//null terminated character array to hold entry
char enteredDigits2[10]  = " ";//null terminated character array to hold entry
boolean entryComplete = false;
boolean entryComplete2 = false;
boolean first = 0;

float result; // Create an integer for the result of 'A' and 'B' (in this case, it will be the 'Inductance' x 'Capacitance')
float power = .5; // Used in the equation
float r1; // Result 1
float r2; // Result 2
float r3; // Result 3
float r4; // Result 4
float fc; // Result 5
float power2 = 6; // Used in the last part of the equation
float result2 = 10; // Also used in the last part of the equation
#define TWO_PI 6.283185307179586476925286766559 // two Pi (:
float num1;
float num2;

void setup()
{
  myKeypad.setDebounceTime(deBounce);
  myKeypad2.setDebounceTime(deBounce);

  lcd.begin(16, 2);
}

void loop()
{
  getNumber();
  if (entryComplete)
  {
    entryComplete = false;
    lcd.setCursor(0, 1);
    num1 = atof(enteredDigits);
    first = 1;
  }

  if (first == 1) {
    getNumber2();
    if (entryComplete2)
    {
      entryComplete2 = false;
      lcd.setCursor(0, 1);
      num2 = atof(enteredDigits2);
      values();
      first = 0;
    }
  }
}

void getNumber()
{
  static byte index = 0;
  char key = myKeypad.getKey();
  if (key != NO_KEY)
  {
    switch (key)
    {
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9': case'.':
        lcd.print(key);//print entry on top row
        enteredDigits[index] = key;//build character string
        index++;
        enteredDigits[index] = '\0'; //null terminate
        break;

      case '#':
        lcd.setCursor(8, 0);
        lcd.print(F("= Ind."));
        delay(1000);
        entryComplete = true;
        index = 0;//reset for next entry
        break;

      case 'D'://clear entry and display
        memset(enteredDigits, '\0', 10); //clear buffer
        lcd.clear();
        index = 0;
        entryComplete = false;
        break;
    }
  }
}

void getNumber2()
{
  static byte index2 = 0;
  char key2 = myKeypad2.getKey();
  if (key2 != NO_KEY)
  {
    switch (key2)
    {
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9': case'.':
        lcd.print(key2);//print entry on top row
        enteredDigits2[index2] = key2;//build character string
        index2++;
        enteredDigits2[index2] = '\0'; //null terminate
        break;

      case '#':
        lcd.setCursor(8, 1);
        lcd.print(F("= Cap."));
        delay(1000);
        entryComplete2 = true;
        index2 = 0;//reset for next entry

        break;

      case 'D'://clear entry and display
        memset(enteredDigits2, '\0', 10); //clear buffer
        lcd.clear();
        index2 = 0;
        entryComplete2 = false;
        break;
    }
  }
}

void values() {

  result = num1 * num2; // If a 'comma' key is pressed (in this case, the # key on a 4x4 keypad)

  lcd.clear(); // Clear the writing from the LCD
  lcd.setCursor(0, 0); // Set the cursor position to the first block on the first line
  lcd.print(F("Ind. =")); // Display 'Ind. =' onto the LCD Screen
  lcd.setCursor(7, 0); // Set the cursor position to display after the previous text
  lcd.print(num1, 4); // Display the number value given to num1
  lcd.setCursor(0, 1); // Set the cursor for the first block on the second line
  lcd.print(F("Cap. ="));// Display 'Cap. =' onto the LCD Screen
  lcd.setCursor(7, 1); // Set the cursor position to display after the previoust text
  lcd.print(num2, 2); // Display the number value given to num2
  delay(2500);

  r1 = pow(result, power);
  r2 = r1 * TWO_PI;
  r3 = 1 / r2;
  r4 = pow(result2, power2);
  fc = r3 * r4;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Res. Peak =")); // Display the answer onto the LCD Screen
  lcd.setCursor(0, 1);
  lcd.print(fc);
  lcd.setCursor(9, 1);
  lcd.print(F("(Hz)"));
}

I fear it's related to debounce time and the duration of pressing a keypad button. Is it always exactly duplicating the entries?  What about a debug output (Serial) to see more, what's going on?

Hmm, I didn't notice anything after changing the debounce settings. Even with a relatively high debounce (500 milliseconds), it still prints double.

If I take out this line from the getNumber2 function:

I had to remove this line from the getNumber2 function!
lcd.print(key2);
works now (:

keymap2 is not useful at all and just a duplicate. But having both keypads act on the same pins is your issue. Or don't you intend to have two keypads ?

You need to break your code into parts and debug it part by part. Start by printing a single character to the LCD once, and setting a bool so you don't do it repeatedly. If that works, the LCD is not your problem.
As DataFiddler suggested, bounce problems with your switch seem like a likely culprit. Add serial print statements to your button handling code and see if it's being triggered more than once. If so, research debouncing code.


text:
DC Motor Acceleration with PWM
I'm not sure why this has been so difficult for me, but I'm trying to control the acceleration of a 10v DC motor with an Arduino UNO and an L298n H-Bridge. Using a 12v regulated power supply to power the motor
For the life of me, I can't get a smooth acceleration/deceleration for this. I want the motor to move back and forth with a potentiometer, slowing down as it reaches the '0' and '10' positions. This works, but it's not very smooth
const byte motorUp      = 4;
const byte motorDown    = 5;
const byte motorPWM     = 6;

const int speed1 = 85;
const int speed2 = 92;
const int speed3 = 100;
const int speed4 = 110;
const int speed5 = 130;
const int speed6 = 190;

int state = 0;

const byte wiper        = A0; //Position of fader relative to GND (Analog 0)
double faderMax = 0; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
byte motorSpeed = 255;  // Raise if the fader is too slow (0-255)
byte tolerance  = 10;  // Raise if the fader is too shaky (0-1023)

void setup() {
  Serial.begin(250000);
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  analogWrite(motorPWM, motorSpeed);
  calibrateFader(); }

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, 155);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(wiper) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, 155);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(wiper) + tolerance;
  delay(2500); }

void loop () {
  moveMotorUp();}

void moveMotorUp() {
  while (analogRead(A0) <= 100) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 100) && (analogRead(A0) <= 200)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 200) && (analogRead(A0) <= 300)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 300) && (analogRead(A0) <= 400)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 400) && (analogRead(A0) <= 500)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 500) && (analogRead(A0) <= 600)) {
    analogWrite (motorPWM, speed6);
    digitalWrite (motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 600) && (analogRead(A0) <= 700)) {
    analogWrite (motorPWM, speed5);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
   while ((analogRead(A0) > 700) && (analogRead(A0) <= 800)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 800) && (analogRead(A0) <= 900)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 900) && (analogRead(A0) <= 1000)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while (analogRead(A0) > 1000) {
    analogWrite (motorPWM, speed1);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW);
    moveMotorDown(); } }

void moveMotorDown() {

  while (analogRead(A0) > 1000) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 900) && (analogRead(A0) <= 1000)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 800) && (analogRead(A0) <= 900)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 700) && (analogRead(A0) <= 800)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 600) && (analogRead(A0) <= 700)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 500) && (analogRead(A0) <= 600)) {
    analogWrite (motorPWM, speed6);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 400) && (analogRead(A0) <= 500)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 300) && (analogRead(A0) <= 400)) {
    analogWrite (motorPWM, speed4);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 200) && (analogRead(A0) <= 300)) {
    analogWrite (motorPWM, speed3);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 100) && (analogRead(A0) <= 200)) {
    analogWrite (motorPWM, speed2);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 10) && (analogRead(A0) <= 100)) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while (analogRead(A0) <= 10) {
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW);
    moveMotorUp(); } }

I hope it's simpler than this - Any ideas?
Thanks

You have a nice infinitely recursive pair of functions there. You're going to run out of stack space if you leave that running for a while.

It seemed really inefficient to me as well. Know of any libraries that have acceleration? I'm wishing I could find something like the AccelStepper library for stepper motors. Unfortunately I'm limited to a DC motor this time.

@zRockafellow There are multiple libraries that provide value interpolations between values with various mechanisms (e.g., Ramp). Anything that can be done with recursion can be done without it--it's more likely you mean to have a state machine.

I think you need to think a little differently. Instead of "Move it at this speed until you get to here" you need to think more along the lines of "Where am I? Where do I want to get to? How far away is it?"
Basically the further you have to go the faster you want to go. The closer you get to your target value the slower you want to go.
Simply put - you want to convert the distance between your current and target positions into a proportional speed.
Take one variable: the target value that you want to get to. Take one reading: the current location of the fader. Subtract one from the other.
Take the sign of the result - that defines what direction you want the motor to turn in.  Take the "absolute" (abs(...)) value of the result - that is the distance you are away from your target.  Divide that absolute value by a speed factor to keep it within the range of your PWM, or lower if you want to go slower. Set the speed of the motor to that result.
So if you want to get to 0 and you are currently reading 1000 from the fader then:

Difference = 0 - 1000 = -1000
Sign is negative, so set direction to "down".
Distance is abs(-1000), or 1000.
Divide by 4 (max ADC is 1023, max PWM is 255 - 1023/4 = 255) = 250
Set speed to 250

Then a moment later you may be reading 738 from the ADC - so this time:

Difference = 0 - 738 = -738
Sign is negative, so set direction to "down".
Distance is abs(-738), or 738.
Divide by 4 (max ADC is 1023, max PWM is 255 - 1023/4 = 255) = 184
Set speed to 184

Keep doing that until you get to your target value (or within a certain tolerance of it) at which point you stop and wait for a new target value to be selected (or automatically change the target value as per your sweep demo - if 0 then set to 1023. If 1023 then set to 0).
This method then allows you to go directly to any value you choose with a deceleration as it approaches that target.

Hi Majenko, Thanks for the details! I've been trying to wrap my head around how to implement PID control into this project. I'm still not sure how to set it up though. I tried following your instructions, but you lost me at "Take the sign of the result"