body:
Starting with an analog signal from any sensor, how do I automatically determine if there is a real signal change or a reset? Below is the sample code that better explains my goal:

```c++
value = sensorRead();

if (millis() > t + 1000) {
  value_old = value;
  t         = millis();
}
float d = value - value_old;
if (d < -3) {
  print("signal change")
  myfunction(); //ex. bink led
}
```

So if `value(current) = 0.5` and `value_old = 100` there has been a real change in signal, even if, because of noise, the value is not exactly 0.

It's very raw code, and I'd like to use a more professional approach that can detect both increments and decrements. Ideally, a suitable library, or alternatively a more efficient algorithm, would be ideal.

title: How to determine when a sensor's output signal changes significantly?

Answers: 1

body:
There is no simple and universal way of deciding what is to be
considered a “significant” change. My recommendation would be to create
an algorithm by playing with the data on your computer:

* Upload a sketch to your Arduino that simply reads the sensor and
  transmits the readings to your computer via `Serial`.

* Capture a long run of such readings in a file.

* Graph the readings and look carefully at the graphs: what would _you_
  consider a significant change? What criteria could you use to decide
  that a change is significant? Devise an algorithm to take this
  decision.

* Implement and test the algorithm on your computer, using the recorded
  data.

* Port the code to the Arduino.

Below are two examples that maybe could give you some ideas. First comes
the simplest I can think of: it says the change is significant if the
current value is far enough from a previously recorded value. That
recorded value is only updated after a significant change has been
detected.

```c++
bool changed_significantly(int value) {
    const int change_threshold = 4;  // tune to taste
    static int old_value;
    bool changed = abs(value - old_value) >= change_threshold;
    if (changed)
        old_value = value;
    return changed;
}
```

It would be used like this:

```c++
void loop() {
    int value = sensorRead();
    if (changed_significantly(value))
        Serial.println("Signal changed.");
}
```

Note that, with this algorithm, a very slow drift would periodically
trigger the detection of significant changes. If this is not what you
want, you may prefer to only detect changes that happen fast enough.
This can be detected by the use of a high-pass filter. The function
below implements a simple low-pass filter (exponentially weighted moving
average) and compares the current input to the previous output. The
difference is equivalent to a high-pass filter. If that difference is
large enough, a significant change is detected, then the filter is reset
in order to prevent it from being repeatedly triggered by a drift:

```c++
bool changed_significantly(int value) {
    const float change_threshold = 4;   // tune to taste
    const float filter_constant = 0.1;  // this one also
    static float filtered_value;
    float delta = value - filtered_value;
    bool changed = abs(delta) >= change_threshold;
    if (changed)
        filtered_value = value;
    else
        filtered_value += filter_constant * delta;  // low-pass filter
    return changed;
}
```

------------------------------------------------------------------------

**Edit**: some details about the filter.

This high-pass filter alone could be simplified as this:

```c++
float filter(float x)
{
    static float y;
    float delta = x - y;
    y += filter_constant * delta;
    return delta;
}
```

Note that, if this function returned `y`, we would have a conventional
first-order low pass filter (exponentially weighted moving average).
Since it returns instead the difference between the input and the
previous low-pass-filtered value, it behaves as a high-pass filter. Its
transfer function is

  H = (z − 1) / (z + k − 1)

where k is the filter constant. This constant is related to the cut-off
frequency as

  fc ≈ k fs / (2π)

where fs is the sampling frequency. Note that, for
frequencies significantly smaller than the cut-off, the filter behaves
like a scaled derivative:

  H x ≈ 1/(k fs) dx/dt


body:
[![enter image description here][1]][1]

Hi!
I require your help regarding a problem I’m encountering.
I am trying to measure wind speed using Hall sensor, Neodymium magnet & below mentioned code. But I only get “0” value for both RPM & KPH values. Can you help me to solve this?

```cpp
volatile byte revolutions;

unsigned int rpmilli;
float speed;

unsigned long timeold=0 ;

void setup()
{
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(2), rpm_fun, RISING);

    revolutions = 0;
    rpmilli = 0;
    timeold = 0;
}

void loop()
{
    if (revolutions >= 1) {
         //Update RPM every 20 counts, increase this for better RPM resolution,
         //decrease for faster update

         // calculate the revolutions per milli(second)
         rpmilli = revolutions/(millis()-timeold);

         timeold = millis();
         revolutions = 0;
         // WHEELCIRC = 2 * PI * radius (in meters)
         // speed = rpmilli * WHEELCIRC * “milliseconds per hour” / “meters per kilometer”

         // simplify the equation to reduce the number of floating point operations
         // speed = rpmilli * WHEELCIRC * 3600000 / 1000
         // speed = rpmilli * WHEELCIRC * 3600

         speed = rpmilli 1.288053600;

         Serial.print(“RPM:”);
         Serial.print(rpmilli * 60000 ,DEC);
         Serial.print(" Speed:");
         Serial.print(speed,DEC);
         Serial.println(" kph");
    }
}

void rpm_fun()
{
    revolutions++;
}

```

  [1]: https://i.stack.imgur.com/gPM83.jpg

title: Wind speed measuring using Hall sensor

Answers: 1

body:
```
rpmilli = revolutions/(millis()-timeold);
```

All variables in this line are of type `int`, so this is an integer division. When the time delta in ms is larger than the number of revolutions it counted, this always returns 0. You need to change this to:

```
rpmilli = ((float)revolutions)/(millis()-timeold);
```
and change `rpmilli` to float.


body:
I have a DC motor connected to a L298N (Green) controller. The controller is receiving  electricity but the motors aren't. This is how we wired everything

[![enter image description here][1]][1]

Our code:

```cpp
#include <SoftwareSerial.h>

int IN1 = 13;
int IN2 = 12;

int IN3 = 8;
int IN4 = 9;

void setup(){
  Serial.begin(9600);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

}

void loop(){
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  delay(2000);
}
```

The DC motor is not responding at all

Edit: Why is the motor not receiving electricity? How can we connect the card to the Arduino UNO correctly and get the motors running?

  [1]: https://i.stack.imgur.com/t9OTL.png

title: DC Motor not running with the L298N (Green) card

Answers: 1

body:
**First:** The connection between the 5V pin of the L298N and Arduino Vin is not correct here. The L298N 5V pin is an output. You could use it to power the Arduino. But then you would have to connect it to the 5V pin of the Arduino. Vin is connected to the linear voltage regulator. You need about 7V here to get the Arduino running reliably, because the regulator needs some headroom for regulating it down to 5V and the battery deplets over time a bit. Since you are powering the Arduino over USB you can remove this connection.

**Second:** The standard 9V block batteries, that you use, are not meant for providing the power for something like a motor. They are made for low power applications (like smoke detectors). So you will need a different battery type. Which exactly is dependent on further factors. You could start with putting AA batteries in series (enough to get to the voltage, that you need for your motors). Or you can buy a LiIon or LiPo battery (including the corresponding charging board). I'm not enough of a battery expert myself to go more detailed with the recommendations on direct batteries.

If you want it easy you might want to use a standard USB power bank. These give you 5V and (depending on the product) about 1 or 2A of current. Using a standard power bank has the advantage, that you get well regulated voltage, relatively high current and it already has the correct charging electronics.

With a USB-C power bank a corresponding PD board (Power Delivery) you can even get up to 12V from the power bank. Haven't tried this myself yet. Have a look at [this video from GreatScott][1] on Youtube. Looking at a standard online marketplace (we all know which one) and searching for "USB-C PD board" gave some promising results.

  [1]: https://www.youtube.com/watch?v=DQLrZA5RMjQ


body:
I am trying to figure out how to get requests (or whatever they are called) to display in the serial monitor, yet not change the HTML page bodies.

The user selects their choices in the submenu (`selection`). Once clicking the submit button there, they return to the original main index menu and simultaneously the query parameters are sent to the ESP32 of the user's selections.

Based off another very similar question I asked, it works so that the query parameters (in the URL) can be seen in the serial monitor. Although, then the main menu is cleared out and left with "message sent".

Alternatively, the main menu can remain the same, but the query parameters are not sent. So one works but not the other, and vise versa.

The files are below and here: https://github.com/adamelli/MinimalExamples/tree/main/22-1-25_query_parameters_submitButton

# File structure

sketch (folder)

 * sketch.ino
 * data (folder)
   * index.html
   * selection.html

# sketch.ino

    #include <WiFi.h>
    #include <ESPAsyncWebServer.h>
    #include <SPIFFS.h>
    #include <painlessMesh.h>

    const char* ssid = "Wireless Controller";
    const char* password = "12345678";

    // User stub
    void sendMessage() ; // Prototype so PlatformIO doesn't complain

    Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

    void sendMessage() {
      taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
    }

    AsyncWebServer server(80);

    void notFound(AsyncWebServerRequest *request) {
        request->send(404, "text/plain", "Not found");
    }
    IPAddress IP(192, 168, 1, 1);
    IPAddress gateway(192, 168, 1, 1);
    IPAddress subnet(255, 255, 255, 0);

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

      // Initialize SPIFFS
      if (!SPIFFS.begin(true))
      {
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
      }

      WiFi.softAP(ssid, password);
      delay(500);
      WiFi.softAPConfig(IP, gateway, subnet);
      IPAddress IP = WiFi.softAPIP();
      Serial.print("AP IP address: ");
      Serial.println(IP);

      server.on("/selection.html", HTTP_GET, [](AsyncWebServerRequest * request) {
        request->send(SPIFFS, "/selection.html", String(), false );
      });

    // Main menu index page works
    //  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    //    request->send(SPIFFS, "/index.html", String(), false );
    //  });

    // Query parameters works
      server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
      {

        int paramsNr = request->params();
        Serial.println(paramsNr);

        for (int i = 0; i < paramsNr; i++)
        {
          AsyncWebParameter* p = request->getParam(i);
          Serial.print("Param name: ");
          Serial.println(p->name());

          Serial.print("Param value: ");
          Serial.println(p->value());

          Serial.println("------");
        }

        request->send(200, "text/plain", "message received");
      });

      server.begin();
    }

    void loop() {}

# index.html

    <!DOCTYPE html>

Main Menu

<button class="button">Selection</button>

<button class="button">Oblivion</button>

# selection.html

    <!DOCTYPE html>

    <form action="/" method="get">

     Shape Size:

     <select name="size" id="size" style="font-size: 22px;">
       <option value="1"> 1   </option>
       <option value="2"> 1/2 </option>
      </select>

Speed:

     <select name="speed" id="speed" style="font-size: 24px">
       <option value="1">     Slowest </option>
       <option value="2" selected> Regular </option>
     </select>

<button class="submit" name="circle" value="3">Circle</button>

<button class="submit" name="square" value="4">Square</button>

    </form>

The data files must be uploaded via "Tools" → "ESP32 Sketch Data Upload".

How can the definitions, `server.on("/"` be combined so the data (size/speed/shape) is viewable in the serial monitor AND where the main and submenu remain the same (with their buttons)?

I have tried...

* putting `request->send(SPIFFS, "/selection.html", String(), false);` and    `request->send(200, "text/plain", "message received");` together inside ` server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)`

