text:
HTTP_GET not clarified in scope
I'm trying to do an async webserver with access point using an ESP32.
It's a little bit of a mix between This tutorial for AP and async and this tutorial since it's also with an async webserver and it uses inputs which I desperately need.
The part I don't understand is I included all the necessary libraries and I still got this error. If I copy-paste the code in one block everything is fine. It was never necessary to declare HTTP_GET since it should be a variable from a library.
So what's wrong?
These are my errors:
    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\Async Webserver ESP32\main\main.ino:3:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp:1:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    C:\Users\Valentin\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp: In function 'void setup_server(AsyncWebServer)':
    webserver.cpp:6:18: error: 'HTTP_GET' was not declared in this scope
       server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
                      ^
    Multiple libraries were found for "WiFi.h"
     Used: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi
     Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
    Using library ESPAsyncWebServer-master at version 1.2.3 in folder: C:\..\Arduino\libraries\ESPAsyncWebServer-master
    Using library FS at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\FS
    Using library WiFi at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi
    Using library AsyncTCP-master at version 1.1.1 in folder: C:\..\Arduino\libraries\AsyncTCP-master
    exit status 1
    'HTTP_GET' was not declared in this scope

I already tried to use the standard Arduino WiFi library which resulted just in more errors so I switched it back.
I split up the code into three pieces for better visibility.
main.ino
#include <Arduino.h>
#include "webserver.h"

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "blabla";
const char* password = "blabla";

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

  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(IP);

  setup_server(server);
}

void loop() {}

webserver.cpp
#include "webserver.h"

void setup_server(AsyncWebServer server) {
  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    // GET input2 value on <ESP_IP>/get?input2=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
    // GET input3 value on <ESP_IP>/get?input3=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
      + inputParam + ") with value: " + inputMessage +
      "
Return to Home Page");
    });
    server.onNotFound(notFound);
    server.begin();
  }

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

webserver.h
#ifndef WEBSERVER_H
#define WEBSERVER_H

#include "Arduino.h"
#include "ESPAsyncWebServer.h"
#include "AsyncTCP.h"
#include <WiFi.h>

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";

AsyncWebServer server(80);

String music_state;
IPAddress IP;

String inputMessage;
String inputParam;

// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
  <title>ESP Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <form action="/get">
    input1: <input type="text" name="input1">
    <input type="submit" value="Submit">
  </form>

  <form action="/get">
    input2: <input type="text" name="input2">
    <input type="submit" value="Submit">
  </form>

  <form action="/get">
    input3: <input type="text" name="input3">
    <input type="submit" value="Submit">
  </form>
)rawliteral";

void setup_server(AsyncWebServer server);

void notFound(AsyncWebServerRequest *request);

#endif

Thanks for the input, I will check back tomorrow and answer all questions and test every suggestion.

Macro Conflict
You have two basic problems here.  The more significant one is that your use of SERVER_H in your include guard:
#ifndef WEBSERVER_H
#define WEBSERVER_H

conflicts with a usage in ESPAsyncWebServer.h:
#ifndef WEBSERVER_H
typedef enum {
  HTTP_GET     = 0b00000001,
  HTTP_POST    = 0b00000010,
  HTTP_DELETE  = 0b00000100,
  HTTP_PUT     = 0b00001000,
  HTTP_PATCH   = 0b00010000,
  HTTP_HEAD    = 0b00100000,
  HTTP_OPTIONS = 0b01000000,
  HTTP_ANY     = 0b01111111,
} WebRequestMethod;
#endif

and that explains why your HTTP_GET etc are not found.  They're not being defined because of your include guard macro.
Changing your code to:
#ifndef XENOSHELL_WEBSERVER_H
#define XENOSHELL_WEBSERVER_H

or something similar will get you past that problem.
Multiply Defined Variables
You also have some non-static variables defined in your webserver.h that will also need to be changed somehow.  A simple change just being to make them static:
static const char* PARAM_INPUT_1 = "input1";
static const char* PARAM_INPUT_2 = "input2";
static const char* PARAM_INPUT_3 = "input3";