* sending different stuff for `request->send(200, "text/plain", "message received");` even though I still do not understand how to get it to submit data, and return to the main menu, without clearing it out with a new message (various trial and error combinations either did not allow it to compile or just made one of the pages "Not found")

* messing with HTML stuff (nothing changed)

title: ESP32 Access Point using ESPAsyncWebServer, how to send multiple parameters between submenu and main (index) menu while still retaining page layout?

Answers: 1

body:
This is not an answer per se.

Posted as an answer because of attached images.

It is unclear what you are actually asking.

I ran a python minimal web server in the same folder as index.html.

Here is the trace from the server.

~~~
C:\Users\qwerty\Desktop2\MinimalExamples-main\22-1-25_query_parameters_submitButton\data>py3 -m http.server 80
Serving HTTP on :: port 80 (http://[::]:80/) ...
::1 - - [27/Jan/2022 15:43:23] "GET / HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:43:24] code 404, message File not found
::1 - - [27/Jan/2022 15:43:24] "GET /favicon.ico HTTP/1.1" 404 -
::1 - - [27/Jan/2022 15:43:25] "GET /selection.html HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:43:32] "GET /?size=2&speed=1&circle=3 HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:43:34] code 404, message File not found
::1 - - [27/Jan/2022 15:43:34] "GET /notMinimal.html HTTP/1.1" 404 -
::1 - - [27/Jan/2022 15:43:39] "GET /?size=1&speed=2&circle=3 HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:45:07] "GET /?size=1&speed=2&square=4 HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:52:46] code 404, message File not found
::1 - - [27/Jan/2022 15:52:46] "GET /notMinimal.html HTTP/1.1" 404 -
::1 - - [27/Jan/2022 15:53:02] "GET /?size=2&speed=1&square=4 HTTP/1.1" 200 -
~~~

This is what `index.html` is called with.
The data is available to index.html. You only have to parse it from the URL.

[![enter image description here][1]][1]

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/gMKTI.png
  [2]: https://i.stack.imgur.com/jC61W.png


body:
Hi dears
I want help I’m in begging in programming. I want use more than 64 analog pin for ldr photoresistor in single reading. Because I can’t   use digital pin 0-1.
Any methods I can use ,,,,
And How??

title: How I can use more than 64 analog in arduino

Answers: 2

body:
You basically have 2 ways to do this:
- You can use multiplexer chips, which are capable of carrying analog signals. Then you can connect the multiplexers to an analog input and the inputs of the multiplexers to the LDRs. Each multiplexer gets controlled over multiple digital pins (depending on the exact chips; it may be good to find one with a serial interface like I2C) and connects the analog input with one of the LDRs. Which one depends on the control inputs.

- You can use external ADCs (Analog Digital Converters, like the one in the Arduino). These are normally controlled over a serial interface (like I2C) and give you multiple analog inputs at once. For example [this board from adafruit][1], which gives you 16 analog inputs and is controlled over only 2 lines (I2C, A4 and A5 on an Arduino Uno/Nano). This is probably a simpler way, though for a higher cost. If you want to to cheaper than the linked board, you may wanna use blank ADC chips instead of a breakout board.

  [1]: https://www.adafruit.com/product/1085

body:
I've just built a board that allows an Arduino to access 192 analog inputs - one at a time of course. More is possible. It uses 4067 16 x 1 analog mux chips. A single 8 bit port controls it.
Need a schematic?


body:
After being introduced to this code on [github][1], and exploring [electronoobs tutorial][2] I was compelled to try and recreate it with the Arduino Nano, and using the A0-A3 analog comparator inputs. Currently, I am just trying to get the rising edge of the receiver transducer to be recognized in the interrupt. Thus, I think my problem resides in `ISR(ANALOG_COMP_vect)`

Using an oscilloscope confirms that the ultrasonic transducer is firing every 100 ms, and I can detect the ping with the receiver as a small voltage above GND, which should trigger the ISR interrupt with DIO6 connected to GND... but that is not happening...

Here is my code:

    #include  <avr/interrupt.h>

    #include  <stdint.h>
    #include  <stdlib.h>
    #include  <stdio.h>
    #include  <stdbool.h>

    #include <Arduino.h>
    #include  "fastio.h"

    #define F_CPU 16000000UL

    // pins for TX driver
    #define PING0   PB1
    #define PING1   PB2

    #define LED     DIO13

    #ifndef MASK
      #define MASK(m) (1UL << m)
    #endif

    #define DEBUG 0
    #define INTERVAL 100
    #define diff(a,b) (((a) >= (b))?((a)-(b)):((b)-(a)))

    inline bool ge(uint32_t a, uint32_t b) {
      return ((a - b) & 0x80000000UL) == 0;
    }

    inline bool lt(uint32_t a, uint32_t b) {
      return ((a - b) & 0x80000000UL) != 0;
    }

    volatile uint32_t milliseconds = 0;

    uint16_t starttime = 0;
    volatile uint16_t envelopetime = 0;
    volatile uint16_t phasetime = 0;

    #define PULSECOUNT_X2 16
    volatile uint8_t edges = 0;

    void pins_init(void) {
      WRITE(PING0, 0);
      SET_OUTPUT(PING0);

      WRITE(PING1, 0);
      SET_OUTPUT(PING1);

      WRITE(LED, 0);
      SET_OUTPUT(LED);

    }

    void timer_init(void) {
      // init timers
      GTCCR = MASK(TSM) | MASK(PSRSYNC); // pause clocks

      PRR &= ~MASK(PRTIM1) & ~MASK(PRTIM0) & ~MASK(PRADC); // enable timers 0 and 1 and ADC

      // use timer1 for output waveform generation and analog comparator timing
      TCCR1A = 0;                       // normal mode, no match behaviour
      TCCR1B = MASK(CS10);              // maximum speed (no prescale)

      // use timer0 for our millisecond clock
      TCCR0A = MASK(WGM01);             // CTC mode
      TCCR0B = MASK(CS00) | MASK(CS01); // prescaler=64, ie clock is 250kHz
      OCR0A  = 250;                     // interrupt at 1kHz, ie every 1ms
      TIMSK0 = MASK(OCIE0A);            // interrupt on compare

      // set up analog comparator
      ADCSRA = (0 << ADEN);
      ADCSRB = (1 << ACME);
      ADMUX = 0;
      ACSR |= 0x03;

      GTCCR = 0; // re-enable clocks
    }

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

    void loop() {
      timer_init();
      sei();
      Serial.println("Start");

      uint32_t pingtime = INTERVAL;

      for (;;) {
        if (ge(milliseconds, pingtime) && (edges == 0)) {
          // note when we should ping next
          pingtime += INTERVAL;

          // start in a millisecond from now to avoid race conditions
          starttime = TCNT1 + (F_CPU / 1000);
          OCR1A = OCR1B = starttime;

          // reset edge counter
          edges = PULSECOUNT_X2;

          // set A and clear B on match
          TCCR1A = MASK(COM1A0) | MASK(COM1A1) | MASK(COM1B1);

          // disable interrupt on comparator
          TIMSK1 &= ~MASK(ICIE1);

          // clear flag in case it triggered during startup
          TIFR1 = MASK(OCF1A);

          // enable interrupt
          TIMSK1 |= MASK(OCIE1A);
        }
        if (phasetime != 0) {
          uint16_t eoff = envelopetime - starttime; // time when Rx signal became loud enough to consider, ie start of envelope
          uint16_t poff = phasetime - starttime;    // time of first zero crossing after envelope, use for calculating phase offset

          //printf_P(PSTR("envelope +%u (%uus) phase +%u (%uus)\n"), eoff, eoff >> 4, poff, poff >> 4);

         Serial.println(eoff);
         //Serial.println(poff);

          // zero so we only print once, process data before this
          phasetime = 0;
        }
      }
    }

    ISR(TIMER1_COMPA_vect) {
      if (edges == PULSECOUNT_X2) {
        TCCR1B |= MASK(ICES1);   // listen for rising edge
        TIFR1 = MASK(ICF1);      // clear flags in case it triggered during startup
        TIMSK1 |= MASK(ICIE1);   // interrupt on comparator

        TCCR1A = MASK(COM1A0) | MASK(COM1B0); // toggle on match
        //Serial.println("PULSE");
        WRITE(LED, 1);
      }
      else if (edges == 1) {
        TCCR1A = MASK(COM1A1) | MASK(COM1B1); // clear both on match
      }
      else if (edges == 0) {
        //putc('>');

        TIMSK1 &= ~MASK(OCIE1A);   // disable interrupt

        return;
      }
      edges--;
      OCR1A = OCR1B += F_CPU / 80000; // set next timeout
    }

    ISR (ANALOG_COMP_vect)
      {
      phasetime = ICR1;
      if((ACSR & B00100000)){
        envelopetime = ICR1;      // store timestamp
        WRITE(LED, 0);
        TIMSK1 &= ~MASK(ICIE1);   // disable interrupt on comparator
      }
    }

    ISR(TIMER0_COMPA_vect) {
      milliseconds++;
    }

  [1]: https://github.com/triffid/ultrasonic-poc
  [2]: https://electronoobs.io/tutorial/190#1

title: ATMega328p internal comparator problem - ISR(ANALOG_COMP_vect) not firing

Answers: 1

body:
You have not enabled the comparator interrupt.

Just need to change the line where you set ACSR.

    //Comparator interrupt on rising output edge.
    ACSR |= (1 << ACIS0) | (1 << ACIS1);

    //Enable comparator interrupt
    ACSR |= (1 << ACIE)

Can also be achieved with.

    ACSR = 0x0B

If you want to change what triggers an interrupt.
Bits 0 and 1 control how an interrupt is fired (Toggle, falling or rising).

    //Toggle (Default, only required if another interrupt mode is already selected)
    ACSR &= ~(0b11)

    //Falling
    ACSR &= ~(1 << ACIS0); //Only required if ACIS0 is set
    ACSR |= (1 << ACIS1);

    //Rising
    ACSR |= (1 << ACIS0) | (1 << ACIS1);
    //Or
    ACSR | = 0x03;

You will also need to enable global interrupts. (Which you have done)
Which can be done by calling...

    interrupts(); //Arduino only
    sei();        //AVR and Arduino

I see you are calling "sei" in the loop, it only needs to be called once (unless you have disabled them with "cli()," and I believe its not even required at all with Arduino as I think interrupts are already enabled.

[The datasheet is your friend.][1] Tutorials are a great way to learn, but if you really want to increase your skill set you should try to break free from tutorials as much as possible by reading the datasheet, and experimenting on your own.
The comparator starts on page 202, and would be a great place to start as its an easy peripheral to get going.

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf


body:
Currently, I'm trying to build image processing on ESP32 using OpenCV GitHub - [joachimBurket/esp32-opencv: Shrinked OpenCV for ESP32][1]. Then I want to put this library into Arduino IDE.

But, I'm having problem `"Specified folder/zip file does not contain a valid library"`.  Is there a file that must be deleted to be included in the Arduino IDE libraries? And, I previously also tried manual input. But, not everything was detected by the Arduino IDE.

Please give me a way out as I am new in this field.

  [1]: https://github.com/joachimBurket/esp32-opencv

title: Problem adding library in the Arduino IDE

Answers: 0


body:
I'm making a project based on HC-SR04 ultrasonic sensor with a stepper motor and an SG90 servo motor. I have done some conditions for my stepper motor that is given below. Now I want to include my servo in it. When the distance goes below 10cm the servo rotates at 90 degrees (N.B. the stepper remain the same as it is) and when the distance is above 10cm then the servo comes back to 0 degree.

Please help me out to complete this.

Thanks.

```c++
#include <Stepper.h>

// Define number of steps per rotation
const int stepsPerRevolution = 2048;

int rotationCW = 0;
int rotationCCW = 0;
int location = 1;

// Create stepper object called 'myStepper' note the pin order:
Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

const int trigPin = 2;
const int echoPin = 3;

// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement

void setup()
{
  myStepper.setSpeed(15); //Set the speed to 5 rpm

  Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed

  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
}

void loop()
{
  // Clears the trigPin condition
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin HIGH (ACTIVE) for 10 microseconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)

  // Displays the distance on the Serial Monitor
  //Serial.print("Distance: ");
  //Serial.print(distance);
  //Serial.println(" cm");

  if (distance >= 20 && location == 1)
  {
    rotationCW = (.4 * stepsPerRevolution);
    myStepper.step(rotationCW);
    location = (2);
    delay(500);

    Serial.println ("Gate closed");
  }
  else if (distance <= 20 && location == 2)
  {
    rotationCCW = .4 * -stepsPerRevolution;
    myStepper.step(rotationCCW);
    location = 1;
    delay(500);

    Serial.println ("Gate opened");
  }
}
```

title: Problem regarding on HC-SR04 sonar with an additional stepper and SG90 servo motor

Answers: 0


body:
I'm attempting to use an MPXV6115V pressure sensor to monitor the constant vacuum of a suction device. I haven't been able to find a library to use with this sensor. I'm very new to Arduino but I am a software developer so would like to write some code to get this sensor working. The datasheet for this sensor can be found [here][1]. I've had some success using the code found [here][2] but this is for a different MPX pressure sensor and the output doesn't look right, I believe my constant values might need adjusting but not sure.

I've heard I may be able to use the transfer function for the basis of the code? I'm really not sure where to start with that. Could someone please explain how I can write the code to get this sensor working with the Arduino? Thank you.

[![enter image description here][3]][3]

  [1]: https://www.mouser.co.uk/datasheet/2/302/MPXV6115V-1127049.pdf
  [2]: https://www.instructables.com/How-to-Read-MPX5010-Differential-Pressure-Sensor-W/
  [3]: https://i.stack.imgur.com/Ntsww.png

title: Writing Arduino code for MPXV6115V pressure sensor

Answers: 1

body:
The linked code basically just does `analogRead()`s, calculates a real world value from the results and sends it over Serial. Thats also what you want to do, you just need to change the calculation.

So take the transfer function of your sensor and reorder it so that you get a formula for P:

    P = (Vout/Vs - 0.92)/0.007652

with Vs being the supply voltage (5V in this case) and Vout being the output voltage. The ADC of the Arduino is 10 bits, so it gives you a value in the range of 0 to 1023 for 0V to 5V. So you get the voltage by calculating

    voltage = analogRead(pin) / 1023.0 * 5.0;

Now put that into the formula above, write it as proper C++ code (for the variables use `float` as type, while `pin` is an integer and is the pin you connected the sensor to, like `A0`) and then replace the calculation in the linked code with yours - or wrote your own complete code. There isn't much to do besides `analogRead()`, the calculation and corresponding `Serial.println()` calls.


body:
As digispark is more compact and suitable for my electrical application. Following the same procedure in [brtiberio answer][1]. I tried to convert the script from Arduino UNO to digispark, but not succeed

```lang-cpp
#define irPin 2
const int buttonPin1 = 0;
const int buttonPin2 = 4;
const int relay1 = 1;
const int relay2 = 3;
int Relay1State = 0;
int Relay2State = 0;
int master1State = 0;
int master2State = 0;
int button1State;
int button2State;
int lastButton1State;
long lastDebounceTime1 = 0;
int lastButton2State;
long lastDebounceTime2 = 0;
long debounceDelay = 50;
void setup() {
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay1, Relay1State);
  digitalWrite(relay2, Relay2State);
}

void loop() {

  int key = getIrKey();

  if(key == 7388){
    Relay1State = !Relay1State;
    if(Relay1State == true)
      digitalWrite(relay1, HIGH);
    else
      digitalWrite(relay1, LOW);
  }

  if(key == 1778){
    Relay2State = !Relay2State;
    if(Relay2State == true)
     digitalWrite(relay2, HIGH);
   else
     digitalWrite(relay2, LOW);
  }
}

int getIrKey(){
  int len = pulseIn(irPin,LOW);
  int key, temp;
  key = 0;
  //Serial.print("len=");
  //Serial.println(len);
  if(len > 6000) {
    for(int i=1;i<=32;i++){
      temp = pulseIn(irPin,HIGH);
      if(temp > 1000)
        key = key + (1<<(i-17));
    }
  }
  if(key < 0 )
    key = -key;

  //if(key)
    //Serial.println(key);

    delay(250);
  return key;
  //**********************//
  int reading = digitalRead(buttonPin1);
  if (reading != lastButton1State) {
    lastDebounceTime1 = millis();
  }
  if ((millis() - lastDebounceTime1) > debounceDelay) {

    if (reading != button1State) {
      button1State = reading;

      if (button1State == HIGH) {
        master1State = !master1State;
        Relay1State = master1State;
      }
    }
  }

  digitalWrite(relay1, Relay1State);
  lastButton1State = reading;

  //*******************************//
  int reading2 = digitalRead(buttonPin2);
  if (reading2 != lastButton2State) {
    lastDebounceTime2 = millis();
  }
  if ((millis() - lastDebounceTime2) > debounceDelay) {

    if (reading2 != button2State) {
      button2State = reading2;

      if (button2State == HIGH) {
        master2State = !master2State;
        Relay2State = master2State;
      }
    }
  }

  digitalWrite(relay2, Relay2State);
  lastButton2State = reading2;
}
```

Any advise, please?

  [1]: https://arduino.stackexchange.com/questions/18022/controlling-relays-with-ir-and-button/88579#88579

title: Problem with IR remote and Pushbutton for digispark

Answers: 1

body:
Your button code is in the function `int getIrKey()`. But it never gets executed, because before it you execute `return key;`. With that you leave the function and returning the value of `key`. Everthing that comes after the return statement will not be executed.

Putting the button code in that function doesn't make sense in the first place (since the buttons are not used to "get the pressed IR key"). Instead try to put it in the `loop()` function, after the other relay code.


body:
I wish to upload measurement data to Google Cloud Platform IoT Core with Arduino MKR GSM 1400. I have followed:

https://docs.arduino.cc/tutorials/mkr-gsm-1400/securely-connecting-a-mkr-gsm-1400-to-google-cloud-iot-core

and

https://create.arduino.cc/projecthub/Arduino_Genuino/securely-connecting-a-mkr-gsm-1400-to-google-cloud-iot-core-b8b628

but I did not succeed on connecting to Google's MQTT broker.

I have seen that I am not the only one with this problem, but I hope that someone has figured out the solution to this problem.

Reading this:

https://groups.google.com/a/arduino.cc/g/developers/c/EK7lmDK-jTA?pli=1

I came to the realization that I might need to update the root certificate in the "radio module", aka SARA-U201. I've tried to figure out how to do this, and stumbled upon the arduino-fwuploader, I have tried to run it like this:

/arduino-fwuploader firmware get-version -b arduino:samd:mkrgsm1400 -a /dev/ttyACM0

in order to succeed with this:

./arduino-fwuploader certificates flash -b arduino:samd:mkrgsm1400 -a /dev/ttyACM0 -u mqtt.googleapis.com:443

but the fwupdater does not even find the board despite "arduino:samd:mkrgsm1400" being correct. And yes, I am trying to do all this under Linux.

I was also trying to make the example: "SSLCertificateManagement_Example" working, but for this I would have needed the certificates to be converted to DET format and arrange it to be an array of unsigned chars.

https://www.sslshopper.com/ssl-converter.html

At this point I don't know what else I should/could try. I know for a fact that the hardware itself is working, I have tried as many examples regarding GSM as I could (sending SMS, GPRS ping, initiating a voice call, detecting GSM networks, etc.), and all worked. Following the tutorial, I have properly locked the ECC508 crypto chip, and generated a private/public key into slot 0. I have a GCP account, configured it properly, I have even tried to disable the HTTP protocol in the GCP project registry, but no use, I still think that it is about updating the root certificate in the SARA module.

Did anyone figure this out yet?

Thank you for the related tips and ideas!

title: How to update root certificate(s) on Arduino MKR GSM 1400 (SARA-U201 basically) in order to be able to connect to GCP MQTT?

Answers: 0


body:
I'm using an arduino UNO with a L2989N motor controller with a nema 17 hanpose 17h3401 stepper motor. I'm using two 9 volt batteries in series to power it. I'm sure I connected them properly but it just doesn't work. I tried using the example stepper motor sketch stepper_oneRevolution but it didn't work. I just cant pinpoint what's wrong.
PS. I'm very new to this

title: I cant get a stepper motor to work with arduino UNO

Answers: 1

body:
It is highly likely your power source supplies insufficient current to power both the stepping motor and the Arduino reliably.

This is very similar to one of my [past stackexchange question / answer][1].

Where I say ...

> Consider using a power source which can supply more current.  For
> instance, [D size cell][2] batteries can supply much more current than
> a [small 9 volt battery][3].

... all that said, stepping motors are high current devices.  It may not be feasible to run stepping motors off batteries.

  [1]: https://arduino.stackexchange.com/questions/85856/mixed-sharp-ir-sensor-readings/85859#85859
  [2]: https://en.wikipedia.org/wiki/D_battery
  [3]: https://en.wikipedia.org/wiki/Nine-volt_battery


body:
I am new to programming in general and to Arduino as well.
I am working on a small project to improve my ability to write complete and kind of useful programming sketches.

I am facing a problem. I am using a few things in my circuit like 7-segment display and relays and several indicating LEDs and a buzzer.

Let's sat that when a condition occurs I want one LED to  blink while everything still works fine and sends data to the display and controls relays, and I solved that with the `millis` function.

But the problem came when I tried to implement the same concept to the buzzer (which in my case I want to buzz for a pre-set amount of time, and then stop, without keeping buzzing all the time which might be too long), without using the `delay` function.

I tried many many code but nothing would work for me so far. Here is the simple code of my sketch. I hope you guys will help me find a solution

```c++
const byte buzzer = 13;  // buzzer_PIN
const byte switch1 = 3;  // PUSH-BUTTON PIN

/* please NOTE:
that the switch in my project will actually represent a condition to start the buzzer alarm, then maybe that condition will not exist, and after that the condition might come back and need the buzzer again
*/

unsigned const int delaytime = 500; // delay time needed between on and off states for the buzzer
unsigned long previousBuzz = 0;     // Variable for millis
unsigned long currentTime = millis();
boolean buzzPreState = true;        // Boolean made to avoid repetition for the buzzer when not needed

void setup() {
  pinMode(buzzer,OUTPUT);
  pinMode(switch1,INPUT_PULLUP);
}

void loop() {
  unsigned long currentTime = millis();
  int switchVal = digitalRead(switch1);

  if (switchVal == LOW && currentTime - previousBuzz > delaytime && buzzPreState == true) {
    previousBuzz = currentTime;
    buzzPreState = false;
    buzzerStart(5);
    buzzPreState = true;
  }
}

void buzzerStart(int repeat) {
  for (byte i=0; i<repeat; i++) {
    digitalWrite(buzzer, !digitalRead(buzzer)); // to switch buzzer ON and OFF alternatively
  }
}
```

title: Question about using millis for alarm conditions - Arduino

Answers: 1

body:
You are missing a delay here:

```c++
for (byte i = 0; i < repeat; i++) {
    digitalWrite(buzzer, !digitalRead(buzzer));
}
```

Without the delay, the whole loop terminates so fast that you cannot
hear anything.

Now, if you want non-blocking code, you should instead use the approach
of the Blink Without Delay tutorial:

* have the program remember the current state
* when it's time to switch states (as determined by `millis()`), update
  the current state.

The difficulty is that, whereas the program state in that tutorial is
trivial (either the LED is off or it's on), in your case it is more
complex. In addition to the time of the last toggle, you have to keep
track of:

* whether the buzzer is off or on
* whether it is supposed to be making sound
* a counter for the buzzing cycles.

The approach I would use is to have a counter (let's call it
`buzzer_remaining`) telling how many cycles it still has to complete.
The counter would decrement when the pin goes `LOW`. When it reaches
zero, the buzzing is done. Note that this choice implies that, when the
condition for buzzing becomes true, we will start at the middle of a
buzzing cycle.

Here is a tentative implementation of this approach:

```c++
const uint32_t buzzer_half_period = 500;  // 500 ms in each state
const uint8_t buzzer_count = 5;  // buzz for 5 cycles
uint8_t buzzer_remaining;        // remaining buzzing cycles
uint8_t buzzer_state;            // LOW or HIGH
uint32_t buzzer_last_toggle;     // millis() at last toggle time

void buzzer_start() {

    // Ignore request to start if we are already buzzing.
    if (buzzer_remaining > 0)
        return;

    // Initialize the buzzer state.
    buzzer_remaining = buzzer_count;
    buzzer_state = HIGH;
    digitalWrite(buzzer, buzzer_state);
    buzzer_last_toggle = millis();
}

// Call this periodically from loop().
void buzzer_update() {

    // Do nothing if we are not supposed to be buzzing.
    if (buzzer_remaining == 0)
        return;

    // Do nothing if it is too early to switch state.
    uint32_t now = millis();
    if (now - buzzer_last_toggle < buzzer_half_period)
        return;

    // Update the buzzer state.
    if (buzzer_state == LOW) {
        buzzer_state = HIGH;
    } else {
        buzzer_state = LOW;
        buzzer_remaining--;
    }
    digitalWrite(buzzer, buzzer_state);
    buzzer_last_toggle = now;
}
```

I resisted the temptation to put all this inside a class. It would be
cleaner, but I think this “plain C” style of programming might be easier
on a newcomer.

Note that calling `buzzer_start()` when the program is already buzzing
has no effect: the request to start the buzzer is ignored. This is not
the only possible choice: one could instead want to reset the counter in
order for the buzzing to last longer. The choice I made is arbitrary,
and I only made it because, in your question, the program requirements
are not fully specified.


body:
I am trying to use a RP2040 Pico with the Arduino IDE. This is a huge uphill battle. Initially I couldn't get the upload serial port to show up, then copied the "hello world" UF2 to the Pico folder ( https://datasheets.raspberrypi.com/soft/hello_world.uf2 ), after which the port showed up in the Arduino ISE 2.0.0 on Windows 10 - but I can't upload any programs. All I get is this error message:

    Traceback (most recent call last):
      File "C:\Users\light\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\1.9.15/tools/uf2conv.py", line 380, in <module>
        main()
      File "C:\Users\light\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\1.9.15/tools/uf2conv.py", line 360, in main
        drives = get_drives()
      File "C:\Users\light\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\1.9.15/tools/uf2conv.py", line 233, in get_drives
        "FileSystem,", "DriveType"])
      File "D:\obj\Windows-Release\37win32_Release\msi_python\zip_win32\subprocess.py", line 395, in check_output
      File "D:\obj\Windows-Release\37win32_Release\msi_python\zip_win32\subprocess.py", line 472, in run
      File "D:\obj\Windows-Release\37win32_Release\msi_python\zip_win32\subprocess.py", line 775, in __init__
      File "D:\obj\Windows-Release\37win32_Release\msi_python\zip_win32\subprocess.py", line 1178, in _execute_child
    FileNotFoundError: [WinError 2] The system cannot find the file specified
    Upload error: Failed uploading: uploading error: exit status 1