IPAddress IP; is only used in main.ino, and should be moved there as a local const IPAddress IP = WiFi.softAPIP();  If you leave it in the header you'll get multiple definitions because of that.
String inputMessage; and String inputParam;   Same problem, only these belong inside your lambda expression in server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {
I don't know why your server variable is in the header either.  The simplest thing to do is put it in webserver.cpp instead and don't pass it in to setup_server, in other word remove the parameter and use the variable defined in the same file as the function.

Having done that your code compiles fine.
Whether or not it works is another question.
I am unable to test that.

hello @timemage thanks for your very detailed answer. I got the code to compile too, but when i tried to connect to the wifi from the ESP the IP adress is not reachable. The output i get from serial monitor is " dhcps: send_offer>>udp_sendto result 0 ". Do you maybe know what could be the problem?

As of yet, I don't have an ESP32 board, so I have no way of troubleshooting this.  What you're asking about seems like an entirely new question.  I would say cut down your program to the minimal thing necessary to demonstrate the problem.  Given the message you're quoting, your demo program should not have #include "ESPAsyncWebServer.h" or #include "AsyncTCP.h" in it at all.  If you don't find the problem in the course of making the demo, post it as part of a new question.

Ok still thanks for your answers, right now i settle on the version that works and if i have enough time i will come back to this problem

Thank you! This is a very helpful answer with expert analysis.


text:
What is the maximum frequency input signal that I can accurately track on a GPIO pin?
This all started with me wanting to use an Arduino to make a tachometer. This is all now working fine, but it got me wondering what the highest frequency digital signal that I could read?
So I built a simple test sketch and have run this on both a Nano and an ESP32. The result was about 6300Hz on both. Anything above this gives chaotic results. This is somewhat lower than I expected.
Has anybody done better than this?

Doing it all in software, yes, it'll be slow. There's hardware built in to most MCUs that will do it for you that can measure MHz ranges.

could use a cheap 8 bit counter ic as a frequency divider; just feed the last bit into the MCU where your tach is now, and feed the tach into the clock/tirgger of the IC.

As Majenko wrote, when you only rely on software to measure the frequency on a IO pin, it will always be rather slow. And it also depends on the code, that you use. Functions like digitalRead() are always slower than directly working with the control registers of the pin (Reference). As you didn't show your code, we cannot say more about that.
If you need to measure higher frequencies or you want to do other things in between (like outputting the data somewhere), it is better to use the microcontrollers buildin hardware. There are multiple ways to measure the frequency. 2 immediately come to my mind:

You could assign an ExternalInterrupt or a PinChangeInterrupt to the signal pin (limited choice of pins here), which triggers each time you see a rising (or falling) edge on the signal. In the ISR (Interrupt Service Routine) you could count up a variable. That value is the number of rising (or falling) edges, thus periods of the signal. The frequency is this value divided by the duration of the measurement. Every time you calculate the frequency, you reset the counter; reading it again after a defined duration. This should be better than just polling, but its not the best. (Note that a PinChangeInterrupt triggers on every edge, so you have to divide the frequency by 2)

You could configure an unused Hardware Timer/Counter to use your signal as external clock source. Let it count up until it overflows (or up to a value defined by you) and let it trigger an interrupt. Since the Arduino framework already uses Timer0 for timekeeping, you could divide the max value of the Timer/Counter by the time passed and you will get the frequency. I think this can get you in the MHz range.(As with PinChangeInterrupt, the Counter will increment on every edge, so again a factor of 2 here)

Both ways will calculate the frequency as a mean over a specific time. If you have a changing frequency, you might wanna manipulate measurement frequency. In the first case you can change the interval, in which you read the counter variable. In the second case you can change the max value, to which the Timer/Counter will count.

what the highest frequency digital signal that I could read?

(I assume you just want to read the frequency of the signal) That depends on many factors. If we use the second case from above (configuring a Hardware Timer as Counter connected to the signal) we have a limit on the maximum frequency, that we can provide. I found the relevant part in the datasheet of Atmega328p (which is the microcontroller on the Nano):

Each half period of the external clock applied must be longer than one system clock cycle to ensure correct
sampling. The external clock must be guaranteed to have less than half the system clock frequency (f ExtClk < f clk_I/O /2) given a 50/50% duty cycle. Since the edge detector uses sampling, the maximum frequency of an
external clock it can detect is half the sampling frequency (Nyquist sampling theorem). However, due to
variation of the system clock frequency and duty cycle caused by Oscillator source (crystal, resonator, and
capacitors) tolerances, it is recommended that maximum frequency of an external clock source is less than
f clk_I/O /2.5.

So we should stay below the controllers clock frequency divided by 2.5, which would be 16MHz / 2.5 = 6.4MHz for the Nano. But before you reach that, your code might introduce further delays, which make the measurement less accurate. That depends on the implementation.

Dear Chris and Majenko, Thanks for the excellent answers. I have tried the approach of using the signal to trigger an interrupt. That helped a bit. I have not tried to feed the signal into a hardware counter. I don't need to do this at the moment but it is a useful thing to know.

My DaquinOscope https://www.daqarta.com/dw_rroo.htm can use burst sampling to grab 1024 samples at high sample rates, then send them to a host computer over USB for display and analysis. For digital-only inputs it can acquire over 400,000 samples per second on an UNO, with each sample being a reading of 8 pins to make one byte in the record.  It does this by reading a digital port (PIND or PINB) in a tight loop, with an optional delay on each read for slower sampling. DaquinOscope is free, and it uses the open-source DaqPort https://www.daqarta.com/dw_rraa.htm, both included with Daqarta, complete with code that you can modify as desired.

Oh Wow! - I've just had a surf through your site - lots of interesting stuff. Many thanks, but you should have warned me - I could easily lose weeks of my life here. I do have a vague aspiration to build myself an arduino based 'scope but I want to be able to use an Android device (phone/tablet) for the UI.

source: Stack Exchange

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

sort: votes


text:
25Q128 flash and garbage data over SPI
I have a logic analyzer coming in the mail, but thought I might ask for help here first.
I soldered the 25Q128 flash onto an adapter and wired it up to an Arduino UNO clone as you can see in the images below. I get nonsense data in the serial monitor. The 4 10k resistors are connected in parallel to GND and there are 4.7k resistors on the SCK, MISO, MOSI and CS lines. I am using the TestFlash sketch from the SPIMemory Arduino library by Marzogh. Could it be a bad soldering joint? Or am I missing something?
I used this as a guide also:
https://www.14core.com/wiring-the-winbond-w25qxx-spi-serial-flash-memory-with-microcontroller/
https://www.14core.com/wp-content/uploads/2017/09/windbond-spi-flash-memory-W25Q80BV-8bit-storage-wiring-guide.jpg
Here are some pictures and a diagram.
Setup
Breadboard
Closeup
Arduino
Fritzing diagram

That "guide" is bad. You don't want any resistors on MISO. Just connect it direct between the Arduino and the chip.

You will be better to buy one of these from aliExpress.

here's de pinout connections to an arduino:

Pin 1 - CS

Pin 2 - D0 (I/O1)

Pin 3 - VCC (I/O2)

Pin 4 - GND

Pin 5 - Di

Pin 6 - CLK

Pin 7 - VCC (I/O)

Pin 8 - VCC

this connection setup does not make use of the full data parallel async I/O, as you can see only I/O1 is connected to D0. This way has much slower data transfers.

what is "pin 1"? Uno TX pin?

CS = chip select

I ask what are the pins on the left. Uno pins? you use the TX pin as CS?

you can use any digital pin for CS

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


text:
Controlling LEDs with bit bang method
I'm doing a research for RGB LED chips that MCU can control with one pin. I found this LED chip and it seems controlling LEDs is not as I've tought. I understand hardware part, software side is a problem.
In chip's datasheet, on page 6, you can find chapter four Data Transfer Format.
My questions are: Why D2 has only second 24 bit, third 24 bit while D3 has only third 24 bit and why D4 has no bits? What should I do when I'm done with "updating LEDs"?
I thought controlling LEDs can be done like this:

Lets say I have five LEDs to control. Every LED has Red, Green and Blue and every color is 8-bit. Five times three is 15 bytes array.
First three bytes in array are for last LED chip. While sending the data, highest bit(bit 7) will go first.
After first three bytes, MCU will stop for X microseconds. After delay, new three bytes will push old three bytes to second LED chip.
After MCU is done with sending data, it will leave data pin low.

Thanks!

first 24 bits are for the first LED chip .... each LED chip does the same thing ... after reset, it takes ownership of the first 24 bits of data arriving at its input pin and passes the rest of the bits to its output pin

This protocol looks an awful lot like the protocol of the WS2812 chips. There are libraries for driving those. Search for “Neopixel”.

@EdgarBonet Yes, but I want to make own lib for that since Neopixel and FastLED are too heavy for my needs.

You need to send the 5x24 bits out without a pause. If you then keep the line low for over 80us, that is interpreted by all LED drivers as the reset signal. It is not stated explicitly in the datasheet (at least I haven't found it), but I guess the reset signal means, that at that time all drivers will output the received values on the LEDs. That way you can light up all LEDs at the same time with their respective data.
The picture, that you refer to, explains the automatic data cascading. The first row is what you actually send from your microcontroller and also what is seen by the first LED driver in the row. That driver will then consume the first 24 bits, that it sees. After that, it will forward the rest of the data to the next LED driver. That will now consume the first 24 bits that it sees (thus the second 24 bits, that you have send). The third LED driver will do the same. But since in that example you only send data for 3 LEDs, no data is forwarded. Then the reset pulse happens and at some point in time you send a new set of data.
So each row represents, what the corresponding LED driver will see of the data, that you send. D1 sees all the data. Each following LED driver will see 24 bits less. D4 will see nothing, since you send only 3x24 bits in that example.

Why they using pause after every 3x24bits?

Because the example only has 3 LEDs. You do a pause, when you have send all the data, because a pause of more than 80us will set cause the LEDs to actually activate the values, that you send it. You can send how much data you like, but at the end you need to do a pause to actually output the data on the LEDs


text:
How to reset the count/data after HTTP.POST?
I have a project that records interrupts from a reed switch to nodemcu.
It records like this: 0.3,0.6,0.9,1.2 Then what I want to happen is to go back to zero when it successfully HTTP.POST to a webserver.
How can I do it? Thanks!
volatile float rainrate = 0.3;
volatile float total;

void count {
  total += rainrate;
}

So how do you set a variable to zero?

are micros() effective for this?

You are missing a lot of context on this question. Can you post the entire program?

Yea sorry, got it working already, after HTTP.POST, I put total = 0;

Try putting your total variable to 0, like this:
total = 0;
It should work like this.

yea got it already, btw thanks for answering :)


text:
arduino mega buzzer output
I have project by Arduino mega which have 22 inputs and 22 outputs and buzzer reset and output reset pushbuttons , it have two status

if the input is high(not continuous ) the output will on and the buzzer will be on, if  output reset pushbutton is pressed  the output will off , if buzzer reset pushbutton  is pressed the buzzer will off.
if the input is always high (continuous high signal on input ) the output will on and the buzzer will be on, in this case we will not reset the output even if the output  reset pushbutton is pressed , and we will be able to reset the(turn off) buzzer by the  buzzer reset pushbutton, and wait until  input state to change to high again to repeat procedure

help me with editing my code

    //int input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,23,24}; //input pins (23 for reset ,24 for buzzer reset)
//int output[] = {26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 24, 34, 44, 45, 46, 47, 48,49}; //output pins (49 for buzzer)

int in1 =     2;

int in25 =   26;// for output reset
int in26 =   27;// for buzzer reset

///////////////

int out1 = 28   ;

int out24= 51   ;
int out25= 52   ; // output for buzzer

////////////////////////////////////

int buttonState1 =  0;

int buttonState24 =  0;
int buttonState25 =  0; //for  reset
int buttonState26 =  0; //for buzzer reset

//unsigned long previousMillis = 0;        // will store last time buzzer was updated
//const long interval = 10000;           // interval at which to buzzer (milliseconds)
//int buzzerState = LOW;             // buzzerState used to set the buzzer

void setup() {

  pinMode(in1 , INPUT);

  pinMode(in24 , INPUT);
  pinMode(in25 , INPUT);
  pinMode(in26 , INPUT);

///////////////////////////

pinMode(out1, OUTPUT);
pinMode(out2, OUTPUT);

pinMode(out24, OUTPUT);
pinMode(out25, OUTPUT);

digitalWrite(out25, LOW); // buzzer LOW

}

void loop() {
  buttonState1 = digitalRead(in1);
  if (buttonState1 == HIGH) {
    digitalWrite(out1, LOW);
    //digitalWrite(out25, LOW);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState25 = digitalRead(in25); //read reset button state from input (25) pin 26
  if (buttonState25 == HIGH )

  {
    digitalWrite(out1, HIGH); //reset out1
    //digitalWrite(buzzer, LOW);
  }

  //else {
   // buttonState26 = digitalRead(in26); //read the buzzer reset button state from input (26)pin 27
   // if (buttonState26 == HIGH) {
    //  digitalWrite(out25, HIGH);

   // }
  //}

    //   while (digitalRead(input1) == HIGH);
    //digitalWrite(buzzerrelay, LOW);

    ////////////////////////////////////////////////////////////

 buttonState2 = digitalRead(in2);
  if (buttonState2 == HIGH) {
    digitalWrite(out2, LOW);
   // digitalWrite(out25, LOW);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState25 = digitalRead(in25); //read reset button state
  if (buttonState25 == HIGH )

  {
    digitalWrite(out2, HIGH); //reset the output
    //digitalWrite(buzzer, LOW);
  }

 // else {
  //  buttonState26 = digitalRead(in26); //read the buzzer reset button state
    //if (buttonState26 == HIGH) {
    //  digitalWrite(out25, HIGH);

    //}
 // }

   //////////////////////////////////////////////////////////////

  //  }
 // }

  }

your code is definitely overly repetitive ... why did you opt to not use arrays, such as the first two lines of your code, which you commented out? .... it is definitely simpler to use in[1], in[2], etc. because you can use a for loop to access the variables... you cannot use a loop for in1, in2, etc. so you are forced to repeat the same code multiple times

What is the problem with your code? Is it not working? If yes, please explain, what you expected and what it actually does

i have  tried to use arrays put they do not worked properly because i am new to Arduino and arrays , and now I'm focusing on solving buzzer problem

it is working put the buzzer part is not working ,,the problem that if the input is contentious the buzzer could not be reset and still ON until the input goes low after that i can reset the buzzer

You posted over 850 lines of code. It's unrealistic to expect your readers to review and post suggestions on that much code. You need to simplify and narrow your question, and provide a smaller example project that illustrates what you are struggling with.

i simplified the code ;)

couple of questions ... what is the difference between continuous high input and non-continuous high input ................... re. #2 if the input is continuously high, then how can you wait until input state to change to high again?

Any time you have the same sequence of code repeated over and over with slight variations, that is a "code smell" (an indication that you may be using the wrong approach.)
You should use arrays of pin numbers as you have in the first couple of commented-out lines, and write code that loops through those arrays, as well as functions that take parameters and can do the same thing using different values that are passed in.
Don't try to tackle a problem like this without learning the skills and concepts you need. You said "...I am new to Arduino and arrays , and now I'm focusing on solving buzzer problem." That is a mistake. Code like you have posted is hard to write, hard to read, and much harder to maintain.

Here is your code simplified. (untested)
Since the pins are sequential, you could calculate pin numbers, instead of using an array for pin number lookup.
For example, you could use a loop for (int i = 1; i < 25; i++) and first input pin would be referenced as i + 1 and first output pin would be referenced as i + 27.
// https://arduino.stackexchange.com/questions/80972/arduino-mega-buzzer-output

//  int in25 = 26;                           // for output reset
//  int in26 = 27;                           // for buzzer reset

//  int out25 = 52   ;                       // output for buzzer

//  int buttonState25 =  0;                  // for  reset
//  int buttonState26 =  0;                  // for buzzer reset

//  arrays are zero indexed (first element is at index zero)
//  array index      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26

    int in [27] = {255,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};   // input  pin numbers (26 for reset, 27 for buzzer reset)
    int out[26] = {255, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 24, 34, 44, 45, 46, 47, 48, 49, 50, 51, 52    };   // output pin numbers (52 for buzzer)

    int buttonState[27];

//  unsigned long previousMillis = 0;        // will store last time buzzer was updated
//  const long interval          = 10000;    // interval at which to buzzer (milliseconds)
//  int buzzerState              = LOW;      // buzzerState used to set the buzzer

    void setup() {

      for (int i = 1; i < 27; i++) { buttonState[i] = 0;      }       // clear states of buttons 1 to 26
      for (int i = 1; i < 26; i++) { pinMode(out[i], OUTPUT); }       // configure outputs 1 to 25

      digitalWrite(out[25], LOW);                                     // buzzer LOW

    }

    void loop() {

      for (int i = 1; i < 25; i++) {                                  // loop buttons 1 to 24

        buttonState[i] = digitalRead(in[i]);

        if (buttonState[i] == HIGH) {
          digitalWrite(out[i], LOW);
//        digitalWrite(out[25], LOW);
//        delay(10000);
//        digitalWrite(buzzer, LOW);
        }

        buttonState[25] = digitalRead(in[25]);       // read reset button state

        if (buttonState[25] == HIGH ) {
          digitalWrite(out[i], HIGH);                // reset the output
//        digitalWrite(buzzer, LOW);
        }

//      else {
//        buttonState[26] = digitalRead(in[26]);     // read the buzzer reset button state
//        if (buttonState[26] == HIGH) {
//          digitalWrite(out[25], HIGH);
//        }
//      }
      }
    }


text:
How to fix "expected primary-expression before '%' token" error code?
I'm trying to use this code to get temperature and humidity values from DHT11 sensor and send it to Python and I need to write the temperature and humidity values in the same line. But I keep getting the error code

expected primary-expression before '%' token

How can I fix this?
#include <dht.h>
#include <stdio.h>
int a = 0;
int b = 0;
char buffer [64];

dht DHT;

#define DHT11_PIN 7

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

void loop(){
  a = DHT.temperature;
  b = DHT.humidity;
  int chk = DHT.read11(DHT11_PIN);
  sprintf(buffer, %d %d, a, b);
  Serial.print(buffer);
  delay(1000);
}

The error mentioned a line number.  Did you look at that line?

You are missing quotes on the second parameter of sprintf:
sprintf(buffer, "%d %d", a, b);

please don't answer syntax error questions. they are off-topic


text:
I'm making a trim wheel using a rotary encoder for flight simulation. Should I have the Joystick library use button presses or make it an axis?
Title says the majority of it. I'm looking to make a trim wheel for flight sim using a rotary encoder, the Joystick library and an Arduino Leonardo. I wasn't sure if it would be better to make it a button press or have it be an axis, possibly the Rx, Ry, or Rz axis.
Thanks in advance!

are you not the one that knows what you want?

As you build that project, it is up to you to decide, wether you want to control trim via a joystick or button presses.

@jsotola I had an idea of what I thought would be best, but I wasn't sure if anyone thought differently. Thanks though!

@chrisl I had an idea of what I though would be best, but I wasn't sure if anyone thought differently. Thanks though!

what I thought would be best ... yes, it is your job to define what best means ... nobody else can tell you what is good for you ... and nobody else's opinion is relevant unless you ask a technical question


text:
End stops for stepper motor
I need to add some end stops to this stepper motor code. I'm using one axis of a joystick to control a carriage that goes back and forth on a long screw. I have hall switches for both ends, I just want it to stop going in that direction when it triggers the switch.
I didn't write this code but it would work great if I could just add the end stops. If I have the switches connected to pins 2 and 3.
How could I write something like: if pin 2 goes high, stop motor in that direction, and then the same for pin 3 in the opposite direction?
#include <AccelStepper.h> // accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)

//Pins
const byte Analog_X_pin = A0; // x-axis readings
const byte enablePin = 7;

//Variables
int Analog_X = 0;             //x-axis value
int Analog_X_AVG = 0;         //x-axis value average
  //----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  //----------------------------------------------------------------------------
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------
  InitialValues(); // averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------
  // Stepper parameters
  // setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000);     //SPEED = Steps / second
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
  stepper.setSpeed(1000);
  delay(1000);
}

void loop() {
  ReadAnalog();
  stepper.runSpeed(); // step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadAnalog() {
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    digitalWrite(enablePin, HIGH);  // enable the driver
    stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
  } else {
    digitalWrite(enablePin, LOW);   // disable the driver
    stepper.setSpeed(0);
  }
  // Reading the potentiometer in the joystick:
  Analog_X = analogRead(Analog_X_pin);
  // if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  // This is a sort of a filter for the inaccuracy of the reading
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    stepper.setSpeed(5 * (Analog_X-Analog_X_AVG));
  } else {
    stepper.setSpeed(0);
  }
}