This is ultra-weird, because no such folders etc. exist on my drive D:\, and I have no idea why it's looking for files on drive D:\ in the first place, because the Arduino IDE is installed on drive C:\. And these folders also aren't present on C:\.

Does anyone have any ideas on how to fix this? I've Googled everything I can find and have so far found nothing helpful. I'm about ready to give up and would REALLY appreciate any help you can give!

title: Cannot upload programs to Raspberry Pi Pico with Arduino

Answers: 1

body:
It took me two days to fix that mistake!
Who would have thought that this is due to the missing file "C:\Windows\SysWOW64\framedynos.dll".
When I put the file back in place, everything went back to normal.

UPD:

Turn on "Show verbose output" in Preferences and browse several last lines.
There should be a line like this:

```
C:\Users\light\AppData\Local\Arduino15\packages\rp2040\tools\pqt-python3\1.0.1-base-3a57aed/python3 -I C:\Users\light\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\1.10.0/tools/uf2conv.py --serial COM5 --family RP2040 --deploy C:\Temp\arduino_build_214726/...
```

Copy and run that line in Terminal (Win-R). There may be bug reports to help you solve your problem.


body:
**Background**

I'm reading a 24-bit ADC value into a uint32. Using SPI bus, here's the logic:

    value = SPI.transfer(0);   // read first 8 bits (MSB first)
    value <<= 8;               // shift bits left
    value |= SPI.transfer(0);  // read next 8 bits
    value <<= 8;               // shift bits left
    value |= SPI.transfer(0);  // read final 8 bits

As such I'm left with this ADC reading:

    00000000 11111111 11111111 11111111
             MSB                    LSB

(Ignore the leading zeros for now.)

Now I transfer this value over ethernet like so:

    client.write((const byte*) &value, sizeof(value));

The problem is this:
- The value is stored as MS **bit** first.
- client.write() transmits it LS **byte** first.

I am using NodeRED as a TCP server. So at the other end, I receive the data like this:

    11111111 11111111 11111111 00000000
         LSB          MSB

I understand this is the expected behavior, but I would like to switch the BYTE order around before sending, so that it is read in NodeRed native endianness.

----------

**Question**

Perhaps I should do some bit shifting at the point of reading the ADC, to accommodate the fact that client.write() sends the least significant byte first, like this:

      byte1 = SPI.transfer(0);
      byte2 = SPI.transfer(0);
      byte3 = SPI.transfer(0);
      response = byte3;
      response <<= 8;
      response = byte2;
      response <<= 8;
      response = byte1;

Is this the most efficient way in terms of clock cycles?

Please note that my MCU is a Teensy 4.1, and I'm transferring 10,000 readings per second. I would like to keep the clock cycles for any necessary bitwise operations to a minimum, so that the timing of ADC readings are affected as little as possible.

title: How to swap byte order

Answers: 2

body:
    // reverse wire order:
    client.write((const byte*) &value + 3, 1);
    client.write((const byte*) &value + 2, 1);
    client.write((const byte*) &value + 1, 1);
    client.write((const byte*) &value,     1);

body:
You can use an array of `byte` to save the shifts at all. This solution should be the one with the least clock cycles, and with no additional memory usage.

```c
static byte value[4] = { 0 };

    /* ... */

    /* value[0] is still 0. */
    value[1] = SPI.transfer(0);
    value[2] = SPI.transfer(0);
    value[3] = SPI.transfer(0);

    client.write(value, sizeof value);
```

Some notes:

1. Using an array avoids the re-interpretation of a 32 bit variable as a byte array. You read bytes from SPI, and `write()` expects a byte array. This circumvents your endianness issue completely.

1. In the call of `write()` you don't need to cast the address of `value` to `const byte *`, because the `const` is a qualifier _for the called function_. It is not allowed to change the bytes pointed to.

1. Making the array static saves you from zeroing the first byte repeatedly. BTW, it is sufficient to provide the first byte, as all other bytes are zeroed automatically. However, the last bytes will be updated on each transfer.

1. `sizeof` is an operator, not a function. However, it is quite common to use it with a type instead of an object, and then you need parentheses because of the syntax. But it is better to use the respective object, actually you mean that.


body:
Total Arduino noob, I come from a Python "background", though I barely know that, either.

I'm writing a super simple script that will turn on a bulb when the random number generator generates a number greater than 100. Obviously, I have a syntax problem or something: What am I doing wrong? Secondly, How quickly does ```random``` query numbers? Is it possible to slow it down? I don't need my bulb turning on 50 times a second.

Thanks! And please be kind; I know this is Googleable, I just lack the prerequisite knowledge to Google this efficiently.

```
/*

*/
int relayPin = 7;
int randomNumber = random(1001);

void setup() {
  pinMode(relayPin, OUTPUT);

}

void loop() {

if(randomNumber > 100)
  digitalWrite(relayPin, LOW);

else{
   digitalWrite(relayPin, HIGH);}

}```

title: Using Random() and Greater Than

Answers: 1

body:
There are a few things to be discussed in here.

First, the random number generation: in fact, the arduino **does not** generate random numbers. It has a list of numbers on its memory that just "seems" to be random. That's why it's called a pseudo-random number.
So, you need to declare a starting point on this sequence, from which you will get the "random" numbers. This is made with "randomSeed()" in void setup. For example:
```
void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point,
                             //in this case, the analogRead value of an unconnected pin
}
```

Next, let's generate our number. The variable can be global (as you declared it outside any function), but **you must declare it with "random()" only inside "void loop"**. Otherwise, its value will be assigned just one time (that's what your code is telling it, to do it once).

Here is what I would do:

```
int relayPin = 7;
long randomNumber; //just declares the variable; it must be type "long"

void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point
  pinMode(relayPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  randomNumber = random(0, 301);
  //each time the code loops, it assings another value to randomNumber
  //in this case, the number will be between 0 and 300 (301 is the excluded limit)

  if(randomNumber > 100){
    digitalWrite(relayPin, HIGH);
  }
  else{
    digitalWrite(relayPin, LOW);
  }
  delay(500); //half a second delay

}
```

If you want to have more details about how random numbers are generated in the Arduino, visit the Arduino language Reference:
https://www.arduino.cc/reference/en/


body:
I am working on a simple project on talking to the serial monitor, and my only global variable ("int" type, named "incomingByte") is consuming a lot of memory. There is no problem on running the scketch, but I am not satisfied to have it that way.

When I load it, I receive: "Global variables use 390 bytes (19%) of dinamic memory...".
Why is it happening, and how could I fix this?

```
int incomingByte = 0; //for the incoming serial data
void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point
  Serial.begin(9600);
  //waits for serial initialization to send the messages:
  //(Serial) returns false for serial off, and true for serial on. This is inverted with !.
  while(!Serial){
    ;
  }
  //sending instructions:
  Serial.println("Initializing...");
  Serial.println(" ");
  delay(2000);
  Serial.println("Please select an option:");
  Serial.println("1 - greetings");
  Serial.println("2 - random number");
  Serial.println("3 - calculator");
  Serial.println(" ");
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available() > 0){
    incomingByte = Serial.read(); // Serial.read() returns the first byte of incoming data

    //recognizing the command received:
    if (incomingByte == '1'){
      numberOne();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
    if (incomingByte == '2'){
      numberTwo();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
    if (incomingByte == '3'){
      numberThree();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
  }
}

void numberOne() {
  Serial.println("Hello, Vitor! Good to see you!");
}

void numberTwo() {
  //sets the random number to be picked between [0, 101[
  long randomNum = random(0, 101);
  Serial.print("Your random number is: ");
  Serial.println(randomNum, DEC);
}

void numberThree(){
  Serial.println("Tool not available yet");
}
```

title: 1 global variable consuming 19% of memory

Answers: 1

body:
A few things that count towards the “global variables” that you may not
think of:

* all your literal strings, unless encapsulated within [the `F()`
  macro][F]; you have quite a few of them
* The `Serial` object, including its transmit and receive buffers (157
  bytes on an Uno)
* The [vtable][] for `HardwareSerial` (that's the class `Serial` belongs
  to, 18 bytes)
* The time-keeping variables (9 bytes).

And then, on top of that, there are the actual global variables of your
code, and the static locals which, for the purpose of memory allocation,
are the same as globals. An `int`, for example, takes 2 bytes on
AVR and 4 bytes on most other hardware platforms.

[F]: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/#_the_f_macro
[vtable]: https://en.wikipedia.org/wiki/Virtual_method_table

------------------------------------------------------------------------

**Edit**: answering the questions in a comment

> every single time I call `Serial` it will increase the memory
> consumption of the code?

I don't quite understand what you mean by “every time”:

- Every time you add a reference to `Serial` to a sketch, the linker
  will add the `Serial` object to your compiled code, and the program's
  RAM consumption will grow by the size of this object.
- Within a single sketch, whether `Serial` is used once or many times
  makes no difference: the object will be instantiated only once.

> why does the IDE considers everything that uses RAM as a global
> variable?

When it says “global variables” it actually means “statically allocated
data”. It says “global variables” because it is targeted at beginners,
and the authors assume beginners would not understand what static
allocation means. Globals are the simplest form of static allocation.

> is there a difference in consumption between globals and locals?

Yes. Globals get allocated statically, i.e. at compile time. That's why
the IDE can report how much space they will consume. Locals (at least
non-static locals) get allocated and deallocated on the stack, at run
time. Short of running the program in an emulator, it is very hard to
predict how much stack space a program will consume, as this will
usually depend on run-time events.


body:
I am trying to control a single DC motor using a L298N DC Motor Driver. I have a 12V motor plugged into Out1 and Out2, a 7.4 volt battery wired to the 12v in and common ground, a m/m common ground going from the arduino grnd to the L298N common ground, and I have IN1 and IN2 connected to digital pins 2 and 3. I am powering the Uno with USB. I am also running a m/m wire from the Uno 5v to the L298N (I shouldn't have to) in order to power the L298N[![enter image description here][1]][1]

[![enter image description here][2]][2]

I am using a basic code to test the motor

        int motor1pin1 = 2;
    int motor1pin2 = 3;

    void setup() {
      // put your setup code here, to run once:
      pinMode(motor1pin1, OUTPUT);
      pinMode(motor1pin2, OUTPUT);

    }

    void loop() {
      // put your main code here, to run repeatedly:
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);

      delay(1000);

      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, HIGH);

      delay(1000);
    }

If I wire the 7.4v lipo battery directly to the L298N the red led doesn't go on. It only goes on when I run a 5V wire from the Uno to the L298N. Yet still I get no reaction out of the motor. However if I run a ground from the arduino directly to the out1 or out2, the motor turns in that one direction. Anyone have an idea what I am doing wrong?

  [1]: https://i.stack.imgur.com/XtgO7.jpg
  [2]: https://i.stack.imgur.com/Yb3yr.jpg

title: L298N DC Motor Driver Conundrum

Answers: 2

body:
I don't see any problem in your wiring and code. The only thing that's not exactly optimal is that the voltage provided by the battery is not just high enough. The L298N's supply voltage is supposed to be at least 2.5V above the logic supply voltage (the logic HIGH level to be precise). That would make 7.**5**V - you only have 7.**4**V.

That sounds like a tiny gap, but the battery voltage might drop further under load.

"*run a ground from the arduino directly to the out1 or out2*" - you should not do that as this can create a short circuit, depending on the state of the EN and IN pins.

body:
Assuming you have the ENABLE jumper in place to enable motor control, then you should be able to drive the motor full-speed forwards or backwards without the UNO code at all - just use the +5V and GND lines from the UNO as 'logic level probes'.

According to my logic table a LOW (GND) on L1 and a HIGH (+5v) ON L2 will cause a motor connected to OUT1/2 to rotate one way, and reversing the logic on L1/2 will cause it to rotate in the other - at full speed (full speed being whatever the battery supply voltage can provide).

Once you have the motor(s) turning properly, THEN you can add the complexity of trying to control the speed and direction programmatically.  The code you showed does exactly the same as just using the +5 & GND leads as probes - with a 1 second delay between reversals.

Hope this helps

Frank


body:
I have Seeeduino Cortex-M0+, which is similar to Arduino Zero, both using Atmel SAMD21 MCU. It is powered from 12V battery directly to 12V PWRIN jack. Current draw for LED blink test is 18mA. I tried two low power libraries:
- https://github.com/rocketscream/Low-Power
- https://github.com/adafruit/Adafruit_SleepyDog

with:
- `LowPower.standby(); delay(5000);`
- `Watchdog.sleep(5000);`

In both cases, the current draw dropped only to 12.7mA, which is still huge. I checked the datasheet of MP1496DJ-LF-2 step-down, switch-mode converter used by this board and its quiescent current is below 1mA, so it doesn't look like the source of high current consumption. I've read posts about Arduino Zero running on 5mA from 12V input in low power. What else can I do in order to get the current closer to 5mA?

I cross-posted at https://electronics.stackexchange.com/questions/607000/achieving-low-power-with-seeeduino-cortex-m0-powered-from-12v-battery

----

I did a few experiments with external DC/DC converters feeding 5V pin on Seeeduino Cortex-M0+ from 12V battery, bypassing its MP1496DJ-LF-2 power stage. Here are the results:

| DC/DC model | sleep current [mA] | LED blink current [mA] |
|-----------------|-------------|--------------------|
|MP1496DJ built-in baseline|12.7|18.0|
|LM2596S generic|8.6|14.8|
|Pololu D24V22F5|5.0|11.2|
|Pololu D24V5F5|3.6|9.3|

title: Achieving low power with Seeeduino Cortex-M0+ powered from 12V battery

Answers: 1

body:
As [@devnull at Electronics Stack has answered][1], the quiescent current of 5~10 mA from the LDO could be enough to make up for the lost currents.

I don't have any specific suggestions on code or parts, but I can give you some tips regarding methodology. If you're working on the software side to reduce current consumption, you might be better off eliminating the possibility of hardware imperfections entirely. I'd power the board with 3.3V directly and preferably cut the traces to 5V or other unused circuits. Reduce the current consumption to the lowest possible on software side, and then work on the hardware side. You could be better off with an external LDO or a 12V to 3.3V converter with a low quiescent current to power your board.

From my experience, currents can leak from even the most unexpected circuits. There could be a faulty or crappy capacitor with higher than usual leakage current, resistors in voltage dividers with resistance not high enough drawing a couple of mA in total, or some random transistors we didn't think of drinking 1~ mA per chip. Or combinations of everything above being responsible for only a few hundred uA per part, but totals to a few mA in total. It's best to make a board with the most barebone parts or get one.

  [1]: https://electronics.stackexchange.com/a/607005/172770


body:
I've recently got one of these nice M5-Though devices (basically a water-proof M5-Core2). They have these 4-wire sockets to connect their sensors. The I2C socket has 4 pins for +5V, GND, SDA and SCL. According to the [schematics (bottom of page)][1], the SDA and SCL lines are directly connected to the GPIO pins of the ESP32. That means that most sensors connected to this socket will run the I2C bus at 5V. Even their own sensors [(example)][2] have pull-ups to 5V on the SDA and SCL lines.

Isn't this going to fry the ESP32? Different sources say that it's inputs are _not_ 5V tolerant. So far, I always used the 3.3V line to power external sensors from the ESP32 (or added a level shifter).

  [1]: https://docs.m5stack.com/en/core/tough
  [2]: https://docs.m5stack.com/en/unit/tof

title: M5Stack - confused about I2C bus voltage

Answers: 1

body:
No, it's not going to "fry" the ESP32, and here's why:

Yes, there are pullups to 5V. Those are 4.7K in your example. The IO pins are connected to 3.3V through ESD diodes. That means that any voltage over and above 3.3V plus the forward voltage of those diodes will be "diverted" away from the IO pin through the diode. IO pins have these ESD diodes built in, but this board has extra external ones added to make it more rugged.

These ESD diodes can handle a finite amount of current flowing through them - the internal ones only a small amount, but the external ones much more.

The 5V will only be a low current because it is connected with a resistor. We can even do some maths here.

Assuming the ESD diodes have a 0.3V forward voltage (as is reasonably typical) we can say that the voltage across the diode will be 5V - 3.3V - 0.3V = 1.4V.

With a 4.7K resistor as a pullup the current through the diode will be 1.4V / 4700 = 298 microamps.

That's way below the limit you'd expect of a small internal ESD diode, let alone a larger external one.

The "frying" of an IO pin happens when too much current flows through the ESD diode and it blows, "failing short", causing the IO pin to be locked in either a HIGH or LOW state for the rest of eternity. Since the current is nowhere near the kind of levels needed for that it's not going to even remotely stress the diodes, and the inclusion of external diodes makes it even safer.


body:
I'm trying to squeeze code onto an [ATtiny10][1], but I'm just not getting there. I'm using 1060 bytes and only have space for 1024 bytes.