void InitialValues() {
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------
  // read the analog 50x, then calculate an average.
  // they will be the reference values
  for (int i = 0; i<50; i++) {
    tempX += analogRead(Analog_X_pin);
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------
  Analog_X_AVG = tempX/50;
  //----------------------------------------------------------------------------
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");
}

This is what I came up with. Note that the ReadLimits function is called after ReadAnalog and before runSpeed. In that order the stepper will not move in the direction of the limit switch, if it is pressed.
PS since you used setAcceleration, don't you need to call run instead of runSpeed?
void loop()
{
  ReadAnalog();
  ReadLimits();
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

edit to avoid some confusion; here is the entire code with my suggestion embedded:
#include <AccelStepper.h> // accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)

//Pins
const byte Analog_X_pin = A0; // x-axis readings
const byte enablePin = 7;

//Variables
int Analog_X = 0;             //x-axis value
int Analog_X_AVG = 0;         //x-axis value average
  //----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  //----------------------------------------------------------------------------
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------
  InitialValues(); // averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------
  // Stepper parameters
  // setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000);     //SPEED = Steps / second
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
  stepper.setSpeed(1000);
  delay(1000);
}

void loop()
{
  ReadAnalog();
  ReadLimits();
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

void ReadAnalog() {
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    digitalWrite(enablePin, HIGH);  // enable the driver
    stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
  } else {
    digitalWrite(enablePin, LOW);   // disable the driver
    stepper.setSpeed(0);
  }
  // Reading the potentiometer in the joystick:
  Analog_X = analogRead(Analog_X_pin);
  // if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  // This is a sort of a filter for the inaccuracy of the reading
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    stepper.setSpeed(5 * (Analog_X-Analog_X_AVG));
  } else {
    stepper.setSpeed(0);
  }
}

void InitialValues() {
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------
  // read the analog 50x, then calculate an average.
  // they will be the reference values
  for (int i = 0; i<50; i++) {
    tempX += analogRead(Analog_X_pin);
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------
  Analog_X_AVG = tempX/50;
  //----------------------------------------------------------------------------
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");
}

Thanks for responding, I tried what you sent, if I touch either pin 2 or 3 to gnd. or 5V still nothing happens the motor doesn't stop in either direction. I don't know much about coding, I tried to hire someone to do it and after 2 days of trouble shooting and revising the code it still doesn't work. The code works perfectly except I can't seam to add the end stops. Any help would be greatly appreciated.

Have you added pull-up resistors, or used pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP);?

Why did you add ReadAnalog();  stepper.runSpeed(); at the end of the ReadLimits function I provided?

See my edit above.

I think that's it, if I have pins 2 and 4 connected to 5v it runs normally, when I connect the jumper wire to gnd instead or + it stops the motor in that direction. Forgive me I really don't know what I'm doing when it comes to this stuff. So I have hall switches for the stops do I include pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); or do I need pullup resistors? if so what value please? I am very grateful for your help maybe now I can finish this.

Got it, added input pull ups works perfectly,

It depends on the hall effect sensors. Some require a pull-up resistor. INPUT_PULLUP enables the pull-up resistor that's inside the Arduino chip. There is no difference between enabling this pull-up resistor in software, or having a physical (35kOhm) pull-up resistor on the pin. The value of the resistor doesn't really matter in this case.


text:
Setting a fixed receiver frequency RDA5807m
I am using the receiver RDA5807m, but I do NOT need to switch the frequency and other parameters during operation.

I noticed that the module continues to work when the programming pins are disconnected during its operation, that is, it remembers the settings until the supply voltage is removed.
Therefore, I want to set the frequency and volume at the beginning of work, so as not to occupy the resources of the microcontroller, but I just understand the registers. Tell me how to write code, the simplest of all possible configurations for this purpose.
Now I am using the following sketch, it works, but it takes a lot of resources, and I don't need it. Help simplify it and free it if possible "void loop()"
#include <Wire.h>

#define RDA5807M_RANDOM_ACCESS_ADDRESS 0x11
// registers
#define RDA5807M_REG_CONFIG 0x02
#define RDA5807M_REG_TUNING 0x03
#define RDA5807M_REG_VOLUME 0x05
#define RDA5807M_REG_RSSI   0x0B
// flags
#define RDA5807M_FLG_DHIZ 0x8000
#define RDA5807M_FLG_DMUTE 0x4000
#define RDA5807M_FLG_BASS 0x1000
#define RDA5807M_FLG_ENABLE word(0x0001)
#define RDA5807M_FLG_TUNE word(0x0010)
//masks
#define RDA5807M_CHAN_MASK 0xFFC0
#define RDA5807M_CHAN_SHIFT 6
#define RDA5807M_VOLUME_MASK word(0x000F)
#define RDA5807M_VOLUME_SHIFT 0
#define RDA5807M_RSSI_MASK 0xFE00
#define RDA5807M_RSSI_SHIFT 9