The code is simple enough; I need to read a button pin. If high it needs to pick a random value and that causes one of two random LEDs on the PCB to turn on for two seconds. Is there a way to optimize this code to work on this IC?

```
int buttonState = 0;

void setup() {
    pinMode(3, INPUT);
}

void loop() {
    buttonState = digitalRead(3);
    if (buttonState == HIGH) {
        bool ranNum=random(0,1);
        if(ranNum == 0) {
            digitalWrite(0, HIGH);
        }
        else {
            digitalWrite(1, HIGH);
        }
        delay(2000);
        digitalWrite(1, LOW);
        digitalWrite(2, LOW);
    }
}
```

  [1]: https://www.microchip.com/en-us/product/ATtiny10

title: Optimizing code for ATtiny10

Answers: 4

body:
Are you sure the pins are correct?

Maybe use a smaller random number generator per https://arduino.stackexchange.com/a/18092/6628 ?

    static uint8_t lfsr = 0x01;
    const byte LFSR_MASK = 0x8e;

    void setup() {
      pinMode(0, OUTPUT);
      pinMode(1, OUTPUT);
      pinMode(3, INPUT);
    }
    void loop() {
      //      int buttonState = digitalRead(3);
      if (digitalRead(3)) {
        if (generateNoise()) {
          digitalWrite(0, HIGH);
        }
        else {
          digitalWrite(1, HIGH);
        }
        //delay(2000)
        //for (int i = 31; i; i--)_delay_us(64516);
        _delay_ms(2000);
        digitalWrite(0, LOW);
        digitalWrite(1, LOW);
      }
    }

    uint8_t generateNoise() {
      // Return 1 bit of noise using a Galois Linear Feedback Shift Register
      // See https://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs

      if (lfsr & 1) {
        lfsr =  (lfsr >> 1) ^ LFSR_MASK ;
        return (1);
      }
      else         {
        lfsr >>= 1;
        return (0);
      }
    }

The RNG didn't help as much as changing the much-disparaged delay.

body:
As I stated in a comment, this device would be too small for me to
consider programming it using an Arduino core. I would rather stick with
the avr-libc and direct port manipulation:

```c
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB = _BV(PB0)   // PB0 as output
         | _BV(PB1);  // PB1 as output
    for (;;) {
        loop_until_bit_is_set(PINB, PB3);  // wait for PB3 high
        if (rand() & 1)
            PORTB |= _BV(PB1);  // PB1 high
        else
            PORTB |= _BV(PB0);  // PB0 high
        _delay_ms(2000);
        PORTB &= ~_BV(PB0);     // PB0 low
        PORTB &= ~_BV(PB1);     // PB1 low
    }
}
```

This is plain C, but I expect it to be accepted by the Arduino IDE as a
valid .ino file. I tried compiling it like this:

```shell
avr-gcc -mmcu=attiny10 -Os -Wall -Wextra -DF_CPU=8000000 prog.c -o prog.elf
```

And it resulted in a program that uses 660 bytes of flash. Most of that
is in the implementation of `rand()` and its dependencies
(multiplication and division routines).

body:
If the button is pressed by a human and your clock is high enough (MHz range), you can use a trick and get rid of the RNG.

You can replace it with a free running counter like this:

```c
unsigned char count = 0;

void loop() {

    count += 1;

    buttonState = digitalRead(3);

    if (buttonState == HIGH) {
        if( (count & 1) == 0) {
            digitalWrite(0, HIGH);
        }
        else {
            digitalWrite(1, HIGH);
        }
        delay(2000);
        digitalWrite(1, LOW);
        digitalWrite(2, LOW);
    }
}
```

You have `count` incremented every ⪝10 us (depending on your clock speed, attiny executes one instruction per cycle), so when the user pushes the button, the counter will be sampled.

Note: I assumed `loop()` is all what the microcontroller has to do, and it's constantly called.

body:
An 8-bit chip requires multiple instructions for processing 16 bit. Changing ints to either uint8_t or int8_t will save code.

Depending on compiler optimization, replacing

    if ( (count & 1) == 0) {
        digitalWrite(0, HIGH);
    }
    else {
        digitalWrite(1, HIGH);
    }

with

    digitalWrite((count & 1), HIGH);

could save bytes.


body:
I'm getting an unexpected extra character added to the serial monitor print line only when I initialize an SD card in the code.

Normal

The code below gives me this expected result in the serial monitor:

**Serial Monitor**
```
23:31:12.745 -> inputString: abc
```

**Code**
```
const int BUF_DIM = 3;
char inputString[BUF_DIM];

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  inputString[0] = 'a';
  inputString[1] = 'b';
  inputString[2] = 'c';

  Serial.print("inputString: ");
  Serial.println(inputString);
}

void loop() {
}
```

Unexpected Character

However, the serial monitor prints an unexpected extra `M` at the end of `inputString`'s value `abc` when I add initialization of an SD card.

**Serial Monitor**
```
23:24:30.319 -> Initializing SD card...initialization done.
23:24:30.319 -> inputString: abcM
```

**Code**
```
#include <SPI.h>
#include <SD.h>

File myFile;

const int BUF_DIM = 3;

char inputString[BUF_DIM];

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  //-------------Toggle this block to see the M dissapear-----------
  Serial.print("Initializing SD card...");
  if (!SD.begin(5)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  myFile = SD.open("DATA.TXT");
  //-------------Toggle this block------------

  inputString[0] = 'a';
  inputString[1] = 'b';
  inputString[2] = 'c';

  Serial.print("inputString: ");
  Serial.println(inputString);
}
```

Why is this happening and how can I get the serial monitor to behave as expected with the SD card.

title: Unexpected character added to char buffer array in serial monitor only when SD card initialized

Answers: 1

body:
    const int BUF_DIM = 3;

    char inputString[BUF_DIM];
    ...

      inputString[0] = 'a';
      inputString[1] = 'b';
      inputString[2] = 'c';

    ...

      Serial.println(inputString);

You have allowed three characters in your array and indeed put three characters there, however you have not put a "null terminator" there at the end (nor is there room for one) so you will naturally get garbage at the end of the string until the processor happens to find a 0x00 byte.

Put it another way, how does the code know to print three characters and not 20 characters? The answer is that the underlying function (Serial.println in this case) looks for a null-terminator.

You need to read up on how null-terminated strings work.


body:
I am looking for a reference document or documentation system that concretely relates at minimum:

- Screen printed pin name/number
- SAM3X8E pin number
- Register number
- Channel number
- Port name

In my case I am looking to change the PWM characteristics of pins 2 and 3 (as named on the physical board). Various forum posts discuss setting registers, register pin mappings, but nothing seems to quite tie up.

On the Arduino as printed, Pins 2 to 13 are listed as PWM pins, 12 in total. By [this][1] page, pins 2 and 3 map to PB25 and PC28 respectively on the SAM3X8E chip. Presumably this suggests Pin 2 is on the 'B' port, and 3 is on the 'C' port. Referencing [this][2] page, the sample code goes through 'all 8' PWM ports and pins, which by the register naming scheme `PIO_ASBR_Pxx`, suggests the pins numbered 16 to 19 are on the B Port, and 21 to 24 are on the 'C' port. Later the PWM ports are again iterated over with the `PWM->PWM_CH_NUM[i]` where `i` runs from 0 to `PWMCH_NUM_NUMBER - 1`, which is suggested as 8 in total.

'Pin 2' on the board then seems to have a mapping to a named pin on the Atmel chip of PB25, somewhere between 21 and 24 on the register name and between 0 and 7 on the channel index. Surely there is a place that attempts to harmonise all of these disparate naming conventions.

**Further Information:**

For instance, PWM/Digital Pin 2 maps to PB25 on the chip, as per the schematic provided by Majenko. PB25 is not a member of the PWM pins as per the chip [datasheet][3]. How am I to understand this?

When referencing the name `PIO_ASBR_19`, this is the 20th bit in the PIO_ASBR register, but how does this bit map onto the port/pin mapping? Then while the datasheet discusses the 'PIO_ASBR' register, since that can relate to at most 32 pins, the datasheet does not expand on how to map the excess pins.

  [1]: https://docs.arduino.cc/hacking/hardware/PinMappingSAM3X
  [2]: https://forum.arduino.cc/t/due-pwm-frequency/435603/5
  [3]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf

title: Is there a definitive reference for the Arduino DUE?

Answers: 1

body:
The [full pinout][1] is available on arduino.cc in Store and in the Getting started section.

>  For instance, PWM/Digital Pin 2 maps to PB25 on the chip. PB25 is not a member of the PWM pins as per the chip datasheet. How am I to understand this?

The Arduino core uses timers to do PWM on pins without native PWM support.

In [analogWrite source code][2] you can see sections for DAC, PWM and TIMER PWM pins.

The information about pins for Arduino core is in [variant.cpp][3].

  [1]: https://content.arduino.cc/assets/Pinout-Due_latest.pdf
  [2]: https://github.com/arduino/ArduinoCore-sam/blob/790ff2c852bf159787a9966bddee4d9f55352d15/cores/arduino/wiring_analog.c#L280
  [3]: https://github.com/arduino/ArduinoCore-sam/blob/master/variants/arduino_due_x/variant.cpp


body:
For my project I am using 6 continuous servos connected to an Adafruit Servo Shield. To run them I use
`pwm.setPWM(0, 0, 1000)`
and then set a delay to run them for how long i’d like to, then run
`pwm.setPWM(0, 0, 0)`
to stop it.

I would like to run the servo in the opposite direction. How would I do this?

title: Using Arduino to allow continuous servo to go in the opposite direction

Answers: 1

body:
You probably already know that [continuous servos][1] are different to other hobbyist servos in that they rotate freely, and the [PWM signal][2] is used to control speed and direction of rotation.

The specific model of servo you're using is important and you'll need to refer to the datasheet to find out its details. Particulalry the servo's minimum (typically clockwise rotation); mid-point (neutral / no rotation); maximim (usually counter clockwise rotation) PWM pulsewidths. The mid-point is often set by a PWM pulsewidth of 1500 microseconds, but this can vary and it pays to check.

The [library][3] you referenced does implement a setPWM() function as you mentioned, however you'll note that it works in a range of *ticks* from 0 to 4095. The two parameter values set when to turn the PWM pulse on and off expressed as values from 0 to 4095. To use this function you'll need to map these parameters to produce the PWM signal the servo is expecting.

I recommend an alternative, using the **writeMicroseconds()** function of the same library, which accepts a value in microseconds for which the PWM signal will be high. You'll be able to obtain these directly from the datasheet.

In your question you mention using a PWM of approximately 25% duty cycle (1000/4095) for ON. This is likely much longer than the desired maximum for your servo which if it is 2000 microseconds, might need a value something like 430 (/4095). Similarly you mentioned a zero pulse to achieve a stop. I think this library uses zero as a special case for no PWM pulse. You said this generates a stop condition for your servos, but finding the neutral value may be better.

Rather than figuring out the maths for setPWM() to turn on and off the PWM pulse, the writeMicroseconds() function may be easier.

You'll need to check datasheets for your servos but a value of 1500 microseconds should be near neutral / no rotation. Decreasing values less than this should generate increasing speed clockwise. Increasing values greater than neutral should generate increasing speed counter clockwise.

  [1]: https://en.wikipedia.org/wiki/Servo_(radio_control)#Continuous-rotation_servos
  [2]: https://en.wikipedia.org/wiki/Servo_control
  [3]: https://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/library-reference
  [4]: https://learn.adafruit.com/adafruit-16-channel-pwm-slash-servo-shield/using-the-adafruit-library
  [5]: https://en.wikipedia.org/wiki/Straw_man_proposal


body:
Lets say I have a sensor connected to Arduino Uno Rev3's I2C Bus. I am reading the sensor output and using Serial.print() to send the sensor reading back to a my laptop.

I am trying to understand the bottlenecks that limits the sensor sampling rate received at the laptop.

The sampling rate of the sensor depends on many factors. Lets assume sensors sampling rate is not limited. That would mean I am limited by how much data each intermedia bus can carry before it reaches the laptop. For example, I am limited by I2C bus atmega328p is using to read the sensor data. I am also limited by the UART bus atmega16u2 is using to send the data to my laptop. Am I correct so far? Also, on what bus atmega328p and atmega16u2 are connected over?

title: Trying to understand the bottleneck of sensor sampling rate

Answers: 2

body:
> Also, on what bus atmega328p and atmega16u2 are connected over?

See:

<https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf>

They are connected by TxD and RxD.

Without seeing your code (hint) it is extremely difficult to say. Perhaps a faster baud rate would help.

body:
If there had been a specific scenario you were considering, it might help to share. There's quite a lot to think about with just theoretical assumptions.

> That would mean I am limited by how much data each intermedia bus can carry before it reaches the laptop

Yes, mostly yes. The bandwidth of the entire transmission interface which includes the I2C interface, ATMEGA328P, connection to ATMEGA16U2, and the USB interface would account for the theoretical max sampling rate of the sensor.

For some cases, you may need to consider the latency as well as the bandwidth of the transmission media, which would include the I2C interface, ATMEGA328P, ATMEGA16U2, and the USB interface. The sensor may require some calculations which may result in some delay. The I2C interface or the UART interface could introduce some delay too, especially if it's driven by bit-banging(although probably not with 328P).

Also from 328P's perspective here, it has to receive data from the sensor, make calculations from the incoming raw data if needed, and send over the UART interface to the 16U2. Most of these processes will happen step by step and if the combined processing time takes longer than the delay between each sample coming from the sensor, the 328P itself could theoretically be a bottleneck too.


body:
I have project with an ESPAsyncWebServer with websockets working already. What I need to add is Client functionality to poll a site for a response. I looked at the ASyncTCP library and it has two different implementations that aren't well documented in how to use.

There's the SyncClient option that looks like this:
```
  SyncClient client;
  if(!client.connect("www.google.com", 80)){
    Serial.println("Connect Failed");
    return;
  }
  client.setTimeout(2);
  if(client.printf("GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n") > 0){
    while(client.connected() && client.available() == 0){
      delay(1);
    }
    while(client.available()){
      Serial.write(client.read());
    }
    if(client.connected()){
      client.stop();
    }
  } else {
    client.stop();
    Serial.println("Send Failed");
    while(client.connected()) delay(0);
  }
```
I don't know if i'm supposed to put code after a client.connected() or client.available()? Of if I need the full structure as shown or just one of the commands. It also doesn't show all the commands and syntax available (such as an equivalent for client.write(), client.print or the like).

Then there is the simply named ClientServer > Client which only has the following:
```
static void replyToServer(void* arg) {
 AsyncClient* client = reinterpret_cast<AsyncClient*>(arg);

 // send reply
 if (client->space() > 32 && client->canSend()) {
  char message[32];
  sprintf(message, "this is from %s", WiFi.localIP().toString().c_str());
  client->add(message, strlen(message));
  client->send();
 }
}

/* event callbacks */
static void handleData(void* arg, AsyncClient* client, void *data, size_t len) {
 Serial.printf("\n data received from %s \n", client->remoteIP().toString().c_str());
 Serial.write((uint8_t*)data, len);

 os_timer_arm(&intervalTimer, 2000, true); // schedule for reply to server at next 2s
}

void onConnect(void* arg, AsyncClient* client) {
 Serial.printf("\n client has been connected to %s on port %d \n", SERVER_HOST_NAME, TCP_PORT);
 replyToServer(client);
}

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

 // connects to access point
 WiFi.mode(WIFI_STA);
 WiFi.begin(SSID, PASSWORD);
 while (WiFi.status() != WL_CONNECTED) {
  Serial.print('.');
  delay(500);
 }

 AsyncClient* client = new AsyncClient;
 client->onData(&handleData, client);
 client->onConnect(&onConnect, client);
 client->connect(SERVER_HOST_NAME, TCP_PORT);

 os_timer_disarm(&intervalTimer);
 os_timer_setfn(&intervalTimer, &replyToServer, client);
}
```
This doesn't tell me a whole lot about how to use this library.

I need some guidance on how to deploy the client alongside my server. I don't need much, just listen for server directive, parse it and then send a response (client.println) or upload a file (client.write). I'd like to implement the asynchronous version of this.

title: ESP8266: ESPASyncserver + client

Answers: 0


body: I have a project plan in which there are calculations that require high precision, which later will have calculations with numbers after commas such as 245.5431657288. from some of the information that I read to make the project a success it must use 32 bytes, initially I wanted to use arduino due, but for some reasons I was more interested in using STM32 but my knowledge of STM32 is not much, especially in terms of the level of precision calculation, therefore I ask is STM32 suitable for my project? I hope my question can be understood, thank you.

title: how accurate is the calculation in stm32?

Answers: 1

body:
The hardware makes no difference to the accuracy of calculations. That is purely down to the software - whether you use single or double precision floats, whether the compiler flags disable double precision to save space (as some 8 bit configurations do), etc.

The choice of hardware only affects the efficiency of the processing at different precisions, such as if there is an FPU, or what precision the FPU can operate at (using precisions outside the range of the FPU will only affect speed not precision).

Both the stm32 and due are ARM based MCUs, so any differences will be down to what additions there are in any specific chip (such as FPU).


body:
I have an Arduino sleeping most of the time to save power and there are two buttons attached to different interrupt pins that run different functions.  These functions are different from each other, but both have to run long blocking code.  I don't want the button bouncing (or even deliberately being pressed multiple times during the blocking code) to [queue][1] up multiple runnings of the interrupt function.  I also don't want the sleep period to be short because I'm trying to keep if off as much as possible to save power.  I don't want to have to wait 8 seconds after a button press before the button's action happens.  As such, I would think flags or polling the pins from the main loop are not the way to handle this because of power inefficiency and long latency between button press and action.  Should I have each ISR detached its own interrupt pin until its action is complete and then reattach?

    const int buttonA = 6;
    const int buttonB =  10;

    void setup() {
      pinMode(buttonA, INPUT_PULLUP);
      pinMode(buttonA, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(buttonA), actionA, FALLING);
      attachInterrupt(digitalPinToInterrupt(buttonB), actionB, FALLING);
    }

    void loop() {
      sleep_function();  //takes 8 seconds
    }

    void actionA(){
      //some blocking code that takes 2 seconds, but that I want to run immediately upon button press
    }

    void actionB(){
      //some blocking code that takes 10 seconds, but that I want to run immediately upon button press
    }

  [1]: http://www.gammon.com.au/interrupts

title: How do I debounce multiple external interrupt buttons?

Answers: 1

body:
Just set a flag in the interrupt, and run your code in the loop

    const int buttonA = 6;
    const int buttonB =  10;
    volatile byte flagA = 0;
    volatile byte flagB = 0;

    void setup() {
      pinMode(buttonA, INPUT_PULLUP);
      pinMode(buttonA, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(buttonA), actionA, FALLING);
      attachInterrupt(digitalPinToInterrupt(buttonB), actionB, FALLING);
    }

    void loop() {
      if(flagA){
        //some blocking code that takes 2 seconds, but that I want to run immediately upon button press
        flagA = 0;
      }
      if(flagB){
        //some blocking code that takes 10 seconds, but that I want to run immediately upon button press
        flagB = 0;
      }
      sleep_function();  //takes 8 seconds
    }

    void actionA(){
       flagA = 1;
    }

    void actionB(){
       flagB = 1;
    }


body:
I'm trying yo get a .bat file to send my cpu data to the com port my arduino is on. I've tried multiple google results (including one from this site) and everything I found will just... erase all the variable tied to the com port. The arduino is hooked up to an lcd (not really because arduino microview, but basically that) which displays the variables I want and works as expected when I put the data into the serial monitor manually, but when I run anything that's supposed to send the info they all go blank when I have nothing in my sketch that clears them.

The file is getting the data how it should. If I run this

`wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature`

then I get the temperature as normal. But If I try to send that to the com port...

`wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature > COM3`

The arduino reads whatever it's getting as literally nothing and blanks the variables.

title: Send batch info to com port?

Answers: 1

body:
As Edgar has noted in the comments the Arduino resets every time you open the serial port.

Every time you perform a redirect the serial port is opened afresh, which resets the Arduino into the bootloader. There is then a brief delay while the bootloader looks for suitable communication for uploading new code, and then your existing program gets started afresh.

Coupled with that is the problem of baud rate: you need to ensure that the serial port is configured for the same baud rate as your program is expecting.

All together that means that a simple redirect like you are using is really not the best way of communicating with an Arduino. Instead you will need to write a proper program that opens the serial port, waits for the Arduino to reset, then starts periodically probing for and sending the information that you need it to.

Python and PySerial is a common choice for beginners as is easy to get started with and has plenty of examples.


body:
ESP32-C3 has a nice feature called [GPIO Matrix][1] which allows to map most of it's peripherals to any GPIO pin. And it has feature called IO_MUX which allows direct & faster operations for some of the high speed peripherals, including SPI. The API from ESP-IDF (HAL SDK) provides [some library documentation on SPI functions][2].

But [Arduino-ESP32 core documentation][3] seems to completely miss SPI library & it's functions. It refers to basic Arduino SPI class, but it lacks description of features ESP32 family has.

I've found [this example for ESP32][4] (note that I'm looking for ESP32-C3 info) which sets SPI pins through SPI.begin method actually.

I've also found [this source][5] which seems to feature a lot of SPI internal HAL functions. And a C++ [SPI class sources are here][6]. But it's actually doesn't have any useful comments on how to use IO_MUX or allowed values for ::setFrequency() method.

So basically I'm asking for a documentation on ESP32-C3 Arduino specific SPI class features. But to narrow things down **I'm actually looking now how to initialize SPI2 (which is the only generally available SPI master on C3) as IO_MUX at the fastest SPI clock speed possible from the Arduino core/SPI class**. Any suggestions are also welcomed!

  [1]: https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#iomuxgpio
  [2]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/peripherals/spi_master.html
  [3]: https://docs.espressif.com/projects/arduino-esp32/en/latest/libraries.html
  [4]: https://stackoverflow.com/questions/66722386/how-to-use-spi-with-esp32-and-arduino
  [5]: https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.c
  [6]: https://github.com/espressif/arduino-esp32/tree/master/libraries/SPI/src