uint8_t volume = 15; // 0..15
uint16_t freq = 1073; // 107.3FM
uint16_t reg02h, reg03h, reg05h, reg0Bh;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  // Register 02h - enable, settings
  reg02h = RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE;
  setRegister(RDA5807M_REG_CONFIG, reg02h);

  // And then we decided to further strengthen the bass:
  reg02h |= RDA5807M_FLG_BASS;
  setRegister(RDA5807M_REG_CONFIG, reg02h);

  // Register 03h - radio station selection
  // After reset in register 03h, the default value is 0
  // Thus BAND = 00 (87..108MHz), STEP = 00 (100kHz). Let's leave them as they are
  reg03h = (freq - 870) << RDA5807M_CHAN_SHIFT; // chan = (freq - band) / space
  setRegister(RDA5807M_REG_TUNING, reg03h | RDA5807M_FLG_TUNE);

  // Register 05h. Set the volume, do not change the rest of the beats
  reg05h = getRegister(RDA5807M_REG_VOLUME); // read the current value
  reg05h &= ~RDA5807M_VOLUME_MASK; // Resetting the VOLUME bits
  reg05h |= volume << RDA5807M_VOLUME_SHIFT; // Set a new volume
  setRegister(RDA5807M_REG_VOLUME, reg05h);
}

void loop() {
  // Register 0Bh - status
  reg0Bh = getRegister(RDA5807M_REG_RSSI);
  uint8_t RSSI = (reg0Bh & RDA5807M_RSSI_MASK) >> RDA5807M_RSSI_SHIFT;
  Serial.print("RSSI = ");
  Serial.print(RSSI);
  Serial.println(" (0-min, 127-max)");
  delay(500);
}

void setRegister(uint8_t reg, const uint16_t value) {
  Wire.beginTransmission(0x11);
  Wire.write(reg);
  Wire.write(highByte(value));
  Wire.write(lowByte(value));
  Wire.endTransmission(true);
}

uint16_t getRegister(uint8_t reg) {
  uint16_t result;
  Wire.beginTransmission(RDA5807M_RANDOM_ACCESS_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(0x11, 2, true);
  result = (uint16_t)Wire.read() << 8;
  result |= Wire.read();
  return result;
}

I found a really short sketch that allows you to set the frequency. It remains to set the volume in the same way.
#include <Wire.h>
float f = 104.7;

void setFrequency(float frequency)
{
  unsigned int frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;
  byte frequencyH = frequencyB >>8;
  byte frequencyL = frequencyB & 0XFF;
  Wire.beginTransmission(0X60);
  Wire.write(frequencyH);
  Wire.write(frequencyL);
  Wire.write(0xB0);
  Wire.write(0x10);
  Wire.write(0x00);
  Wire.endTransmission();
}

void setup() {
  Wire.begin();
  setFrequency(f);
}

void loop()
{
}

What resources do you mean? RAM? Flash? Computing time? I don't see anything, that seems really bad here

I do not need the receiver to interfere with the microcontroller during operation. I noticed a significant slowdown in other code when I use it in conjunction with this code. So I need to keep the program as simple as possible

Without seeing the complete code, that slows down, I cannot be sure. But in the code above the biggest slowdown is the delay. You should not use any delay calls. Also: do you really need to read the RSSI continuously? If not, then just don't do it.

It seems to me, that you want to optimize for code length (not size). If you compare the two codes in your question, you see two things: The second code does less things (setting only one register instead of 4) and it doesn't use any defines. The first one is the easiest to optimize (only do things, that you need to do). The second one is an antipattern (meaning not a good coding practice). The code uses hexadecimal values without any description. Defines can give these values names without taking up any extra space in the final program (since they are substituted before compilation)

And the second codes does nothing in loop, which is the same principle as my first point

I just need it to do nothing in the loop!

If you didn't know how to do nothing in loop prior to this question, please write your own answer. I still don't really know, what your actual question was, so maybe an answer from you would enlighten me

I need to set the frequency and volume once; I don't need to change them during operation. As I understand it, I just need to remove everything from the loop of the first given program. Since I did not create it myself, but took it ready, so there is a lot of unnecessary things.


text:
Atmega328 and ADXL335 - is the right choice for vibration analysis?
I'm planning to use the ATMEGA328 and the ADXL335 accelerometer to monitor the bearing and gears vibration of a industrial extractor that works at maximum speed of 3000rpm at 380VAC - 50Hz .
The main scope of this monitoring is to get continuously the vibration readings and apply the FFT transform in order to identify if there is something that is not running well.
My primary concerns are regarding the sampling speed of the ATMEGA328P: i've tried to identify the needed sampling speed but i'm a little bit confused about the relation of motor/gear speed and the ADC sampling speed of the ATMEGA...also, the ADXL is the right choice?

According to nyquist-shannon you have to sample at 2x your maximum interesting frequency. That's probably the same as your max RPM, so 6000sps. You need to take 6000 readings per second from the ADXL, and if you want all three axes that's 18,000sps (if you want the values concurrently). The Arduino can (from a quick google) manage about 9615sps.

You could just about manage 1 axis with that. You could cycle through the three axes and take a sample block from each one and FFT it in turn I guess.

However, the ADXL335 can only go up to 1600Hz, so won't be able to get anywhere near your needed sample frequencies. You may be better thinking about audio instead of vibration.

I would say that depends on how you identify that "something is not running well". What frequencies do you expect to find then. Did you some research?  Also, the ADXL335 is a device with radiometric analog output with negative voltages. Did you plan how to read that with a arduino?

And, where do perform the FFT? On the Arduino? ;-)

Actually the ADXL is only one candidate sensor, something like that may be better: https://www.pcb.com/products?m=639a91

@PeterPaulKiefer, my initial purpouse is to get the "vibration fingerprint" when the extractor is okay and works well and then monitor it during time and correlate the result of the frequency analysis with the typical frequency fingerprint of the monitored components (bearings, for example)

I fear the arduino approach is not the best, as long as you are fishing in the dark. You don't know what frequencies (fingerprints) you should expect. For research purposes you should use equipement with a wider and deeper view into the domain. Let's say an error leads to overtone frequencies of 23.000 HZ. Then none of the sensors you mentioned would suffice the pcb one would even get in resonance. And the arduino would be out of the race. Finding out what you need means finding the condition you have to search for. You may find some research results. Standing on the shoulders of giants. ;-)

@Majenko, the ATmega328 can sample up to 50Ksps by speeding up the ADC at the cost of slightly reduced resolution. I do it in my library in this switch case here: https://github.com/ElectricRCAircraftGuy/eRCaGuy_analogReadXXbit/blob/Version_2/eRCaGuy_NewAnalogRead.cpp#L66. 50ksps is kind of the "sweet spot" where you get 5x faster than normal sampling speed with very little loss in resolution. You can sample faster still by further speeding up the ADC ckock, but resolution losses increase more and more, eventually down to something like 7 bits vs the Arduino's default 10 bits.

For anyone wondering about how analog sampling can affect the voltage on the line being sampled, when sampling too fast, see my answer here under the section I titled "Which ADC sampling time should I choose?", near the end of my answer.

Gabriel, about the sensor and the desired measurements, you have some advices to give?

@Symon, can you post a link to the ADXL datasheet? I don't know anything about it. As for sample rate, any sample rate > 2x the maximum vibrational frequencies you care about it enough to do post analysis FFT, as Nyquist says. So, what vibrational frequencies do you care about? If the ADXL is analog, the fastest you can do a single channel ADC sampling in the ATmega328 is about 10kHz by default or about 50kHz if you speed up the ADC clock. If the ADXL is digital, it's different. You also have to consider how you will log or transmit the data stream live.

Lastly, you may need to set up the ADC to do jitter free continuous sampling rather than blocking sampling which is the Arduino default when you call analogRead(). I'm sure @nickgammon has some examples of this (jitter free continuous sampling) on his website. The low level details will all be in the ATmega328 datasheet, but expect to read it for days to understand it, and get an experienced embedded systems developer to walk you through it for an hr or two to start.

@Symon, I left an answer. Please remember to always leave purchase links, datasheet links, etc, for any specific device you are asking about in the future. Hopefully my answer sheds some light on the situation. A sound card could potentially be a great way to go, as they are designed to sample up to the hundreds of kilohertz usually, to sample high-quality voice, music, and audio.

Thanks for the support @GabrielStaples, for completeness, this is the sensor that i've picked: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl335.pdf

My primary concerns are regarding the sampling speed of the ATMEGA328P

The ATmega328 can sample up to ~10ksps (kilo-samples-per-second) in normal configuration and at 10-bit ADC resolution, or reliably and with good (near 10-bit) resolution up to ~50ksps if you speed up the ADC clock. You can get even faster if you want to sacrifice a lot on sample resolution, but at faster speeds this processor is too slow to even reliably grab the data and transmit it or store it, so you should go to a much much beefier and better microcontroller, such as a 32-bit Arduino Zero, Portenta, or non-Arduino STM32 or something.
Example of speeding up the ATmega328 to sample up to ~50kHz:
See my library here, and my initial article on it here.
#include <eRCaGuy_NewAnalogRead.h>

void setup()
{
    adc.setADCSpeed(ADC_FAST); // now analogRead() will operate up to ~50 kHz
}

void loop()
{
    // these readings can now be done up to ~50 kHz
    uint16_t reading = analogRead(A3);
}

I don't remember the exact details of configuring the ADC clock, but it's all in the ATmega328 datasheet, and in my code--which you can study at the library link above, and you can look at Nick Gammon's website on it here: https://www.gammon.com.au/adc.
How fast do you need to sample? Only you can answer that question.
Perhaps you read some academic paper that says that vibrations of 102kHz on a 5cm diameter motor made of material X can cause microfractures in the material if exposed for 100 hours. Well, in this case, you need to sample at at least 204kHz (2x the frequency of interest) to see if 102kHz vibrations exist.
Or, perhaps you just want to use FFT to determine the RPMs of the motor since it will almost certainly have a dominating frequency at its rotational frequency due to imperfect balance of the motor. In that case, sampling at 2x the max RPM (but in samples per second, not minute) is sufficient. You stated a max rotational speed of 3000 RPM, so that's 3000 rot/min x 1 min/60 sec = 50 Hz. To detect your RPM, therefore, by sampling vibration, you need to sample at least 2x as fast as this, or 100 Hz or higher.
Remember, this is all Nyquist frequency stuff. All that the Nyquist frequency says is [in my own words]:

you can only detect a frequency up to 1/2 as high as your sampling rate

...or otherwise stated [in my own words]:

you must sample at 2x whatever frequency it is you are trying to measure

Any sample rate lower than this, and you get aliasing and it is mathematically and physically impossible to determine if a higher frequency exists. Any frequencies higher than 1/2x your sample rate which appear to exist in your FFT analysis must be thrown out, as they are invalid.
So, what max vibrational frequency do you need to measure? That's for you to find out. If you're looking to find gear tooth wear (ex: a broken, cracked, or missing gear tooth), you can come up with some estimations based on number of teeth per rotation, and knowing your motor's max rotational speed in rotations per second.
Example: assuming 32 teeth per revolution, you will be rotating at 3000 rot/min / 60 sec/min = 50 rot/sec x 32 teeth/rot = 1600 teeth/sec. But, to identify a broken tooth maybe you need to do a waveform analysis of the shape of the wave over that broken tooth, so you should sample at 5x to 10x that rate, or perhaps 1600 teeth/sec x 10 samples/tooth = 16000 samples/sec = 16 kSps. But...5 samples per tooth might be enough, or only 8 kSps...
See how some of this analysis might work? You have to figure out what it is you're trying to figure out, and sample accordingly. If you don't know what you're trying to figure out, just sample as fast as you can and then with that data try to see what you can figure out from what you just sampled! Such are the ways of engineering and curious minds! :)

With that being said, assuming you use my library's adc.setADCSpeed(ADC_FAST); trick, you can sample 1 channel up to 50kHz or 3 channels up to 50/3 = ~16kHz, meaning the max vibrational frequency you can detect with FFT for 3 channels is ~8kHz with an ATmega328. Is that enough?
BUT, you will have jitter problems unless you put the ADC into continuous sample mode at a fixed interval, and you cannot sample all 3 channels at once, so there will naturally be an offset between them all, as they happen in sequence one after the other.