title: ESP32-C3 SPI Class documentation/features?

Answers: 0


body:
I am using an Arduino mega2560 R3 My Arduino port is not recognized by the computer.led on is green,leds Tx and Rx are yellow and led L is blinking constantly(According to the figure).I used an Arduino Uno to upgrade the Arduino Mega bootloader(According to the figure)  but the problem with the Arduino Mega board was not resolved.What do you think is the solution? Is the mega board burnt?[![enter image description here][1]][1]m[![my mega2560][2]][2]

I tested the communication cable, there was no problem.I also tested a UNO board that had no problems and was programmed by computer.

[1]: https://i.stack.imgur.com/uuGTG.png
  [2]: https://i.stack.imgur.com/7Zv0b.png

title: Failure to recognize the Arduino Mega2560 R2 board by the computer

Answers: 1

body:
The "L" LED is controlled by the main MCU. This is blinking because the bootloader is running fine. There is nothing (superficially) wrong with the main MCU.

The TX ad RX LEDs are controlled by the ATMega16U2 (or 8U2 or 32U2 depending on the board version) chip which forms the USB interface bridge. These being solidly on are a bad sign. Normally they would be off until some form of communication between the PC and the main MCU (via the 16U2) takes place. This is not happening. If it were a faulty cable then the LEDs would be off. If the PC were not configuring the port the LEDs would be off. But they're on. Therefore the fault is most likely with the 16U2 itself.

Either the chip has been physically damaged (maybe through overvoltage or other misuse) or it has "forgotten" its firmware, either again through misuse or having the firmware overwritten with something else (which can only happen if you specifically perform such an action through the programming header for that chip).

The first step of diagnosis is to try and communicate with that chip through the 6 pin header adjacent to it. You can do this in the same way as you do for programming the bootloader on the main MCU, but instead of programming a bootloader you program the 16U2's firmware (IIRC it's included with the IDE or the AVR core somewhere).

If that is successful and the LEDs start working correctly and the board starts to function again then it's cured. If not, then chances are the chip is dead.

If the chip is dead does that mean the board is dead? Not necessarily, no. It depends on how the board died. If only the 16U2 is dead and the main MCU is fine you can still use it, just not through the USB connection.  You could either use the TX/RX pins and your own external USB to UART interface to replace the 16U2 or program it through the ICSP (SPI) header using another Arduino or a dedicated USB programming dongle. It's less convenient, but means you can still use the board.


body:
It's important to start by saying that this micro was working perfectly, and the keyboard I built with it was great. Then this happened:

While using the QMK Toolbox I tried to upload an oversized .hex file, and since it was taking too long, I hit the reset button. Clearly uploading an oversized hex file was the problem here.

Now the pro micro won't respond to anything. The green LDE lights up, but windows won't recognize it. I tried clicking the reset button and grounding the reset pin, and nothing works. I even tried the double tap on the reset key, or the tap and hold, nothing.

Have I totally broken the micro somehow? Can't I hard-reset it?

title: I can't get my Micro Pro to bootloader mode anymore

Answers: 1

body:
Alright, just answering my own question in case someone comes along in the future:

The problem in my case, as @Majenko mentions in the comments, was the bootloader. In my case, there was no way around it, I had to re upload it with a ISP.
I got another Arduino Pro Micro and using the wiring from this answer: https://arduino.stackexchange.com/questions/21166/trying-to-verify-that-arduino-pro-micro-isp-is-working and following this tutorial: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP

I managed to get it working.

Notes:
1. I did not have to change anything on the code for the ISP sketch.
2. Careful with the picture from the first answer, the comments show an issue with the wiring you need to take into account.

After that, the "Burn bootloader" action worked like a charm.


body:
I'm working with a 128x64 Oled display. I have just installed the Adafruit library and I'm running some sample codes. I have not modified the sample code in anyway yet just testing if the oled display is working but I've noticed that the splashscreen logo only shows the top half of the image.

How can I fix this?

[![Splashscreen][1]][1]

  [1]: https://i.stack.imgur.com/jvUxk.jpg

title: Why is the Adafruit splashscreen logo not displayed properly?

Answers: 1

body:
<s>I'm unable to test this now, but here goes:</s>
Turns out I *did* have the ability to test it (found an extra display module) and this does indeed explain the problem. The only other change I needed to make to your code in order to replicate the problem was change the display's I2C address to `0x3C`. Adafruit GFX Library v1.10.13 and Adafruit SSD1306 version v2.5.1.

---

From comments on the question:
> I added `#define SSD1306_LCDHEIGHT 64` before line #53 to remove the
> compilation error

Yeah, you can't do that. Under the old method of defining the screen dimensions, you are intended to modify the [header][1] itself:

```c++
// ONE of the following three lines must be #defined:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16  ///< DEPRECATED: old way to specify 96x16 screen
// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
// AND HEIGHT ARGUMENTS).
```

You can see by default it is using a screen with dimensions 128x32. [Later in the header][2] this is used to set `SSD1306_LCDHEIGHT` to `32` in the header.
```c++
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_32 defined
#define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_128_32 defined
#endif
```

What you have done in your code is **re**define `SSD1306_LCDHEIGHT` to `64` from the point where you issued the `#define` downward, which *only affects the code compiled in your sketch*.

Meanwhile, [over in Adafruit_SSD1306.cpp][3], `SSD1306_LCDHEIGHT` is *still* `32`, because this file is compiled independently of your .ino and is unaware of your own re`#define`.  In other words, part of the code you've put into your Arduino thinks it has 32 lines and part of it thinks it has 64 lines.

---

So, the solution would be get rid of the `#define` that you inserted into the sketch and to modify header to read:

```c++
#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
//#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16  ///< DEPRECATED: old way to specify 96x16 screen
```

Or to use the new method of supplying the dimensions by way of the constructor as is done in [newer examples][4]:

```c++
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
/// ...
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
```

The Adafruit SSD1306 version v2.5.1's ssd1306_128x64_i2c.ino example that uses this newer method of passing screen dimensions into the `Adafruit_SSD1306` constructor and compiled and ran without modification in testing here.

  [1]: https://github.com/adafruit/Adafruit_SSD1306/blob/4759c417580bfeba3803fb31f28b9285cfa3419e/Adafruit_SSD1306.h#L27
  [2]: https://github.com/adafruit/Adafruit_SSD1306/blob/4759c417580bfeba3803fb31f28b9285cfa3419e/Adafruit_SSD1306.h#L116
  [3]: https://github.com/adafruit/Adafruit_SSD1306/blob/4759c417580bfeba3803fb31f28b9285cfa3419e/Adafruit_SSD1306.cpp#L330
  [4]: https://github.com/adafruit/Adafruit_SSD1306/blob/f8b3aeb/examples/ssd1306_128x64_i2c/ssd1306_128x64_i2c.ino#L26


body:
As a complete newbie, after much looking for the best bargain, I ended up buying one of these UNO R3 clones, without realizing it had the chip soldered on the board. It looks like this:

[![enter image description here][1]][1]

It works OK for development, but after that I want to get rid of the Arduino board and just use the Atmega with the minimum set of components on the final project.

As far as I understand, two tasks need to be acomplished here:

 1. Program the bootloader on the spare Atmega328P
 2. Upload code to the spare Atmega328P

Acording to [this tutorial][2], I should be able to accomplish 1) with my "Arduino" board and a breadboard, but after that I couldn't upload any programs to that same Atme328P as the original microcontroller from the "UNO R3" should be removed and that can't be done on rip off.

Does anybody know of a method to accomplish 2) with my current setup? I also have one of those USB-to-serial converter (FTDI) boards. According to [this other tutorial][3] that can be done using it and some components, but I'd like to avoid that if, let's say, there's some trick like disabling the RX and TX line from the soldered chip by software so the external chip ones could be used instead...

  [1]: https://i.stack.imgur.com/IdzR0.jpg
  [2]: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoToBreadboard
  [3]: https://www.arduino.cc/en/Main/Standalone?_gl=1*1bzf759*_ga*MjAxODYzNDY3My4xNjQ0NDQ2MTEy*_ga_NEXN8H46L5*MTY0NDU4MzM3My4zLjEuMTY0NDU4MzU2OS4w

title: Uploading to an external Atmega328P with a clone UNO R3 with soldered chip

Answers: 1

body:
Thanks anyone for the comments. Very clarifying! So, all in all, the replies to my question and other doubts are:

 1. There's no need to remove the existing MCU; it's enough to connect it's RESET pin to ground (GND), so it prevents from messing with the external Atmega, and
 2. There's no need to have a bootloader on the "final" product, as it's only a convenience when developing which allows to upload the program easily.


body:
am a little new at this so i sincirely need your help.

So I have a temperature & humidity sensor i got from http://www.aosong.com/en/products-70.html which is probably based on the AM2315C - Encased I2C Temperature/Humidity Sensor https://learn.adafruit.com/am2315-encased-i2c-temperature-humidity-sensor?view=all
I am trying to get it to read the temperature and humidity values, via an STM32F103C8T6 that am using as my microcontroller.

So whats going on is when i try this code:

```
#include <Adafruit_AHTX0.h>

Adafruit_AHTX0 aht;

sensors_event_t humidity, temp;
void setup() {
  Serial.begin(115200);
  if (! aht.begin()) {
    Serial.println("Could not find AHT? Check wiring");
    while (1) delay(10);
  }
  Serial.println();
  Serial.println("Temperature C || Humidity %rH");
}
void loop() {
  aht.getEvent(&humidity, &temp);// วัดค่าอุณหภูมิและความชื้น
  Serial.print(temp.temperature);
  Serial.print("                ");
  Serial.println(humidity.relative_humidity);
  delay(1000);
}

```
I got from this guy on YouTube and uploaded it in my Arduino Uno; it works perfectly, tried it with my ESP 32, works flawlessly and reads accurate values, BUT when i try to use the same code with my STM32 (STM32F103C8T6) Blue Pill it says "Could not find AHT? Check wiring" probably because of this line of course

```
  if (! aht.begin()) {
    Serial.println("Could not find AHT? Check wiring");
  }

```
I'm not sure if it's something to do with the I2C pins and how  they are defined for each board, or maybe the STM32F103C8T6 requres a different library, am not sure. By the  way i also tried adding 2 10k pull-up resistors between the SDA & SCL (AM2315C) and the SDA & SCL (STM32F103C8T6), still no change.

My pinout is as follows:

STM32F103C8T6 >> AM2315C
----------------------------
5v >> VDD

GND >> GND

PB6 (SCL) >> I2C SCL (White Line)

PB7 (SDA) >> I2C SDA (Yellow Line)

I need this to work for a project am doing and i would apppreciate if someone pointed me in the right direction, please let me know if i need to share more info so aid in the solving process.

title: Could not find AHT? Check wiring! How do i connect an AM2315C - Encased I2C Temperature/Humidity Sensor to a STM32F103C8T6?

Answers: 0