How fast can the ADXL335 sample? (ie: what's its "bandwidth", or frequency response?)
As for the ADXL335, its datasheet reveals it to be an analog 3-axis accelerometer, not a digital one, so you are limited by:

how fast the ADC you have on your microcontroller can sample the sensor (we already came up with ~16khz (kSps)/channel, for 3 channels, above) and
what the ADXL335's bandwidth, or max frequency response, is.

The datasheet (see image below) says you get a bandwidth of 0.5 Hz to 1600 Hz for the X and Y axes, and 0.5 Hz to 550 Hz for the Z axis, all depending on the chosen bypass capacitors, cx, cy, and cz you choose for it. See the image and highlighting below.

Bandwidth means simply [in my own words]:

Bandwidth is the maximum frequency at which a device can respond to changes in the thing is it measuring (ex: an accelerometer to changes in acceleration).

By definition, a bandwidth for a low-pass filter, or a sensor responding to a high-frequency input, is equal to the frequency at which point the measurement of the thing being measured is attenuated by 3 db, or in other words, is 1/sqrt(2) = 0.707 times as big as the actual thing being measured. So, if the bandwidth of an accelerometer is 50 Hz, then that means if it tries to measure a 50 Hz vibration, then the measurement it outputs at that frequency is attenuated to 0.707x as large as the actual amplitude of that vibration. Therefore, it is said that this sensor cannot be reliably used to measure higher frequencies than this. Note that since Power = V^2/R, and the 0.707 rule applies to voltage, the attenuation is 0.707^2 = 0.5 for power.
If you bought your ADXL335 sensor from Adafruit here for $15 (https://www.adafruit.com/product/163), they state:

The XYZ filter capacitors are 0.1uF for a 50 Hz bandwidth

...which means they chose capacitors to give it a 50 Hz bandwidth, or frequency response. This means the sensor is limited to reliably measuring vibrations only up to 50Hz. You should sample at least 2x this bandwidth then in order to adequately capture frequencies up to that value, again, based on Nyquist. This means for this Adafruit version of the device and with these chosen bypass capacitors you can sample at 100 Hz or higher to detect vibrations up to 50 Hz (that's Hertz, not kiloHertz!). Even if you sample much much faster, the maximum reliable frequency this device can measure is only up to 50 Hz before attenuation of its measurements becomes a significant concern. Whether sampling at 100 Hz or 1000 Hz, the frequency this sensor can measure, in this configuration, is only up to 50 Hz, which is only 50/sec x 60sec/min = 3000 RPM if your goal is to just detect the rotational frequency, but not any higher-frequency vibrating modes, for your device.
A 50 Hz bandwidth (max frequency response), FYI, is optimized to reduce sample noise for handheld tilt-based game controllers, as it intentionally attenuates any frequencies above 50 Hz, and 50 Hz input from a human is a good expectation for human control signals. You might sample this sensor for such a game controller anywhere from 50 Hz to 1 KHz, but again, it can't detect vibrations any faster than about 50 Hz. So, the Adafruit version of the ADXL335 is optimized to be used to make home-made tilt-based hand controllers for games, toys, smart devices, radio control devices, etc.
Extra note on sampling frequency
Even though the Nyquist frequency says you only need to sample 2x the frequency of interest to detect the frequency of interest through FFT or similar, you need to realize that if you ever want to plot a given signal or inspect its shape or waveform, you should sample at least 5x to 10x as fast as the frequency of the signal you are trying to record and inspect.
This is how oscilloscopes are rated. A "100 Mhz" bandwidth oscilloscope will have a sample rate of at least 5x to 10x that, or 500 MSps (Mega-samples-per-second) to 1 GSps (Giga-samples-per-second). This makes sense because the purpose of an oscilloscope is to plot waveform shapes, and that requires at least 5 to 10 points per period, or 5x to 10x the sample rate of the rated bandwidth in order to display a reasonably-nice picture of the waveform.
For pure FFT or frequency analysis, where you just want to know the frequency of the thing being measured, but don't need to know how the waveform looks, a sample rate exactly 2x or higher than the frequency of the thing being measured is physically and mathematically sufficient.

Thanks Gabriel, this is one of the most complete answer that everyone gave me in my entire life! have a good day man! thanks!
Now, the only remaining question is: looking at commercial MEMS sensors, you have some recommendations about where i need to point in order to sample also higher frequencies...maybe this sensor is the right choice: http://static6.arrow.com/aropdfconversion/c9b572888f3b1329b19ec85b0ef62a2d2c923af5/adcmxl3021.pdf

@Symon, yeah, that looks like a great sensor! It is a digital sensor with its own built-in ADC up to 220 kSps, FIR filters, internal FFT capability, etc. I see a it uses CS (Chip Select), SCLK (Serial Clock), DIN (Data In--MOSI (Master Out Slave In)), DOUT (Data Out--MISO (Master In Slave Out) pins, meaning it communicates over SPI. You'll have to figure out how to do that. Will be a learning curve for sure, but absolutely, go get one and get to it!

First of all, 3000 RPM is only 50 Hz, so sampling is not a problem for the fundamental frequency.  But you usually want to see harmonics, to pick up gear tooth issues, etc.
I suggest using my Daqarta software with a sound card to do your initial testing.  It already does everything you need, including waveform, spectrum, and spectrogram displays plus a lot more.  You can use it free for 30 sessions or 30 days, then the sound card inputs are no longer supported.  By that time you should have a good idea about what you need.  As it turns out, Daqarta also supports Arduino, and that does not end with the trial period.  So you may be able to do everything with an Arduino, for free.  The Daqarta site also has a contact page, and I am glad to answer questions and provide specific help for any issues that arise.  That include free users.


text:
How to put a condition on HTTP.POST?
I set my code to if it executes HTTP.POST, the count will reset / back to zero, but I noticed that even it returns other http code than 201 (-1 or 500), the count still resets.
How to put a condition here that if httpResponseCode = 201 (successful), then reset (total = 0;) else http.end().
Thanks!
void loop () {
  if ((millis() - lastTime) > timerDelay) {
    if (WiFi.status() == WL_CONNECTED) {
      HTTPClient http;
      http.begin(serverName);

      http.addHeader("Content-Type", "application/json");
      char temp[32];
      snprintf(temp, 32, "{\"amount\":\"%.2f\"}", total);
      int httpResponseCode = http.POST(temp);

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
      Serial.println(total);
      total = 0;

      http.end();
    }

void count () {
  total += rainrate;
}

You mean something like this?
if( httpResponseCode==201 )
  total = 0;

Your entire code would then become:
void loop () {

  if ((millis() - lastTime) > timerDelay) {

    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      http.begin(serverName);

      http.addHeader("Content-Type", "application/json");

      char temp[32];
      snprintf(temp, 32, "{\"amount\":\"%.2f\"}", total);
      int httpResponseCode = http.POST(temp);

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
      Serial.println(total);

      if( httpResponseCode==201 )
        total = 0;

      http.end();
    }

void count () {
 total += rainrate;
}

I'm trying that earlier, I'm just missing == lol. btw Thank you! :)

@Giddsec That's a mistake I still occasionally make. Glad you got it working now. Cheers.


text:
Problem with a function having a parameter with a default value
I've got a problem using a default value for a function parameter.
This code gives "'blink' was not declared in this scope":
void loop(void) {
  blink(12, 2, 1000);
}

void blink(const uint8_t led, int num, const uint16_t l = 12) {
  Serial.println(led);
  Serial.println(num);
  Serial.println(l);
}

but it works if I don't assign a default value to the "l" arg:
void blink(const uint8_t led, int num, const uint16_t l) {

or if I put the blink function before the loop:
void blink(const uint8_t led, int num, const uint16_t l = 12) {
  Serial.println(led);
  Serial.println(num);
  Serial.println(l);
}

void loop(void) {
  blink(12, 2, 1000);
}

only a function declaration can have a default parameter value. not the definition. so you have to add a forward declaration if you want to set default parameter values.

Confusing the code mangler that sits between your IDE code and the GCC code it generates is a sure way to get oddball errors.

It's just a failing of the Arduino build process to generate prototypes (function declarations) for functions that have default argument values.  There's otherwise nothing wrong with what you're doing.  Not in my opinion anyway.  The build process sometimes chokes on function or class templates as well.  The answer to these sorts of problems is probably that these features are not considered part of the Arduino "language".
Just a reminder: In C++ a function declaration needs to have been seen in order to generate a call to it.  A definition will serve as a declaration.  In either case, one must have been seen before the call site.  Generating declarations where needed is, perhaps, the greater part of what the Arduino build process does that can be said to make the Arduino "language" different from plain C++.
The following were generated by working out of /tmp/default-param with the "input" being default-param.ino, running:
arduino-cli -b arduino:avr:uno build --build-path /tmp/build

and inspecting /tmp/build/sketch/default-param.ino.cpp which I'm calling "output".  You can use the same process if you want to see exactly what the build process is doing to your code.
Non-default argument
This input:
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

generates:
#include <Arduino.h>
#line 1 "/tmp/default-param/default-param.ino"
#line 1 "/tmp/default-param/default-param.ino"
void setup();
#line 4 "/tmp/default-param/default-param.ino"
void loop();
#line 5 "/tmp/default-param/default-param.ino"
void func(int xyzzy);
#line 1 "/tmp/default-param/default-param.ino"
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

The build process has inserted a valid C++ function declaration prior to the call site, so the compiler is happy.
With default argument
But this input:
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy = 7) {}

generates:
#include <Arduino.h>
#line 1 "/tmp/default-param/default-param.ino"
#line 1 "/tmp/default-param/default-param.ino"
void setup();
#line 4 "/tmp/default-param/default-param.ino"
void loop();
#line 1 "/tmp/default-param/default-param.ino"
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy = 7) {}

No declaration prior to the call site this time, so the compiler is not happy with this generated code.
Build process
The build process is a rather ugly... process... that scrapes the output of the compiler and generated ctags to build include paths and to try to generate forward references for things.  Sometimes, it just gets it wrong.  I'm not sure what the exact error is in the build process, but it is probably just a failure to match the error caused by calling an undeclared function with its matching entry in the ctags.  You can try reading through the build process documentation to make sense of this.  Ultimately though, you may have to read the source to arduino-cli/arduino-builder to get to exact cause.
Non-.ino (and non-.pde) files more or less go through the build process unscathed.  So, if you really want default arguments, you can make use of and .h file for your function prototype/declaration and a .cpp file for its body and follow the normal rules of C++.
Using your own declaration
You can just make your own declaration for it.  Doing so makes it not detect an error on that line.
void func(int xyzzy = 7);

void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

Output:
#include <Arduino.h>
#line 1 "/tmp/default-param/default-param.ino"
void func(int xyzzy = 7);

#line 3 "/tmp/default-param/default-param.ino"
void setup();
#line 6 "/tmp/default-param/default-param.ino"
void loop();
#line 7 "/tmp/default-param/default-param.ino"
void func(int xyzzy);
#line 3 "/tmp/default-param/default-param.ino"
void setup() {
    func(11);
}
void loop() {}
void func(int xyzzy) {}

As you can see it generates a proto type for whatever reason.  But not one that conflicts with your own.

It is probably better if you want to make use of default arguments to just use headers and .cpp file for those functions that have them so that you're not subject to changes in the ability of arudino-cli/arduino-builder to handle them.

Solution is buried in answer: "You can just make your own declaration for it". Suggestion: move to top, or add a TLDR at top.

Probably when I wrote this I took the "or if I put the blink function before the loop" to mean that they already had a solution and were wondering about why, so the TLDR is more of a why-TLDR "It's just a failing of the Arduino build process to generate prototypes" rather than a how-TLDR. They weren't explicit in asking so both are covered. If you're saying you found this helpful but didn't like reading as far, sure, I'll see if I can't address the how part sooner also.

If you use a function after you call it in the same file, you have to (or at least it is better) to add a so called 'forward declaration' before calling it. The best place is before the first function, and in your case it should look like:
void blink(const uint8_t led, int num, const uint16_t l);

You can omit the = 12 or not.

Normaly this is done by the Arduino IDE, and when I don't put a default value "blink" can be define after the "loop" function, without a 'forward declaration' before calling it.
I don't understand why this problem error exist only with default parameter.

The reason behind it probably can better be asked in StackOverflow.


text:
Weird char on a 20X4 LCD
I'm trying to make an RC controller.
I have a problem with my LCD.

I have already double-checked the wiring and the connections are great.
I made a PCB with Kicad and order it to JLCPCB. I have some mistake, you can see the soldered wire.

Before the PCB, I did my project with a breadboard and it worked fine.
const String menuElem[4] = {"Models", "Trims", "Reverse command", "Channel"};

const int rs = 3, en = 4, d4 = 5, d5 = 6, d6 = 7, d7 = 8;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void menu() {
  lcd.clear();
  //lcd.setCursor(0,0);
  //byte pos = 0;
  //int sizeOfanArray = *(&array + 1) - array;
  byte menuElemLength = *(&menuElem + 1) - menuElem;
  for (byte i = 0; i < menuElemLength; i++) {
    lcd.setCursor(2, i);
    lcd.println(menuElem[i]);
  }
  showMenuNav(currentMenuPos);
}

try const char* menuElem[4] = {"Models", "Trims", "Reverse command", "Channel"};

The pictures of your custom board and wiring job don't really tell us anything. It looks to me like you have a bug in your code. You're getting SOME characters from your strings, which tells me that the LCD is working. It looks to me like your strings are being sent with the wrong lengths.

Thank you @Juraj it solves the problem. I understand my mistake. I replaced String by char* in my code and in every class. I use strcat to concatenate my char* but I don't know if this is the best solution.
@DuncanC Yes, at start i believed that I have bad connection or something like that.

Your code to calculate the length of your Strings does not make sense. The String type is an object type. The addresses of your String objects will not match the length of the charcters in those strings. You should use an array of C strings as suggested by Juraj, and then you should use strlen() to get the length of those strings (C strings have a null terminating byte, and strlen() uses that null to calculate the length. Note that C strings can't handle Unicode.)
The String type is best avoided on Arduino anyway, as String objects tend to fragment the extremely limited heap memory on Arduino devices and cause out-of-memory crashes.

Yes, my mistake is to use a String object like a char* pointer.
I would use ``char*pointer instead ofString` object in my future code.
Thank you for your reply!


text:
OTA update - sodaq board (arduino M0 compatible)
I am trying to perform a firmware update from an SD card, on a Sodaq Sara AFF board. If i use the SDU.h library in my sketch, it fails the board check. See this link please.
I have edited the SDU.cpp myself to force the selection of ARDUINO_SAM_ZERO. It is now :
__attribute__ ((section(".sketch_boot")))
unsigned char sduBoot[0x6000] = {
  #include "boot/mzero.h"
};

I have increased the size to 6000 otherwise it was complaining too many initializers.
I also have changed the SD_SS_PIN to match my pin on the SDUboot.ino, under extras. Afterwards, i recompiled it with build.sh in the same folder.
But I am unable to perform the firmware update. After power cycling the board (original code: the blink example, target update: blink with a faster rate) - the original firmware remains.
I exported the firmware using arduino IDE -> export compiled bynary, and tested both versions with and without bootloader.
Any help would be appreciated.

what bootloader has the board? the difference between MKR/Zero and M0 is for SDU the bootloader size which is 2kB for MKR and Zero and 4 kB for M0. why do you want to use SDU? is your sketch larger then half of the flash?

@Juraj the board has a ATSAMD21J18, 32-Bit ARM Cortex M0+. So, I assume 4 kB bootloader size. Is it relevant if the sketch is larger then half of the flash?

Zero and M0 are both SAMD21 but have different bootloaders. the sketch binary doesn't have to be smaller then half of the flash if it is loaded from SD card

https://github.com/arduino/ArduinoCore-samd/pull/344/commits

And what does it mean finally? What is the correct setup to get it work?

@phlegx, the correct way is create .h for SDU library matching pins of the board and this sketch encoded in .h must know the correct bootloader size. it the boards package is not Arduino SAMD but some third party, the it must be modified as the PR in my previous comment

SOLVED!
I have compiled my own SDUBoot.ino with fixed SDU_START 0x2000 and for SODAQ Sara (boot/sodaq_sara.h). My sketch with #include "SDU.h" compiles successfully. The board package is also installed in Arduino (http://downloads.sodaq.net/package_sodaq_samd_index.json). Here my code with changes (base is SodaqCore-samd-1.8.6-sodaq from Github):
File libraries/SDU/extras/SDUBoot/SDUBoot.ino:
#include <SD.h>
#include <FlashStorage.h>

#define SDU_START    0x2000
#define SDU_SIZE     0x4000

#define SKETCH_START (uint32_t*)(SDU_START + SDU_SIZE)

#ifndef SDCARD_SS_PIN
#define SDCARD_SS_PIN 10
#endif

#define UPDATE_FILE "UPDATE.BIN"

FlashClass flash;

// Initialize C library
extern "C" void __libc_init_array(void);

int main() {
  init();

  __libc_init_array();

  delay(1);

  if (SD.begin(SDCARD_SS_PIN) && SD.exists(UPDATE_FILE)) {
    File updateFile = SD.open(UPDATE_FILE);
    uint32_t updateSize = updateFile.size();
    bool updateFlashed = false;

    if (updateSize > SDU_SIZE) {
      // skip the SDU section
      updateFile.seek(SDU_SIZE);
      updateSize -= SDU_SIZE;

      uint32_t flashAddress = (uint32_t)SKETCH_START;

      // erase the pages
      flash.erase((void*)flashAddress, updateSize);

      uint8_t buffer[512];

      // write the pages
      for (uint32_t i = 0; i < updateSize; i += sizeof(buffer)) {
        updateFile.read(buffer, sizeof(buffer));

        flash.write((void*)flashAddress, buffer, sizeof(buffer));

        flashAddress += sizeof(buffer);
      }

      updateFlashed = true;
    }

    updateFile.close();

    if (updateFlashed) {
      SD.remove(UPDATE_FILE);
    }
  }

  // jump to the sketch
  __set_MSP(*SKETCH_START);

  //Reset vector table address
  SCB->VTOR = ((uint32_t)(SKETCH_START) & SCB_VTOR_TBLOFF_Msk);

  // address of Reset_Handler is written by the linker at the beginning of the .text section (see linker script)
  uint32_t resetHandlerAddress = (uint32_t) * (SKETCH_START + 1);
  // jump to reset handler
  asm("bx %0"::"r"(resetHandlerAddress));
}

File libraries/SDU/extras/SDUBoot/build.sh:
#!/bin/sh -x

ARDUINO=arduino
SKETCH_NAME="SDUBoot.ino"
SKETCH="$PWD/$SKETCH_NAME"
BUILD_PATH="$PWD/build"
OUTPUT_PATH="../../src/boot"

if [[ "$OSTYPE" == "darwin"* ]]; then
    ARDUINO="/Applications/Arduino.app/Contents/MacOS/Arduino"
fi

buildSDUBootSketch() {
    BOARD=$1
    DESTINATION=$2

    $ARDUINO --verify --board $BOARD --preserve-temp-files --pref build.path="$BUILD_PATH" $SKETCH
    cat "$BUILD_PATH/$SKETCH_NAME.bin" | xxd -i > $DESTINATION
    rm -rf "$BUILD_PATH"
}

mkdir -p "$OUTPUT_PATH"

buildSDUBootSketch "SODAQ:samd:sodaq_sara" "$OUTPUT_PATH/sodaq_sara.h"

File libraries/SDU/src/SDU.cpp:
#include <Arduino.h>

#include "SDU.h"

__attribute__ ((section(".sketch_boot")))
unsigned char sduBoot[0x4000] = {
  #include "boot/sodaq_sara.h"
};

Sketch file sdu_test.ino:
#include <Arduino.h>
#include "SDU.h"

#if defined(ARDUINO_SODAQ_SARA)
#define DEBUG_STREAM SerialUSB
#else
#error "Please select the SODAQ SARA as your board"
#endif

#define DEBUG_STREAM_BAUD 115200

String message;

void setup() {
  // Start communication.
  DEBUG_STREAM.begin(DEBUG_STREAM_BAUD);

  while (!DEBUG_STREAM) {
    // Wait for Serial Monitor to be opened.
  }

  message += "Sketch compile date and time: ";
  message += __DATE__;
  message += " ";
  message += __TIME__;

  // print out the sketch compile date and time on the serial port
  DEBUG_STREAM.println(message);
}

void loop() {
  // add you own code here
}

File arduino/50/.arduino15/packages/SODAQ/hardware/samd/1.8.6/variants/sodaq_sara/linker_scripts/gcc/flash_with_bootloader.ld add these lines:
KEEP(*(.sketch_boot))

. = ALIGN(0x2000);

here:
...
SECTIONS
{
    PROVIDE(__sodaq_firmware_state = ORIGIN(FLASH) - 0x100);

    .text :
    {
        __text_start__ = .;

        KEEP(*(.sketch_boot))

        . = ALIGN(0x2000);
        KEEP(*(.isr_vector))
        ...

On SD card (formatted as FAT32) I have stored the renamed file UPDATE.bin without bootloader of the compiled sketch file. Pin D10 is connected and used as chip select CS.
Build boot hex files:
$ cd libraries/SDU/extras/SDUBoot
$ ./build.sh

Version 1.8.6-sodaq has these missing lines on arduino_zero variant but not on sodaq_sara variant.

Hi, I was away due to things changing in Cororna times, but now I'm back.
This does not work. It compiles, but I am unable to load the new firmware without bootloader.


text:
Accessing funcition in object via `->` is crashing (resetting) Arduino
I have several classes that call each other running on an Arduino Mega. I am using the ArduinoSTL library to get the std library, most notably the std::vector.
The core problem is as follows: my Manager object that is created in the Arduino global space, is called in the loop(). The Manager object in one of it's functions spawns a derived object Derived derived (the constructor also takes a pin int and a delay value, but just simplifying for now) and calls a function in it derived.startExecution(). All is happy. Then I store a pointer to the object into a std::vector<base*> myVector via myVector.push_back(&derived). All is happy. As long as I don't leave the function, I can then take the pointer out of the vector container and call another function in the object. For example: myVector.back()->continueExecution() and all is great. Now the problem. If I copy paste the line myVector.back()->continueExecution() into a different function, the Arduino restarts. I'm losing my sanity here. I know that the issue is not the pointer, but the call to the function using the pointer. Using println & delay(500), in a new function inside the Manager I can do the following without issue (no restart):

retrieve pointer from vector. All good.
assign pointer from vector to a temporary pointer type to be able to refer to that pointer. All good
calling the function in the object causes instant Arduino Hardware reset (not a single line will execute in the function that is called).

All this leads me to the conclusion that calling the function in the object is causing a problem. I rewrote a simplified version of the code below, and it executes well on this website (please see: https://godbolt.org/z/G3x556), but on the Arduino it crashes.
What can I do to understand why the object crashes the program? how can I validate that the object is OK prior to calling the function? Why does the call to the function in an object that should be alive crashes the system? why does the call work in the function which stored it in the vector, but not in a different function? How can I answer these questions. I have hit a limit on ideas. Thank you for your time!
My code simplified:
#include <iostream>
//#include <ArduinoSTL.h> //commented out to work on website
#include <vector>

//base class is used to be able to push everything into a std::vector
//in ArduinoSTL lib.
class Base
{
    public:
        virtual void continueExecution()
        { std::cout << "Base" << std::endl; }

        // a polymorphic class MUST have a virtual destructor
        virtual ~Base(){};
};

//lots of these classes will exist one day if I keep at this grind
class Derived : public Base
{
    public:
        Derived()
        {
            std::cout<< "Derived constructor" << std::endl;
        }

        void startExecution()
        {
            std::cout << "Derived object, start function"<< std::endl;
            //start work
        }

        void continueExecution()
        {
            //continue when time has eleapsed
            std::cout << "Derived continueExectution " << std::endl;
        }
};

class Manager
{
    public:
        void beginExecutingDerivedObject()
        {

            //derived object
            Derived derivedObj;

            derivedObj.startExecution();

            myVector.push_back(&derivedObj);

            //if I run the line that crashes the code below this
            //comment, all is OK. But that is not where it is needed.
            myVector.back()->continueExecution();
        }

        void finishExecutionOfDerivedObject()
        {
            //CODE CRASH HERE. The moment the function is called, a reset
            //occurs.
            myVector.back()->continueExecution();

            //any code here may appear on the console, but it's just a
            //memory dump. By this point, the Arduino has thrown up it's arms.
        }

    private:
        //create vector
        std::vector<Base*> myVector;
};

//main is actually the arduino loop()
int main()
{
    //this manager class is in the sketch global space
    Manager manager;

    //this is called by a function call in the loop()
    manager.beginExecutingDerivedObject();

    //this is also called by a function call in the loop()
    manager.finishExecutionOfDerivedObject();
}

Derived derivedObj; is a local variable. It's deleted when the function exits. You have saved a pointer to it, but with that object now gone your pointer points to nothing of any interest - so doing anything with it is doomed to failure.
Instead you need to create a new object on the heap, which will already be a pointer:
Derived *derivedObj = new Derived();
derivedObj->startExecution();
myVector.push_back(derivedObj);

And then be sure to delete any objects you remove from the vector or you'll have lost that memory forever.

Note that std::vector<Base*> myVector; is a vector of pointers. You could store values in a vector as std::vector<Base> myVector;, but then you cannot store instances of derived classes.

@Mike In your case, it's a bit complicated, because you have to do it when you remove elements or clear the myVector list. (Iterate over it with a for loop and delete all elements before you clear the vector). Using the STL (and some of the other features you use above) is quite advanced stuff for running on an Arduino, just because it's memory is very limited. You should probably look at some C++ tutorials first and run a few test programs on the PC first (where it's much easier to debug).

A C++11 shared_ptr smart pointer makes it easier, but no idea if ArduinoSTL supports them.

@Majenko You ROCK!!! I don't know C++ at all and it's so hard to learn on the fly. Thanks a ton for your answer. Could I push my luck and please ask for an example on how to use the delete word? I'm totally new to C++ and really appreciate it. Could your example please assume C++99 is being used (if I'm lucky enough to get one)?

Base *ob = myVector[0]; myVector.erase(0); delete ob;

@Majenko  I'm a very new to c++, and have a final follow up to your delete example. In your example, first you copy the pointer from the vector (same as: Base *myObj = myVector.back();. Then you wipe the element in the vector holding pointer (same as myVector.pop_back();). Finally you release the memory using the pointer. Am I correct? Also, when we delete myObj are we not deleting a pointer of Base type? shouldn't we be deleting the actual object, or this does delete the pointer AND the object? Sorry to pester you. I really appreciate your help!

delete is to new what free is to malloc. You give it a pointer (as new provides a pointer) and it frees the object (calling the destructor) that pointer points to. With new, at no point do you ever "have" an object. You only ever have a pointer (with an associated type).


text:
How do I program an LCD screen and do I need an Arduino
I am trying to create a small device with a screen that tells the date and time. I am thinking of using a UCTRONICS 0.96 Inch OLED Module (type that on Amazon). I am very new at coding, and I know more about electrical engineering, so I have a few questions.

Do I need an Arduino that big to power this screen or any screen? I am trying to put this in a compact housing

How do you set up the screen and code it to tell the time and date

Is there a better screen for me to pick that is easier to work with, or is there a screen that comes programmed telling the time and date

Can someone help, please?

"is there a screen that comes programmed telling the time and date" - For that you would just by a simple clock.

OLED screen is really good looking for both indoor and outdoor and I think you have made a good choice.
You need the following things to complete your project easily.

Display (which you have already found one
Arduino (why? easy to program, lots of libraries available, and also tutorials)
RTC - Real-time clock - This is another IC (DS1307, for example)

Arduino need not be UNO. You can use ATTiny85 MCU. the programming will be the same as how you program a UNO. ATtiny85 has no builtin I2C, but the libraries are there to emulate I2C to be connected to OLED displays.
If you want to avoid the third option, go with internal timekeeping alone. But, over a week, you will see the time difference (the internal clocks of the MCU are not accurate, so the time will lead or lag over a period of time)
have you thought about a keypad or a single button to give the option to the user to set the time?

This is just a prototype, the end product should be able to connect to your smartphone, so it can just use the wifi and your phone to get the time going. As per the screen, I am not trying to spend $50 on a screen; I would like it to be cheaper; I think I will go with the OLED screen and an Arduino Nano. I will ditch the clock for now, as that's only half of the prototype I am creating.

The screen you reference is an input only device, that is, it accepts output from other sources and presents the information. It is not, per se, a stand-alone computer for processing information in the manner you describe.

Image above courtesy linked Amazon site.
One option you can consider is a device known as Sparkfun Microview.

Image above courtesy to linked Amazon site.
This device is an integrated Arduino with OLED display. That's only half the objective. You'll also have to have a programming interface (referenced on the site) as well as an external input for RTC (real time clock). Rather than provide a link, an Amazon search for "Arduino RTC" returns many options. Kit form (assembly required (minor soldering), fully assembled, with and without battery.
All of the above requires, at a minimum, a power source for the Microview and a breadboard on which to make the connections. One can, of course, design a PCB to consolidate the components.
The programming portion is easily accomplished (relative reference) by researching that aspect via the internet. There are tutorials for the Microview, which by necessity include Arduino programming, as well as supplemental tutorials for the RTC. Sparkfun is known (by me) for providing good online support via these tutorials.
If you decide to travel this route to your goal, you may have Arduino specific questions which would be acceptable to this SE.


text:
How to access GPS location without internet
I need to provide a basic geolocation service for my clients. I built a location service based on the phone geolocation. It works great, not a problem. My problem is that some of my clients don't have an internet connection.
I know there is a company like Geotab that can provide these types of services.
If I want to build my own (very basic one), how can I make my DIY (Arduino based) GPS communicate with my web servers?

If you want communication with servers you will need internet, what you can do is use some wireless communication protocol take data at the at the gateway and then send the data on the web servers

It is possible to derive approximate locations of users from the WIFI they're currently using, but that requires a big database, such as what google has. Unlikely you can do something similar in an own project. The same applies for locating using IP addresses, which on top of it gives only very broad results.

"some of my clients doesn't have internet connection." - As you want to send data to webservers on the internet, you need to get a connection to the internet. Please explain more about the circumstances. Is the "geolocation service", that you want to provide limited to a specific area?

If you want to send data to a server on the internet, you will need an internet connection, or at least a connection to a internet gateway.
Which type of connection you use, and how you set up that connection, depends on distance, speed, and coverage you need.
Probably the most universal for your application, in the sense that it will work wherever a phone would work, is to use a GSM/GPS module with an Arduino. You can google around for such modules; there are many. Note that you will need a SIM card for every module you use.
The GSM-bit of the module can then be used as a modem to communicate with your server over TCP/IP. There are many examples showing how to do that on the interwebs, so I won't go there.
If this doesn't help you enough, please add more detail to your question and I will edit the answer.


text:
Unable to upload any sketch but Serial Monitor keeps displaying "Start scan, Scan done, Network found" message
I have bought a new Mega 2560 with WiFi.
I tried to upload a sketch that worked OK with the previous Mega 2560 but the upload always fails with the following error message:
*************************************************************
Arduino: 1.8.13 (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

Sketch uses 2762 bytes (1%) of program storage space. Maximum is 253952 bytes.

Global variables use 391 bytes (4%) of dynamic memory, leaving 7801 bytes for local variables. Maximum is 8192 bytes.

C:\Users\warph\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\warph\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega2560 -cwiring -PCOM3 -b115200 -D -Uflash:w:C:\Users\warph\AppData\Local\Temp\arduino_build_593938/2560-Mega-WiFi.ino.hex:i

avrdude: Version 6.3-20190619

         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\warph\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : COM3

         Using Programmer              : wiring

         Overriding Baud Rate          : 115200

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_getsync(): timeout communicating with programmer

avrdude done.  Thank you.

An error occurred while uploading the sketch

Can someone please help to get this issue fixed?

Did you select the correct COM port?

remove the tx rx pin and try again

you have esp8266 on USB. use the DIP switches to configure the board https://robotdyn.com/mega-wifi-r3-atmega2560-esp8266-flash-32mb-usb-ttl-ch340g-micro-usb.html

My apologies for the dumb question but did you try to upload any other, simpler, sketch on this Mega board?

Thanks a lot. All good after changing the DIP switch settings.


text:
MAX30102 showing Heart rate: 0.00bpm / SpO2: 0%
I am using a MAX30102 to monitor SpO2 and heart rate using the https://github.com/oxullo/Arduino-MAX30100 library and the minimal example, but it is not showing any value change.
It only shows zero and in the library tester example it is also showing a timeout error for die temperature.
I removed all 3 pull up registers and given 5 v supply.

Please help to get correct result; I will be thankful.

Have you used pull-up resistor with 5V?

the tester example, checks connections on the startup. are they ok ?
you have to put your finger on the sensor, but not pressing againts it, and without shakes or movements for a few seconds before the results start to change. also, you can decrease the led current (uncomment it in the example) and try again.

To identify the issue, run I2C Scanner and check the address of this module on the Serial Monitor.
If the I2C Scanner program is not able to detect the module, then either the module is defective or connections are wrong.
If the I2C Scanner program is able to identify the sensor, then check with other libraries.


text:
Mkr1000 Wifi Configuration
Is there a package similar to esp8266 WifiManager that supports wifi configuration for Arduino mkr1000?
I have searched everywhere and I got nothing

https://github.com/khoih-prog/WiFiManager_NINA_Lite

It shows error "Error compiling for board Arduino MKR1000."

sorry, I read MKR1010 and you have MKR1000. try to ask Khoi Hoang to make the library WiFi101 compatible. it should be simple.

I'll release a new WiFiManager_Generic_Lite, with functionality similar to WiFiManager_NINA_Lite, to provide support specifically to MKR1000 using WiFi101, as well as other generic boards (nRF52, SAMD, SAM-DUE, STM32, Teensy, AVR, etc.) using generic WiFi Shields (AT-command, WiFiNINA, etc.) within several days.
Please hold on,

The new library has just been released : WiFiManager_Generic_Lite in GitHub as well as Platform.io WiFiManager_Generic_Lite in PIO.
The following 2 examples are created specially for you to use and test

MKR1000_WiFi101
MKR1000_WiFi101_MQTT

Please test and post your feedback here. Post issues, certainly many with this new library, on WiFiManager_Generic_Lite issues
Cheers,

Amazing! please let me know

Please check the just released library in the answer.


text:
RTC DS3231 headache
I've been trying to get an RTC clock to display time. I tried using 3 different RTC modules: standard ds1307, pcf8523 and ds3231.
They all give the same results: wrong time and no incrementing. It does not matter if I manually insert a timestamp or if it gets it at compile time.
I am using using a Feather Adalogger and an MPU6050 accelerometer. The battery is good and the connections have been verified. It's as if there is some value in some memory somewhere that reverts to the timestamp below.
Here's the code:
#include <RTClib.h>
#include <Wire.h>

RTC_DS3231 rtc;

char t[32];

void setup() {
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
  //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop() {
  DateTime now = rtc.now();
  sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d",  now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
  Serial.print(F("Date/Time: "));
  Serial.println(t);

  delay(1000);
}

Here's the printout:
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:02 04/00/2020
Date/Time: 00:35:03 04/00/2020
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:02 04/00/2020
Date/Time: 00:35:03 04/00/2020
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:02 04/00/2020
Date/Time: 00:35:03 04/00/2020
Date/Time: 00:35:00 04/00/2020

Ok so its really an I2C issue. How dos I wire multiple I2C devices on feather adalogger?

The output you've shown makes it look like the board is resetting.  It would be more clear if you had something distinct printing in setup().

Are you resetting the board repeatedly? Your setup() function always resets the date/time to the time the sketch was built.

Normally, in a situation like this... you create a sketch that will initialize and SET the current time for the RTC.  After that, you create a new sketch that only initializes and reads the RTC for your actual clock functions thus keeping the two actions  (SET/GET) isolated.

did you run I2C scanner?

How may I2C devices do you have connected? And what are those? It might be an I2C address conflict.


text:
Help- Optical Sensor interfacing with Arduino
I am a newbie and I wanted to know if it is safe to connect this NPN output sensor directly to one of the GPIO pins of the Sparkfun redboard. Do I need some extra circuitry or components? Thanks

top left schematic on page 5 ... safe ........ bottom schematic ... not safe


text:
Cannot program two arduinos at the same time because they both use the same COM port
I am not able to program my second arduino because they both use the same com port. In other words this picture says it all:

In order to upload my sketch I have to disconnect one arduino. How can I tell windows to use a different COM port?
It will be nice if I do not have to disconnect one arduino evey time I want to upload a sketch. I already restarted my computer and I get the same problem.

Can't you just choose another port in the port properties? It's been a while since I futzed in windows device manager...

That's the answer thanks Majenko

Never in my life have I seen that Windows allocates the same COM port number to two different devices.. weird

@MaximilianGerhardt The only explanation I can think of is that the two UARTs are completely identical and windows can't tell them apart at all.  Counterfeit FTDI chips are known to clone hardware serial numbers.  Windows also usually remembers the COM number a device had when it was last seen on a particular USB port, but it usually assigns a different COM number by default even for the same device if you plug it into two different USB ports.  It could be that a cloned serial combined with a first-plug while the device['s clone] being already plugged in led to this COM port doppelganger...

@J... the cloning thing makes a lot of sense. I just recalled only one of my Arduinos would change port numbers when connected to different ports, and I thought that was the dead one. It also happened to be original.

I did not knew I could change the port on windows. This is how I did it thanks to @Majenko's comment.