message:
Optimised random alphanumeric string generator

I'm trying to build arduino nonce generator, but the only thing I found is [this question on arduino forum][1] but I can't find out how to make it work for me. I checked and Serial.available() is always 0 for me and if I delete the If I still get nothing

**My code:**
```
void setup() {
    Serial.begin(9600);
    randomSeed(analogRead(0));
}

void loop() {
    byte randomValue;
    char temp[5];
    char letter;
    char msg[50];     // Keep in mind SRAM limits
    int numBytes = 0;
    int i;
    int charsRead;

    if(Serial.available() == 0)
    {
        charsRead = Serial.readBytesUntil('\n', temp, sizeof(temp) - 1); // Look for newline or max of 4 chars
        temp[charsRead] = '\0';   // Now it's a string
        numBytes = atoi(temp);
        if(numBytes > 0)
        {
            memset(msg, 0, sizeof(msg));
            for(i = 0; i < numBytes; i++) {
            randomValue = random(0, 36);
            msg[i] = randomValue + 'a';
            if(randomValue > 26) {
                msg[i] = (randomValue - 26) + '0';
            }
            }
            Serial.println("Here is your random string: ");
            Serial.println(msg);
            Serial.print("I received: ");
            Serial.println(numBytes);
            delay(1000);
        }
    }
}
```

How do I make it work?

Do you have some working random alphanumeric string generator that you are using?

  [1]: https://forum.arduino.cc/t/random-alphanumeric-generator/330466

body:
Your problem seems to be related to how you get the actual length you want to generate. There are other ways you could do that. Since your max seems to be 4 characters, you could possibly enter "9999" which would overflow the 50 bytes `temp` variable.

You could simply read until `\n` and then `atoi`. Then cap at 50.

As a side note, here's a function I've used in the past to generate (pseudo)random strings for network requests (e.g. `state` or `nonce` parameters)

```c
#define MAX_UID 8 /* Change to whatever length you need */

const char * generateUID(){
  /* Change to allowable characters */
  const char possible[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  static char uid[MAX_UID + 1];
  for(int p = 0, i = 0; i < MAX_UID; i++){
    int r = random(0, strlen(possible));
    uid[p++] = possible[r];
  }
  uid[MAX_UID] = '\0';
  return uid;
}
```


sender: user

message:
How can I get a Faster boot with the Adafruit Feather SAMD21?

The Adafruit Feather SAMD21 takes about two seconds from power being supplied to when setup() starts running.  How can I shorten that time so that setup() will run sooner?  I measure this time using a power supply and others appear to measure similar times with their eyeballs.

I understand that 328 microcontrollers can be made to boot quicker (almost instantly from a human perspective) using different bootloaders for example, but I haven't found one for the M0 SAMD21 nor another method.

The code isn't relevant because the blink example shows the same timeframe, but here's another example:

    //no libraries, global variables, nothing.
    setup(){
    digitalWrite(LED_BUILTIN, HIGH);
    }

    loop(){
    }

sender: assistant

body:
After consulting the datasheet for the SAMD21, I verified that the processor starts immediately once the internal clocks are stable. This happens quickly. The reset vector directs execution to the Arduino bootloader, which certainly spins while waiting for the Arduino programmer to connect. If that does not happen during that delay, the bootloader jumps to the resident application. The delay with no activity is how the bootloader determines that you want to start the application. You can eliminate that by programming the processor using a hardware programmer/debugger, and getting rid of the Arduino bootloader.<p>
The hardware programmers also allow source level breakpoint debugging. You just have to learn to use a decent IDE programming environment. A good prgrammer will cost you around $160.


message:
'for loop' seems to change the execution of pow()

The first time, pow() works.  But inside of a 'for loop', or again afterwards, it doesn't behave !?  (I'm using a Chinese Pro Mini with Arduino 1.8.16)

**EDIT**
To clarify what I am asking, my question is: "Why does pow() only give the correct answer the first time?"

    uint8_t places;
    uint8_t temp8;
    uint32_t n;

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

    void loop() {
      places  = 5U;

      n = pow( 10, places);
      Serial.println(n);

      Serial.println("\nHERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'\n");

      for (temp8 = 0; temp8 < places; temp8++)  {
        n = pow( 10, places);
        Serial.println(n);
      }

      Serial.println("\nNOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT\n");

      n = pow( 10, places);
      Serial.println(n);

      while(1){}
    }

Here's what the serial monitor shows:

> 100000
>
> HERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'
>
> 99999
>
> 99999
>
> 99999
>
> 99999
>
> 99999
>
> NOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT
>
> 99999

body:
This seems like a case of a confused compiler. More specifically, a
confused optimizer.

On the first occurrence of `pow(10, places)`, the compiler noticed that
`places` must be equal to 5, and so replaced the expression with its
value. If you disassemble the compiled code, you will notice it calls

```c++
Serial.println(100000);
```

On the following occurrences, the compiler did not notice that `places`
can not be anything other than 5, so it did not optimize-out the call to
`pow()`, and got the result 99999.9765625. This is 3 ULPs less than
the exact result, and is consistent with the accuracy you can expect
from `pow()`. Converting to an integer implicitly rounds towards zero,
hence the printed result: 99999.


message:
Random "Compilation error: Error: 13 INTERNAL: exit status 1". No clue how to resolve or even what causes this error

I am a beginner with Arduino. I have a program that is intentionally simple.

The code refuses to compile, spitting out the error `Compilation error: Error: 13 INTERNAL: exit status 1`. I have gotten this type of error multiple times, and I have no idea what causes it, nor how to fix it.

My code is below, by the way.

```lang-c++
void setup() {
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

  analogWrite(10, 10);
}

void loop() {
  digitalWrite(9, HIGH);
  digitalWrite(11, LOW);
  delay(250)
  digitalWrite(9, LOW);
  digitalWrite(11, HIGH);
}
```

body:
The problem with that error message is that you are only reading the very last line. That line says "Oops, it didn't compile". The *actual* error message occurs *before* that. You need to read the entire message to know what is going on.

With your code, for example, you get the following output:

```
blah.ino: In function 'void loop()':
blah.ino:13:3: error: expected ';' before 'digitalWrite'
   digitalWrite(9, LOW);
```

That is your *actual* error. It's telling you that there's a semi-colon missing before the `digitalWrite` on line 13.  There's nothing before the `digitalWrite` on line 13, but, if you look closely, you can see that line 12 has the semi-colon missing from the *end* of it.:

```c++
  delay(250)    <---- missing ;
  digitalWrite(9, LOW);
```

Thus it proves that it is always important to both read and (if you don't understand it) post **the entire error message not just the last line.**


message:
UART connected device communication only works one way

As the title implies, I have two Arduino devices (Uno and Mega) connected to each other over UART (the Mega is hardware UART, the Uno is software UART); I need the Mega to send a command to the Uno, the Uno to perform the command, then the Uno to report back to the Mega when it has finished the task. In this way, I want to implement asynchronous programming to control various light patterns as well as several motors (code not shown, it is unnecessary as the light control is in an isolated segment) without needing any firmware hacking. Sending commands from the Mega to the Uno works, but the reverse is not true, and even polling waitloops do not work. Note that if I send the "affirm" command repeatedly for infinity, but then I hang the code in the Uno and the Mega has no way to stop the barrage; it starts receiving likely random bytes.
My code for the Mega is bulky and multi-file so I can't send the entire thing, but here is the control code:
```c++
lights::showRow(Serial1, 0, 0, 1, 1, 2, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantO(Serial1);
lights::waitUntilFinished(Serial1);
lights::showRow(Serial1, 1, 0, 1, 1, 1, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantX(Serial1);
lights::waitUntilFinished(Serial1);
```
These commands are implemented by:
```c++
namespace lights{
  boll ready = false;
  boll helloSent = false;
  void chantO(HardwareSerial coms){
    coms.write(1);
  }
  void chantX(HardwareSerial coms){
    coms.write(2);
  }
  void showRow(HardwareSerial coms, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t x3, uint8_t y3){
    coms.write(3);
    coms.write(x1);
    coms.write(y1);
    coms.write(x2);
    coms.write(y2);
    coms.write(x3);
    coms.write(y3);
  }
  void clear(HardwareSerial coms){
    coms.write(4);
  }
  void waitUntilFinished(HardwareSerial coms){
    while (coms.available() == 0){};
    Serial.println("Done.");
    // It can't say anything but "affirmed", so we can save some code by not checking.
  }
}
```
The light code:
```c++
/* To make life easy, I will include a wiring map. Change as needed.
 *  Note that each ring is 24 pixels, and is labeled with the first-position to access it. The next one is obviously going to be the final point.
 ____     ____     ____
/48  \___/72  \   /192 \
\____/   \____/   \____/
 |___     |___     |___
/24  \   /96  \   /168 \
\____/   \____/   \____/
 |___     |___     |___
/0   \   /120 \___/144 \_____[END]
\____/   \____/   \____/
 |
 |
[CONTROLLER]

*/

#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif
#define PIN       6
#define NUMPIXELS 216
#define DELAYVAL 500

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
SoftwareSerial coms(9, 8);
int white = pixels.Color(255, 255, 255);
int red = pixels.Color(255, 0, 0);

int getPixel(uint8_t x, uint8_t y, uint8_t num){
  if (x == 0){
    return 48 - (y * 24) + num;
  }
  else if (x == 1){
    return 72 + (y * 24) + num;
  }
  else if (x == 2){
    return 192 - (y * 24) + num;
  }
}

void setRing(uint8_t x, uint8_t y, int color){
  for (int i = 0; i < 24; i ++){
    pixels.setPixelColor(getPixel(x, y, i), color);
  }
}

void setup(){
  pinMode(9, INPUT);
  pinMode(8, OUTPUT);
  coms.begin(9600);
  Serial.begin(9600);
  pixels.begin();
  pixels.setBrightness(205); // 0.8 * 256 = 204.8; thus this is 80% power. Only 6 can be lit up before you have issues.
}

void loop(){
  if (coms.available() > 0){
    uint8_t d = coms.read();
    Serial.println("He talkin' me");
    Serial.print("He say ");
    Serial.println(d);
    switch (d){
      case 1:
        for (uint8_t x = 0; x < 2; x ++){
          setRing(0, 1, white);
          setRing(1, 0, white);
          setRing(2, 1, white);
          setRing(1, 2, white);
          pixels.show();
          delay(500);
          pixels.clear();
          pixels.show();
          delay(500);
        }
        break;
      case 2:
        for (uint8_t x = 0; x < 2; x ++){
          setRing(0, 0, white);
          setRing(2, 2, white);
          setRing(2, 0, white);
          setRing(0, 2, white);
          setRing(1, 1, white);
          pixels.show();
          delay(500);
          pixels.clear();
          delay(500);
        }
        break;
      case 3:
        Serial.println("Hello, World");
        setRing(coms.read(), coms.read(), red);
        setRing(coms.read(), coms.read(), red);
        setRing(coms.read(), coms.read(), red);
        pixels.show();
        break;
      case 4:
        pixels.clear();
        pixels.show();
        break;
    }
    coms.write(1);
  }
}
```

body:
You are passing your `HardwareSerial` (`Serial1`) objects by value. That means that the object is copied, which is not good - it breaks the connection between the incoming data buffer and the interrupt that loads the RX ringbuffer.

Instead you must either pass *by reference* or *by pointer*.  Personally I prefer pointers because it's what I am used to using, but you can use either.

For example:

```c++
  void waitUntilFinished(HardwareSerial &coms){ // <--- note the &
    while (coms.available() == 0){};
    Serial.println("Done.");
    // It can't say anything but "affirmed", so we can save some code by not checking.
  }
```

I would also consider changing this from a namespace to a class and passing the serial object you wish to use as a parameter to the constructor and storing the pointer to it in the class - then you only need ever pass it once and then use that pointer from then on. It would just simplify your code and clean things up somewhat.


message:
fingerprint scanner and GSM module- how do i put a timer condition using if statements?

I am using a fingerprint sensor and GSM module on Arduino MEGA 2560. I want a fingerprint to be scanned every minute, if a minute elapses with no finger scanned, then the next code for the GSM to send an SMS must be executed
[![enter image description here][1]][1]

```
const unsigned long timeLimit = 60000;
unsigned long prevTime;
unsigned long currTime;

void setup() {
  prevTime = millis();
}

void loop() {
  unsigned long currTime = millis();
  getFingerprintID(); //fingerprint func
  if (currTime - prevTime <= timeLimit) {
    if (finger.fingerSearch() == FINGERPRINT_OK) { //if the fingerprint matches
      prevTime = currTime;
    }
  } else {
    Serial.print("MAXIMUM TIME OF ");
    Serial.print(currTime / 1000);
    Serial.print(" SECONDS HAS LAPSED\n");
  }
}
```

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

body:
i cleaned up your version. make sure to update the `prevTime` variable.

```cpp
const unsigned long timeLimit = 60000;
unsigned long prevTime ;
unsigned long currTime;
unsigned long elapsedTime;
int id;
void setup() {
prevTime=millis();
}

void loop() {
  if (fingerprint()){
    currTime = millis();
    elapsedTime = currTime- prevTime;
    if (elapsedTime < 60*1000) {
      prevTime = currTime;
    } else {
       sendSms();
    }
  }
}

void sendSms() {
Serial.print("MAXIMUM TIME OF ");
Serial.print(currTime/1000);
Serial.print(" SECONDS HAS LAPSED\n");
}

bool fingerprint(){
  bool fingerPrintAccepted = false;
  if (finger.fingerSearch()==FINGERPRINT_OK){
    fingerPrintAccepted = true;
  }
  return fingerPrintAccepted;
}
 ```


message:
How to smooth transition to another color NEOPIXELS

I am working on a led strip project and was looking for ways to smooth transition from color to another. Problem is my current method is not so good.

    #include <Adafruit_NeoPixel.h>

    #define LED_PIN     25
    #define LED_COUNT  60
    #define BRIGHTNESS 50

    Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

    bool isFading = false;
    unsigned long startTime;
    uint32_t fadeDuration = 1000;          //fade for 3seconds
    uint32_t startingColor = 0x00ffff00;      // W = 0x00 R=0xFF G=0xFF B=0x00  yellow
    uint32_t targetColor = 0x008f00ff;        // W = 0x00 R=0x8F G=0x00 B=0xff  violet

    void setup() {

      pinMode(25, OUTPUT);
      digitalWrite(25, LOW);

        Serial.begin(9600);
      while (!Serial);
      Serial.println("Starting");

      strip.begin();
      strip.show();
      strip.setBrightness(BRIGHTNESS);

      for (int i = 0; i < strip.numPixels(); i++)
        strip.setPixelColor(i, startingColor);
      strip.show();

      delay(5000); // wait 5 seconds before fading

      isFading = true;
      startTime = millis();
    }

    void loop() {

      if (isFading) { //Fade from yellow to violet in 3 seconds
        for (int i = 0; i < strip.numPixels(); i++)
          strip.setPixelColor(i, getFadeColor(startingColor, targetColor, startTime, startTime + fadeDuration));
        strip.show();
      }

      if ( millis() >= startTime + fadeDuration){; // i intentionally did not include an overflow check to keep it simple
      Serial.println("Fade ended");
      isFading = false;
      }
    }

    uint32_t getFadeColor(uint32_t startColor, uint32_t endColor, unsigned long timeStart, unsigned long timeEnd) {

      uint8_t startWhite  = (startColor >> 24) & 0xff;
      uint8_t startRed    = (startColor >> 16) & 0xff;
      uint8_t startGreen  = (startColor >> 8 ) & 0xff;
      uint8_t startBlue    =  startColor & 0xff;

      uint8_t endWhite    = (endColor >> 24) & 0xff;
      uint8_t endRed      = (endColor >> 16) & 0xff;
      uint8_t endGreen    = (endColor >> 8) & 0xff;
      uint8_t endBlue      = endColor & 0xff;

      unsigned long timeNow = millis();

      uint8_t mapTime = map(timeNow, timeStart, timeEnd, 0, 255);
      uint8_t white   = map(mapTime, 0, 255, startWhite, endWhite);
      uint8_t red     = map(mapTime, 0, 255, startRed, endRed);
      uint8_t green   = map(mapTime, 0, 255, startGreen, endGreen);
      uint8_t blue    = map(mapTime, 0, 255, startBlue, endBlue);

      Serial.print("Time: \t");
      Serial.print(mapTime);
      Serial.print('\t');
      Serial.print("Color now: \t");
      Serial.println(strip.Color(  red,   green,   blue, white),HEX);

      return strip.Color(  red,   green,   blue, white);

    }

The problem im having with this code is visually it would seem that it goes from

Yellow -> White -> violet

and it does not look like a proper transition. I have tried with other colors, and it always seems to pass throught the white color

Are there color theories i can apply for the transition? if you can show me an example sketches on how to do the transition that would also be great.

body:
>  something that will go through the color wheel until the destination color

For that the `FastLED` library has the function `ColorHSV()`, which can be used to define colors using the HSV color space. It stands for **H**ue, **S**aturation and **V**alue (or brightness). Hue is the value representing the position in the color wheel, so that is what you want to change.

Instead of

    strip.Color(  red,   green,   blue, white);

use

    strip.ColorHSV( hue, saturation, brightness );

and change `hue` over time with the algorithm, that you already programmed. When `saturation` and `brightness` stay the same the LEDs will cycle through the color wheel.

Note: The library provides the way from HSV to RGB color (with the above function), but it does not provide a way back. For getting back HSV from an RGB color you would need to write your own conversion function and I don't know how to do that. Though at the current state you don't need it.


message:
RP2040 RTC alarm or similar function

I have a rp2040 board using Earl E. Philhower core. I would like to use the rtc functions just like the one mentioned in the [sdk][1]. Especially the alarm function which is critical in my project.

Supposedly from what i know you have access to all the functions in the sdk on the arduino IDE but when i tried out the example in the sdk it would not compile saying that rtc functions are not declared

    char datetime_buf[256];
    char *datetime_str = &datetime_buf[0];

        datetime_t t = {
                .year  = 2020,
                .month = 06,
                .day   = 05,
                .dotw  = 5, // 0 is Sunday, so 5 is Friday
                .hour  = 15,
                .min   = 45,
                .sec   = 00
        };

    void setup() {
        Serial.begin(9600);
        Serial.println("Hello RTC!");

        rtc_init();
        rtc_set_datetime(&t);
    }

    // the loop function runs over and over again forever
    void loop() {
            rtc_get_datetime(&t);

            Serial.println(datetime_str);
            sleep_ms(100);             // wait for a second
    }

Earl E. Philhower comes with a Time sketch example but problem is i could not find a documentation if a alarm like function exist

    /* Simple demonstration of setting and printing the current time */
    /* The initial time will need to come from an RTC, NTP, or user */

    /* Released to the public domain by Earle F. Philhower, III <earlephilhower@yahoo.com> */

    #include <time.h>
    #include <sys/time.h>

    void setup() {
      Serial.begin(115200);
      delay(5000);
      struct timeval tv;

      tv.tv_sec = 1611198855; // Jan 21, 2021  3:14:15AM ...RPi Pico Release;
      tv.tv_usec = 0;
      settimeofday(&tv, nullptr);
    }

    void loop() {
      time_t now;
      char buff[80];

      time(&now);
      strftime(buff, sizeof(buff), "%c", localtime(&now));
      Serial.println(buff);
      delay(1000);
    }

  [1]: https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__rtc.html

body:
You can try to use my [RP2040_RTC Library](https://github.com/khoih-prog/RP2040_RTC), especially this [RP2040_RTC_Alarm example](https://github.com/khoih-prog/RP2040_RTC/tree/main/examples/Alarm/RP2040_RTC_Alarm).

Both [**ArduinoCore-mbed**](https://github.com/arduino/ArduinoCore-mbed) and [Earle Philhower **arduino-pico**](https://github.com/earlephilhower/arduino-pico) cores are supported.


message:
RP2040 example sketch for dual core queuing

I would like to use queuing because i think its best for my application. I have very limited experience in dual core programming all i want is to hopefully pass 32 bit numbers to the second core properly. queuing seems to be good because it makes sure that the second core who is receiving the data wont miss anything in the sequence if data comes in very fast and core 2 is not ready to process it.

But Im having trouble finding examples. I did [find one][1] but its for a runner queue, which i think is a bit different to what i want

Can anyone show me an example sketch? what i would really like to see is core 1 adding to the queue and core 2 retrieving and removing data from the queue

  [1]: https://github.com/raspberrypi/pico-examples/blob/master/multicore/multicore_runner_queue/multicore_runner_queue.c

body:
This requires a thread-safe queue, where one thread writes to the queue, and another thread reads from the queue.

But I find that with a little care, you can just use a circular buffer where the consumer will increase the head, and the producer will increase the tail.

Something like this:

```
#define MAXSZ 80
static int buff[MAXSZ];
static int head=0;
static int tail=0;

bool full(void)  { return (tail+1)%MAXSZ == head; }
bool empty(void) { return head==tail; }
int  usage(void) { int num = tail-head; return num<0 ? num+MAXSZ : num; }

int produce(int val)
{
   if ( full() ) return -1;
   buff[tail] = val;
   tail = (tail+1)%MAXSZ;
   return 0; // signal success.
}

int consume(void)
{
   if ( empty() ) return -1;
   int val = buff[head];
   head = (head+1)%MAXSZ;
}

```

This will work as long as your compiler doesn't do crazy re-ordering of the operations, and as long as you only touch the head with the consumer, and only touch the tail with the producer. Also, the assignments of head/tail need to be atomic, not split up as: `tail++ ; tail = tail%MAXSZ;`

Come to think of it: if a small capacity suffices, like the 80 from the example code, I would use `int8_t` for head/tail, just in case writing an int to memory gets context-switched between writing the LSB and MSB parts. (I don't know RP2040 well enough to know if writing an int is atomic.)


body:
After digging around i was able to use the queue_t from the sdk. and here it is

    queue_t queue;

    typedef struct queueItem {
      uint32_t value;
    } item;

    const int QUEUE_LENGTH = 128;

    void setup() { //CORE 1 setup

      Serial.begin(9600);
      while (!Serial);
      queue_init(&queue, sizeof(item), QUEUE_LENGTH); //initialize the queue

    }

    void loop() { //CORE 1 TIGHTLOOP

      queueItem temp;
      temp.value = random (1000);
      if (queue_try_add(&queue, &temp)) { //adding items to the queue
        Serial.print("ADDING:\t");
        Serial.println(temp.value);
      }

      else
        Serial.println("FIFO was full\n");
      delay(500);
    }

    void setup1() { // CORE2
    }

    void loop1() {  //CORE 2 TIGHTLOOP

      queueItem temp;
      while (queue_try_remove(&queue, &temp)) { //retrieving item from the queue and deleting it from the queue
        Serial.print("ITEM RETRIEVED:\t");
        Serial.println(temp.value);
      }

      delay(500);

    }


message:
Arduino native USB port and Simulink

I am trying to communicate through the native USB port of the Arduino Due with a PC.

The native port itself works, I have tested this. The problem is, that every time I upload my Simulink model via the programming port onto the Arduino, Windows loses the connection to the native (Bossa) port.

It does not recocnize the port anymore after programming the Arduino with Simulink (Arduino Support Package). The only way to get Windows to recognise the port again is holding reset+erase on the Arduino, which obviously deletes my application.

Do you know any solution? Is this possible to get the native port working for communication after using Simulink to deploy my application?

body: Got it working myself by simply writing the communication part in C for the Due, not using the Simulink blocks.


message:
Arduino data-types

(Im new to the arduino side of stackexchange). Im working on a worksheet for to begin with arduino. I have prior experiences working with arduinos, but problem is new for my field of expertise. Any help will be well appreciated (need help pls uwu)

Problem statement:

[![Problem statement][1]][1]

I tried different methods to obtain those values, but all are to vain.

Methods that I tried so far:
 - using limits.h, floats.h and inbuild variables of those library -- Problem: Im getting wrong minimum and maximum values for float and double: [![Wrong output][2]][2]
Code:
```
#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <math.h>

char fltmax[250];
char fltmin[250];
char dblmax[250];
char dblmin[250];

void sint() {
  Serial.print("Range of signed int: ");
  Serial.print(INT_MIN);
  Serial.print(" to ");
  Serial.print(INT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(int));
  Serial.println(" bytes");
}
void usint() {
  Serial.print("Range of unsigned int: 0 to ");
  Serial.print(UINT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned int));
  Serial.println(" bytes");
}
void schar() {
  Serial.print("Range of signed char: ");
  Serial.print(SCHAR_MIN);
  Serial.print(" to ");
  Serial.print(SCHAR_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed char));
  Serial.println(" bytes");
}
void uschar() {
  Serial.print("Range of unsigned char: 0 to ");
  Serial.print(UCHAR_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned char));
  Serial.println(" bytes");
}
void slong() {
  Serial.print("Range of signed long: ");
  Serial.print(LONG_MIN);
  Serial.print(" to ");
  Serial.print(LONG_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed long));
  Serial.println(" bytes");
}
void uslong() {
  Serial.print("Range of unsigned long: 0 to ");
  Serial.print(ULONG_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned long));
  Serial.println(" bytes");
}
void sshort() {
  Serial.print("Range of signed short: ");
  Serial.print(SHRT_MIN);
  Serial.print(" to ");
  Serial.print(SHRT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(signed short));
  Serial.println(" bytes");
}
void usshort() {
  Serial.print("Range of unsigned long: 0 to ");
  Serial.print(USHRT_MAX);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(unsigned short));
  Serial.println(" bytes");
}
void flt() {
  Serial.print("Range of float: ");
  dtostrf(FLT_MIN, -1, 50, fltmin);
  Serial.print(fltmin);
  Serial.print(" to ");
  sprintf(fltmax,"%e", FLT_MAX);
  puts(fltmax);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(float));
  Serial.println(" bytes");
}
void dbl() {
  Serial.print("Range of double: ");
  dtostrf(DBL_MIN, -1, 50, dblmin);
  Serial.print(dblmin);
  Serial.print(" to ");
  dtostrf(DBL_MAX, -1, 0, dblmax);
  Serial.print(dblmax);
  Serial.print(", which has a storage size of ");
  Serial.print(sizeof(double));
  Serial.println(" bytes");
}

void setup() {
  Serial.begin(115200);
  sint();
  usint();
  schar();
  uschar();
  slong();
  uslong();
  sshort();
  usshort();
  flt();
  dbl();
}

void loop() {
}
```
- Other than using dtostrf(), I found better alternatives at exchange here too such as: https://arduino.stackexchange.com/questions/65813/print-unsigned-long-long-in-esp8266 and https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm

I tried combining both where the test code that I used before actual implementation:

```
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <float.h>
#include <limits.h>

void setup () {
  char str[30];
  Serial.begin(115200);
  snprintf(str, 30, "Value of float max = %e", FLT_MAX);
  /*puts(str);*/
  Serial.print(str);
  return(0);
}
void loop(){

}
```

But ```puts(str)``` is not getting printed in the serial monitor.  Then It clicked, that I have to use Serial.(code) for it to get printed in serial monitor, but it ended up in ```Serial.puts(str)``` code not found. Then I tried just ```Serial.print(str)```, but it just outputs ```Value of float max = ?``` (Initially, before I wrote this problem here, it output ```Va``` only, which i have no idea how it changed, but its still wrong). What do I do now? also, Why cant I use puts to print in serial monitor?

The board im using for this is Arduino UNO (ATmega328P)

  [1]: https://i.stack.imgur.com/OihAW.png
  [2]: https://i.stack.imgur.com/3gDVU.png

body:
There are two issues here.

One is that the Arduino core uses `Serial` to handle serial I/O, rather
than the traditional libc interface (`printf()`, `puts()` and co.). The
avr-libc does provide the traditional stdio functions, but these will
not work unless you tell them where `stdout` is, which is a bit complex.

The take away is to just use the methods of `Serial` for accessing the
serial port.

Then there is the question: why did it print “Value of float max = ?”.
The reason is that the avr-libc does not provide by default support for
formatting floating point numbers with `sprintf()`. That support is
quite expensive in flash space, and it is omitted unless you link with a
specific version of the avr-libc. The simple workarounds are:

 - Use `Serial.print()` to both format and print floating point numbers,
   which is inconvenient for very small or very large numbers.
 - Use [`dtostre()` or `dtostrf()`][dtostr] to format them.

In your case, `dtostre()` is a better fit:

```c++
void setup() {
    char val[40];
    Serial.begin(9600);
    Serial.print("Range of float: ");
    dtostre(FLT_MIN, val, 5, 0);
    Serial.print(val);
    Serial.print(" to ");
    dtostre(FLT_MAX, val, 5, 0);
    Serial.print(val);
    Serial.println();
}

void loop(){}
```

prints:

```text
Range of float: 1.17549e-38 to 3.40282e+38
```

[dtostr]: https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#amgrp67796e0946dab291b611cb32584a051f


message:
sizeof tm struct (datetime) different on ESP32 vs linux64x

I am logging binary data to my SD. I log a datetime object of type 'tm', which is 36 bytes on ESP32.
When I create a datetime of type 'tm' on linux it is 56 bytes.

ESP32 write tm to SD:
[tm datetime = 36 bytes]

    time_t t = std::time(nullptr);
    tm datetime = *std::localtime(&t);
    uint16_t t = file.write((const uint8_t *)&datetime, sizeof(datetime)); // ==36 bytes.

PC
[tm datetime = 56 bytes] (compiled using g++ on linux 64)

    tm datetime;
    std::ifstream fileStream(filename, std::ios::binary);
    fileStream.read((char *)&datetime, sizeof(datetime));

tm is defined in time.h:

    struct tm
    {
      int tm_sec;
      int tm_min;
      int tm_hour;
      int tm_mday;
      int tm_mon;
      int tm_year;
      int tm_wday;
      int tm_yday;
      int tm_isdst;
    #ifdef __TM_GMTOFF
      long __TM_GMTOFF;
    #endif
    #ifdef __TM_ZONE
      const char *__TM_ZONE;
    #endif
    };

My tm struct doesn't have the ['tm_gmtoff' or 'tm_zone'][1], even if it had it wont add up to 56 bytes.

How can my tm be 56 bytes on my PC?
If someone has a better way to log a datetime object, without this issue, let me know.

  [1]: https://stackoverflow.com/questions/13969210/size-of-struct-tm

body:
You can not trust system-level structs for data storage or transfer between different systems. The main reasons are:

1. Different data type sizes (16 / 32 / 64 bit ints, floats vs doubles, etc)
2. Struct element alignment differences owing to underlying architecture optimizations and limitations

Unless you are working with a system struct that is specifically designed for cross-system communication you must define your own and pay special attention to the layout.

1. Always use explicitly sized variable types (uint8_t, int32_t, etc for example) to ensure both ends always agree on data storage sizes
2. Always "pack" your struct (`__attribute__((packed))`) to collapse any specially aligned variables into just the room needed to store those variables

Point 2 requires special attention if you're doing much more than filling the struct and saving / transmitting it. It's advisable to never do more than create the struct instance, fill it, save it, then throw it away. If you start doing advanced operations with pointers to the struct you risk corrupting the packing code if the alignment changes. Also packed structs are often slightly slower to access owing to more complex code usually needed to be used to read / write the individual fields within them (especially if there are no byte-wise operations in the underlying architecture).


message:
Bootload from a Nano to an ATMega328 without a crystal

I have a program to load from a Aduino Nano as ISP to a ATMega328p chip that will have an internal clock at 16M, but I don't have a crystal handy.

Is there a way I can not have to buy a crystal? What should be the circuit's look like?

Here's how I have it hooked:

 1. Ground to Ground (Pin 8)
 2. 5V to VCC (Pin 7)
 3. D10 to Reset (Pin 1)
 4. D11 to MOSI (Pin 17)
 5. D12 to MISO (Pin 18)
 6. D13 to AVCC (Pin 20) (There are no resistors or capacitors, that all was part of a tutorial I cannot find anymore)

So I'm testing now with the basic Blink sketch and here is the resulting terminal comments.

    /Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/b77/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/b77/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/b77/Documents/Arduino/libraries -fqbn=megax8:avr:atmegax8:cpu=328_16 -vid-pid=0403_6001 -ide-version=10816 -build-path /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -warnings=none -build-cache /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avrdude.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -verbose /Applications/Arduino.app/Contents/Java/examples/01.Basics/Blink/Blink.ino
    /Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/b77/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/b77/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/b77/Documents/Arduino/libraries -fqbn=megax8:avr:atmegax8:cpu=328_16 -vid-pid=0403_6001 -ide-version=10816 -build-path /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -warnings=none -build-cache /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5 -prefs=runtime.tools.avrdude.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -verbose /Applications/Arduino.app/Contents/Java/examples/01.Basics/Blink/Blink.ino
    Using board 'atmegax8' from platform in folder: /Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3
    Using core 'megax8' from platform in folder: /Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3
    Detecting libraries used...
    /Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /dev/null
    Generating function prototypes...
    /Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/preproc/ctags_target_for_gcc_minus_e.cpp
    /Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/preproc/ctags_target_for_gcc_minus_e.cpp
    Compiling sketch...
    /Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10816 -DARDUINO_ATmegaxX8 -DARDUINO_ARCH_AVR -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/cores/megax8 -I/Users/b77/Library/Arduino15/packages/megax8/hardware/avr/1.0.3/variants/megax8 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp.o
    Compiling libraries...
    Compiling core...
    Using precompiled core: /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_cache_67558/core/core_megax8_avr_atmegax8_cpu_328_16_27f180324ce8b44e5ad3e6dc83e4e5ee.a
    Linking everything together...
    /Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/sketch/Blink.ino.cpp.o /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/../arduino_cache_67558/core/core_megax8_avr_atmegax8_cpu_328_16_27f180324ce8b44e5ad3e6dc83e4e5ee.a -L/var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627 -lm
    /Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.eep
    /Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-objcopy -O ihex -R .eeprom /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.hex
    /Users/b77/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-size -A /var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.elf
    Sketch uses 924 bytes (2%) of program storage space. Maximum is 32768 bytes.
    Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
    /Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/cu.usbserial-AC012GAB -b19200 -Uflash:w:/var/folders/hv/kcqzq2sd5sl5kwxjrbq96vs80000gn/T/arduino_build_216627/Blink.ino.hex:i

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

             System wide configuration file is "/Users/b77/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
             User configuration file is "/Users/b77/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

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

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

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

    avrdude: AVR device initialized and ready to accept instructions

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

    avrdude: Device signature = 0x000000 (retrying)

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

    avrdude: Device signature = 0x000000 (retrying)

    An error occurred while uploading the sketch
    Reading | ################################################## | 100% 0.05s

    avrdude: Device signature = 0x000000
    avrdude: Yikes!  Invalid device signature.
             Double check connections and try again, or use -F to override
             this check.

    avrdude done.  Thank you.

From what I've seen online, the device signature being 0x000000 could potentially mean that the lack of crystal may make it impossible for me to do the bootloading. The chip is also brand new and I've tested with more than one as I have 3.

My thought is that I probably read the tutorial wrong especially with the AVCC pin?

In any case, **how should I connect a Nano to an ATMega328p without a crystal?**

Thanks for your help!

body:
Alright. After reading some and some more, I was able to notice that SCK, just one pin down from AVCC, was the missing link.

Yet another reminder to properly **read the fabulous manual**.

It looks so easy now.


message:
multiple blinking LEDs at different intervals, morse code A included

Good evening,

I am writing Arduino code to flash multiple LEDS at different sequences from different pins. Everything is working well, however I cant determine how to add in a Morse Code A flash sequence.

Ideally the sequence would go 1s, on 1s off, 3s on, 3s off. then repeat continuously, this would be for a MO (A) bouy

Below is the format I have used for all other lights and works well with 8 different sequences.

```cpp
// A is 1s, B is 2.5s, C is 4s, D is 5s, F is 6s, G is 8s, H is 10s ,

#define aLed 2
#define bLed 3
#define cLed 4
#define dLed 5
#define fLed 6
#define gLed 7
#define hLed 8

void setup() {
  pinMode(aLed, OUTPUT); //pin2 Output
  pinMode(bLed, OUTPUT); //pin3 Output
  pinMode(cLed, OUTPUT); //pin4 Output
  pinMode(dLed, OUTPUT); //pin5 Output
  pinMode(fLed, OUTPUT); //pin6 Output
  pinMode(gLed, OUTPUT); //pin7 Output
  pinMode(hLed, OUTPUT); //pin8 Output

}

void loop() {
  BlinkA(1000);
  BlinkB(2500);
  BlinkC(4000);
  BlinkD(5000);
  BlinkF(6000);
  BlinkG(8000);
  BlinkH(10000);

}
 void BlinkA (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(aLed, !digitalRead(aLed));
 }
}
void BlinkB (int interval){
   static long prevMill = 0;
   if (((long)millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(bLed, !digitalRead(bLed));
  }
 }
  void BlinkC (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(cLed, !digitalRead(cLed));
 }
}
 void BlinkD (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(dLed, !digitalRead(dLed));
 }
}
 void BlinkF (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(fLed, !digitalRead(fLed));
 }
}
 void BlinkG (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(gLed, !digitalRead(gLed));
 }
}
 void BlinkH (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){
    prevMill = millis();
    digitalWrite(hLed, !digitalRead(hLed));
 }
}

body:
> multiple blinking LEDs at different intervals, (*not all periodic*)...

I changed your question hopefully with out changing its meaning.

Based on this question, I would suggest using a [finite state machine][1].  Assuming you are using differently named "BlankI()" functions for each LED, consider adding state machine features to 1 of these functions to control the "*not periodic*" LED.  Consider a state machine with 4 state one for each action:

 0. LED On for 1 second.
 1. LED Off for 1 second.
 2. LED On for 3 seconds.
 3. LED Off for 3 seconds.

Use a counter (either global or static to preserve its value between calls to that function) to track the states.  Use a [switch/case][2] coding pattern to set the "prevMill" to the appropriate time delay for the current state.

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine
  [2]: https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/


message:
I have this issue on Arduino by stating that Adafruit_SSD1306_128x64_i2c_init(); was not declared in the scope, may I ask why?

I have included Adafruit_SSD1306.h file however, it still shows me error  such as 'Adafruit_SSD1306_128x64_i2c_init(); was not declared in the scope' Can anyone enlighten me for this?

body:
Judging by <https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.h> there is no such function in that file, therefore it doesn't exist. That's why you get that error message.

What makes you think such a function would exist? Do you have a link to what led you to believe that?


message:
Arduino ESP32 Import Error No module named serial

I googled and couldn't find a solution to my nice problem:
I have Ubuntu and I want to program a ESP32 ...............
I tried a lot of pip commands ... but it didnt work.
You have any idea how to install the correct packages?
Maybe you can tell me what to do. I am really lost.
I tried it last year and also failed.. Now I want to try it another time :)

       /.arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool.py", line 38, in <module>
            import serial
        ImportError: No module named serial

body:
Open terminal and enter this command `python -m pip install pyserial` it will download `pyserial` for you and you will not receive the above error. The above error is because you don't have `pyserial` installed on the system.

The related documentation for pyserial could be found [here][1]

  [1]: https://pyserial.readthedocs.io/en/latest/pyserial.html


body: Problem resolved, Thank you.  I had installed pyserial.  The error surprisingly was related to the incorrect processor speed (!) in the Arduino IDE.  I have no idea why that would influence the serial/pyserial function.


body:
I had the same issue compiling the CameraWebServer example. I'm using Ubuntu 20.04. The problem occurs during the linking stage when the script invokes python. On my system this runs the system python which is python 2.7.18. I don't think the serial module (supplied by pyserial) is available on Ubuntu 20.04 for python 2.x.

My solution was first to abandon the Arduino IDE and use the arduino-cli to compile the example. I created a virtual python 3 environment, activated it, installed pyserial under the virtual environment and run arduino-cli to make the runtime. The python scripts appear to be compatible with python 3.


body:
Reference: https://www.how2shout.com/linux/how-to-install-python-2-7-on-ubuntu-20-04-lts/

I think Arduino IDE expects Python2 to be installed. My Version is Arduino-1.8.13
You also need Python2 modules so you need to install pip2

:~/curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
:~/sudo python2 get-pip.py
:~/pip2 install pytools
:~/pip2 install pyserial


message:
Issue with input from weighing scale controlling a stepper motor based valve

Hello and thanks for any help in advanced.

What changes do I need to make to my code to get rid of the issue of the valve opening up again at end of cycle in "Auto" function.

Hardware:

 - Arduino Mega
 - Bi-polar Stepper Motor connected to Valve.
 - Weighing scale with TTL output.

Here is my code:
```
//Buttons
#include <mechButton.h> //Button Library
#define BTNa_PIN  10    //Button Pins
#define BTNb_PIN  6
mechButton aButton(BTNa_PIN);  // Set button to pin BTN_PIN.
mechButton bButton(BTNb_PIN);

//Stepper
#include <AccelStepper.h> //Stepper Library
#define dirPin 4          //Stepper Pins
#define stepPin 2
#define motorInterfaceType 1 //Interface set to driver
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);// Create a new instance

//Analog inputs for setting Max and Min Distance
const int analogPin = A0;
const int analogPin2 =A1;

//Data types for Scale Reading for Optima OP900a
char inString[32];
float Input;
float Setpoint;
float fSetpoint;

//Setup
void setup() {

  Serial.begin(9600);           // Fire up our serial monitor for arduino and computer
  Serial3.begin(9600);          //Fire up Serial for Scale for input

  aButton.setCallback(Manual);    // Set up our callback. (Also calls hookup() for idling.)
  bButton.setCallback(Auto);
  stepper.setMaxSpeed(3500);      // Set the maximum speed and acceleration for stepper motor:
  stepper.setAcceleration(5000);

  Setpoint = 4.44;               // Auto parameters
  fSetpoint = (Setpoint*0.9);

}
// Main Loop
void loop() {
   bool abuttonState;
   bool bButtonState;

   idle();                      // Let all the idlers have time to do their thing.
   abuttonState = aButton.trueFalse();    // Have a look at what the current button state is.
   bButtonState = bButton.trueFalse();
}
//Sub Functions
void Manual(void) {
    int maxOpen = analogRead(analogPin);
    maxOpen = map(maxOpen, 0, 1023, 0,100);

   Serial.print("Manual ");
   if (aButton.trueFalse()) {
      stepper.moveTo(0);
      stepper.runToPosition();
   } else {
      stepper.moveTo(maxOpen*40);
      stepper.runToPosition();

   }
}

void Auto(void) {
    int maxOpen = analogRead(analogPin);
    int minOpen = analogRead(analogPin2);
    maxOpen = map(maxOpen, 0, 1023, 0,100);
    minOpen = map(minOpen, 0, 1023, 0,100);

   while (Input < Setpoint){
     readScale();
     if (Input >= fSetpoint && Input < Setpoint){
     stepper.runToNewPosition((minOpen*10)+400);  //Blocking function research work around...
     Serial.print("Min");Serial.print(",");       //debugging
     Serial.println(Input);                       //debugging
     }
     else if (Input < fSetpoint) {
     stepper.runToNewPosition(maxOpen*40);         //Blocking function research work around...
     Serial.print("Max");Serial.print(",");       //debugging
     Serial.println(Input);                       //debugging
     }
     else{
     stepper.runToNewPosition(0);                 //Blocking function research work around...
     Serial.print("Close");Serial.print(",");     //debugging
     Serial.println(Input);                       //debugging
     }
     }
}

void readScale(void){
    byte inChar = Serial3.readBytesUntil('\n', inString, 18); //Scale reading for input
    float scaleInput = atof(&inString[7]);
    Input = scaleInput;
  }
```
I keep getting this strange behavior at the end of the "Auto" function where I am getting false 0.00 from the scale that causes the valve to open and close fully at the end.
```
Max,0.01
Max,0.01
Max,0.01
Max,0.00
Max,0.00
Max,0.00
Max,0.00
Max,0.35
Max,0.42
Max,0.51
Max,0.60
Max,0.66
Max,0.69
Max,0.75
Max,0.83
Max,0.88
Max,0.93
Max,1.00
Max,1.05
Max,1.11
Max,1.16
Max,1.21
Max,1.26
Max,1.32
Max,1.38
Max,1.43
Max,1.48
Max,1.53
Max,1.59
Max,1.64
Max,1.68
Max,1.74
Max,1.80
Max,1.84
Max,1.89
Max,1.94
Max,1.99
Max,2.04
Max,2.09
Max,2.14
Max,2.18
Max,2.23
Max,2.27
Max,2.32
Max,2.37
Max,2.41
Max,2.45
Max,2.50
Max,2.55
Max,2.59
Max,2.62
Max,2.68
Max,2.72
Max,2.76
Max,2.81
Max,2.85
Max,2.88
Max,2.93
Max,2.97
Max,3.00
Max,3.04
Max,3.08
Max,3.13
Max,3.17
Max,3.20
Max,3.23
Max,3.27
Max,3.31
Max,3.35
Max,3.39
Max,3.42
Max,3.46
Max,3.50
Max,3.52
Max,3.55
Max,3.60
Max,3.63
Max,3.66
Max,3.69
Max,3.73
Max,3.77
Max,3.80
Max,3.83
Max,3.87
Max,3.91
Max,3.94
Max,3.95
Max,3.98
Min,4.03
Min,4.06
Min,4.09
Min,4.13
Max,0.00
Max,0.00
Min,4.35
MZ��r��j
Min,4.36
Close,4.46
```

Any suggestions are welcome.

Thanks

body:
There are a few issues here:

* `Serial3.readBytesUntil()` does not add a null character at the end of
  the string. You have to do it yourself if you want a properly
  terminated string.

* You are attempting to read a float starting at the eight byte of the
  string, even if you got less than eight bytes.

* `atof()` does not report errors. If it fails to parse a float, it just
  returns zero.

Just to see what may be going wrong, I suggest this version of
`readScale()` with verbose debug output:

```c++
void readScale(void) {
    byte inChar = Serial3.readBytesUntil('\n', inString, 18);
    inString[inChar] = '\0';  // terminate the string
    const char *start = &inString[7];  // where the number is expected
    char *end;  // where strtod() found it ends
    float scaleInput = strtod(start, &end);
    Serial.print("Scale -> \"");
    Serial.print(inString);
    Serial.print("\", parsed \"");
    *end = '\0';  // terminate the string after the number
    Serial.print(start);
    Serial.print("\" as ");
    Serial.println(scaleInput);
    Input = scaleInput;
}
```


message:
ESP32 TCP disconnect takes very long to be recognized

I'm using the following class to create a stream from a WiFi (server) connection. The client (a PC application) connects to the ESP32 and then issues commands over this connection. This works fine. When the client disconnects gracefully, the connection is reset and the ESP32 is ready for another connection. Only one client can connect at a time, but that's ok for now.

The problem arises when the client disconnects unexpectedly (e.g. if I just kill the process on the PC). The connection remains open for a very long time (10 minutes or so) until the ESP32 detects that the connection died. Within that time, no new connection can be established. In that state, I can still see it printing "Still connected" messages to the serial console, with reducing pace (the number of messages per second drops significantly until it finally gives up).

Is there a way to reduce the timeout on a dead connection? The (working) connection itself might be idle for long times as well, so just because no messages are received doesn't mean we can drop the connection from the ESP32 end.

The `Connect()` function below is called from `loop()` and in normal mode, it just prints "New client connected" and "client disconnected" messages.
```cpp

class WifiCachingStream : public Stream
{
private:
 WiFiServer _server;
 WiFiClient _activeClient;
 bool _hasActiveClient;
public:
 WifiCachingStream(int port) :
 _server(port), _activeClient()
 {
  _hasActiveClient = false;
 }

 void Init()
 {
  _server.begin();
 }

 bool Connect();

 int read() override;

 size_t write(byte b) override;

 void maintain();

 int available() override
 {
  return _activeClient.available();
 }

 int peek() override
 {
  return _activeClient.peek();
 }

 void flush() override
 {
  // Do nothing. The implementation of WifiClient clears the _INPUT_ queue instead of the output queue!
  // _activeClient.flush();
 }

 bool isConnected() const
 {
  return _hasActiveClient;
 }
};

int idx = 0; // for testing only
bool WifiCachingStream::Connect()
{
 if (_activeClient.available() || _activeClient.connected())
 {
  if ((idx ++) % 10000 == 0)
  {
            // For testing: This is printed to the console, even after the communication has been killed on the PC
   Serial.println("Still connected");
            // This (attempts to) send a message over the link, which I would expect to cause the implementation to detect that the connection was dropped.
   Firmata.sendString(F("Still connected"));
  }
  return true;
 }

 _activeClient.stop();
 _activeClient = _server.accept();

 if (_activeClient)
 {
  Serial.println("New client connected");
  WiFi.setSleep(false);
  _hasActiveClient = true;
  return true;
 }

 if (_hasActiveClient)
 {
  _hasActiveClient = false;
  Serial.println("Client disconnected - entering WiFi low-power mode");
  // Low-power mode significantly increases round-trip time, but when nobody
  // is connected, that's ok.
  WiFi.setSleep(true);
 }

 return false;
}

// Other functions irrelevant
```

body:
It's more or less a fact of life that having TCP detect a lost connection (ungraceful disconnect) takes a long time when nothing is being sent over it.

There may be some quaint and curious keepalive and time-out settings in the protocol itself, but implementing a heartbeat (call it an application-level keep-alive) that is sent by the client, and closing the connection from the ESP32-end when no heartbeat/keep-alive message has been received for a certain period, is probably your best bet and it will also give you precise control over the time-out time.


message:
How do I connect 20 outputs and 20 inputs to an Arduino board?

I am a mechanical engineer starting my journey with Arduino, so please excuse me if I put some very generalized message.

* I need to sequentially operate 20 output relays, and then verify if the correct relay has been triggered. If the correct relay was triggered, the next relay will be triggered after a delay of 1-2 seconds.
* I plan to do this with an Arduino Uno so that I can generate error messages if any output has not been triggered.

However, the Uno doesn't have sufficient inputs and outputs to do this. So what are my options?

I want to ask you the below:-
1) If there are I/O expansion boards available for the Uno? If yes, sharing the details will be helpful;
2) A friend recommended to use a multiplexer. Can I use a multiplexer to convert a 4 pin output from the Arduino to 16 pin output, and probably use the saved pins to monitor the inputs? If yes, how?
3) Is there something available like a reverse multiplexer wherein the chip can convert the 16 output signals to 4 pin inputs to the Arduino?

Please let me know the best solution wrt the below parameters - reliability of operation, cost, compactness.

Thanks for your time and support.

body: Look for port expansion boards for the arduino, there are a lot of them many under a dollar. Typically they are in 8 or 16 channel designs. They probably will have PCF8574 or PCF8575 chips. These are low voltage (typically 5V) for the Arduino. You will have to use an interface if it is connected to another voltage. Each of these modules the channels can be individually programmed as an input or output. You can turn on or any of the outputs in any order and pattern you want. These devices operate with the I2C interface so you need only two lines from the Arduino to drive up to 8 of these modules. The pins should be labeled A4 (SDA), A5 (SCL) depending on the model of Arduino you have. Good luck!


body: Instead of using expansion boards, you could use an Arduino Mega or an Arduino Due instead. These have more than enough GPIO pins for 20 inputs and 20 outputs. The price isn't much higher compared to the extra expansion board and the extra wiring required.


message:
PID control doesn't work. After computing the values, the values just become equal to 0

So, I have a working code of the stabilizer project using 2 servo motors, mpu6050, Arduino Uno. However, I want to add PID part for tuning the servo motors movement. I followed the example PID library and just changed the input as data received from the mpu6050 sensor, and output as the data that we send to servo motor. The problem is after adding the PID part project stopped working properly. Servo motors did not react to the accelerometer movement anymore. I tried printing out the values computed by the PID and all of them turned out to be 0 and they don't change even if I rotate the sensor. Can anyone spot the mistake in the code with PID part? I am pretty sure that the rest works perfectly.

```cpp
/*
                        DIY Gimbal - MPU6050 Arduino Tutorial
                        by Dejan, www.HowToMechatronics.com
                        Code based on the MPU6050_DMP6 example from the i2cdevlib library by Jeff Rowberg:
                        https://github.com/jrowberg/i2cdevlib
*/
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"

#include "MPU6050_6Axis_MotionApps20.h"
//#include "MPU6050.h" // not necessary if using MotionApps include file
#include "PID_v1.h"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
#include <Servo.h>
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 mpu;
//MPU6050 mpu(0x69); // <-- use for AD0 high

double Setpointx, Setpointy, Inputx, Inputy, Outputx, Outputy, pidX, pidY;
double Kp = 2, Ki = 5, Kd = 1;
PID myPID0 (&Inputx, &Outputx, &Setpointx, Kp, Ki, Kd, DIRECT) ;
PID myPID1 (&Inputy, &Outputy, &Setpointy, Kp, Ki, Kd, DIRECT) ;
// Define the 3 servo motors
Servo servo0;
Servo servo1;
Servo servo2;
float correct;
int j = 0;

#define OUTPUT_READABLE_YAWPITCHROLL

#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards

bool blinkState = false;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
  mpuInterrupt = true;
}

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
  // join I2C bus (I2Cdev library doesn't do this automatically)
  Setpointx = 10;
  Setpointy = 10;

  myPID0. SetMode (AUTOMATIC);
  myPID1. SetMode (AUTOMATIC);

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif

  // initialize serial communication
  // (115200 chosen because it is required for Teapot Demo output, but it's
  // really up to you depending on your project)
  Serial.begin(115200);
  while (!Serial); // wait for Leonardo enumeration, others continue immediately

  // initialize device
  //Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  pinMode(INTERRUPT_PIN, INPUT);
  devStatus = mpu.dmpInitialize();
  // supply your own gyro offsets here, scaled for min sensitivity
  mpu.setXGyroOffset(17);
  mpu.setYGyroOffset(-69);
  mpu.setZGyroOffset(27);
  mpu.setZAccelOffset(1551); // 1688 factory default for my test chip

  // make sure it worked (returns 0 if so)
  if (devStatus == 0) {
    // turn on the DMP, now that it's ready
    // Serial.println(F("Enabling DMP..."));
    mpu.setDMPEnabled(true);

    attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    //Serial.println(F("DMP ready! Waiting for first interrupt..."));
    dmpReady = true;

    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    // Serial.print(F("DMP Initialization failed (code "));
    //Serial.print(devStatus);
    //Serial.println(F(")"));
  }

  // Define the pins to which the 3 servo motors are connected
  servo0.attach(10); //Z Axis
  servo1.attach(9); //Y Axis
  servo2.attach(8); //X Axis
  servo1.write(90);
  servo2.write(90);
}
// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {
  // if programming failed, don't try to do anything
  if (!dmpReady) return;

  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt && fifoCount < packetSize) {
    if (mpuInterrupt && fifoCount < packetSize) {
      // try to get out of the infinite loop
      fifoCount = mpu.getFIFOCount();
    }
  }

  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();

  // get current FIFO count
  fifoCount = mpu.getFIFOCount();

  // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
    // reset so we can continue cleanly
    mpu.resetFIFO();
    fifoCount = mpu.getFIFOCount();
    Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
  } else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

    // read a packet from FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);

    // track FIFO count here in case there is > 1 packet available
    // (this lets us immediately read more without waiting for an interrupt)
    fifoCount -= packetSize;

    // Get Yaw, Pitch and Roll values
#ifdef OUTPUT_READABLE_YAWPITCHROLL
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

    // Yaw, Pitch, Roll values - Radians to degrees
    Inputx = ypr[2];
    myPID0.Compute();
    Outputx = pidX;
    Inputy = ypr[1];
    myPID1.Compute();
    Outputy = pidY;
    Serial.print("\nX: ");
    Serial.print(pidX);
    Serial.print("\nY: ");
    Serial.print(pidY);
    ypr[0] = ypr[0] * 180 / M_PI;
    pidX = pidX * 180 / M_PI;
    pidY = pidY * 180 / M_PI;
    // Skip 300 readings (self-calibration process)
    if (j <= 300) {
      correct = ypr[0]; // Yaw starts at random value, so we capture last value after 300 readings
      j++;
    }
    // After 300 readings
    else {
      ypr[0] = ypr[0] - correct; // Set the Yaw to 0 deg - subtract  the last random Yaw value from the currrent value to make the Yaw 0 degrees
      // Map the values of the MPU6050 sensor from -90 to 90 to values suatable for the servo control from 0 to 180
      int servo0Value = map(ypr[0], -90, 90, 0, 180);
      int servo1Value = map(pidY, -90, 90, 0, 180);
      int servo2Value = map(pidX, -90, 90, 180, 0);
      // Control the servos according to the MPU6050 orientation
      servo0.write(90);
      servo1.write(servo1Value);
      servo2.write(servo2Value);
    }
#endif
  }
}
```

body:
You seem to have some misconceptions about PID. For explaining I will use a different use case of a PID control, which is easier to understand (and also mentioned in the [documentation of the PID library][1]):

A PID control can be used in any feedback loop system with consistent feedback. When you drive your car you want it to reach a specific speed. For that you press the gas pedal, changing its angle until you reach the target speed. In this scenario you are doing the PID control. The setpoint is the target speed, the input is the actual current speed and the output is the angle of the gas pedal.

You see: Output and input/setpoint don't have the same unit. They are completely different measurements of different things. They are only connected via the feedback loop in the system, meaning that increasing the gas pedal angle will increase the speed of the car. The PID control is then just a formula which involves the actual speed, the desired speed and some scaling variables (Kp, Ki, Kd)(to tune the behavior of the control). And the output of the formula is then the needed gas pedal angle at that time.

**So what does this mean for you?**

- You don't need to convert the output value into an angle. The unit of the output is not important, since the PID will control itself to get to the setpoint. It is more important to tune the PID through Kp, Ki and Kd to get the PID to behave correctly in your system.

- The workflow looks like this:
  1. Set the setpoint variable `Setpointx` to the wanted input value.
  2. Read the input from the MPU and save it to `Inputx`
  3. Call `myPID0.Compute();` to compute the output from setpoint and input.
  4. Read the value from `Outputx` and write it to your servo. The servo movement will then cause a change in the read input in the next loop.
  5. repeat from step 2

- As I currently don't really understand your feedback loop system: Make sure, that the feedback loop is working correctly. An increase in the output should lead to an increase in the input. Make sure it is consistent. Your input value should not have too much noise (or the PID will react to that noise). For testing you might want to tune Kp, Ki and Kd down so that the PID works slower. Then you can see the behavior better. Make sure, that both PID controls aren't influencing each other. They need to be independent.

- Use `myPID0.Compute();` every time you write a new value to your servo and only then. Calling it in between will be just a waste. So it makes sense to use that line somewhere directly before writing to the servo.

---

If it still not works, then you should have a detailed look at the read values and how they relate to the servo angle. Are the requirements above met? Are they stable enough. Is the feedback loop as expected? What does changing Kp, Kd and Ki change in the outcome?

  [1]: https://playground.arduino.cc/Code/PIDLibrary/


body:
This chunk of code is feeding radians into the PID algorithm, and then discarding/overwriting the output with the initialized-to-zero pidX and pidY values.

    ...
    Inputx = ypr[2];
    myPID0.Compute();
    Outputx = pidX;
    Inputy = ypr[1];
    myPID1.Compute();
    Outputy = pidY;
    ...

I'd set the output limits to match the device under control:

    void setup() {
       // join I2C bus (I2Cdev library doesn't do this automatically)
       Setpointx = 10;  // MPU degrees
       Setpointy = 10;  // MPU degrees

       myPID0. SetMode (AUTOMATIC);
       myPID1. SetMode (AUTOMATIC);
       myPID0.SetOutputLimits(0,180); // servo degrees
       myPID1.SetOutputLimits(0,180); // servo degrees
       ...

...and then convert the inputs to match the setpoints, and feed the constrained PID outputs directly to the controls:

    Inputx = ypr[2]*180.0/M_PI;
    myPID0.Compute();
    pid_X = Outputx;
    Inputy = ypr[1]*180/M_PI;
    myPID1.Compute();
    pidY = Outputy;
    ...
    servo1.write(Outputx);
    servo2.write(Outputy);
    ...

It is important to use the `PID.SetOutputLimits(min,max)` so that the PID routine can internally ensure that the outputs don't wander deep into infeasible control regimes.  If you don't call SetOutputLimits(), the default output constraints are 0-255, which would not make sense for a 0-180 servo.

One way to think of your PID constants `Kp = 2, Ki = 5, Kd = 1;` is how big an output unit change (degrees of servo setting) you want to make for a unit of input (MPU radians or degrees?) error, integrated error (error*seconds/5 per https://playground.arduino.cc/Code/PIDLibrarySetSampleTime/), or delta error.  They might need adjusting if the system isn't responding as you like.


message:
Arduino library or code for ESP32 to scan for Bluetooth devices?

Is there some code or library that would allow me to scan for nearby Bluetooth devices using a common ESP32 board ?
I only found similar code for actual Arduino boards.

body: The ESP32 Arduino boards support package includes libraries for ESP32 Bluetooth and BLE. Both libraries have examples which you can find in Arduino IDE Examples menu.


body:
https://github.com/esp32beans/ESP32-BT-exp is a Bluetooth Dual
Mode (classic and BLE) scanner. ESP32-BT-exp works on the original ESP32. No other ESP32 supports BT classic mode.


message:
Should I use C or C++ for a pure code implementation of Arduino?

I have an arduino board (SAMD21 microcontroller) which supports either Arduino or CircuitPython programming. I'd like to program in pure C/C++ instead of Arduino, which seems to be possible without too much trouble. But I'm not sure whether to use C or C++. I thought Arduino was based in C++ but I went to look at some of the library files and they were written in C. Since I'm pretty sure they're not interchangeable, can someone help me learn which language I should use to program my board?

body:
> I thought Arduino was based in C++

There is no language "Arduino" - the Arduino IDE runs a the GNU C++ compiler so "its language" is the language supported by the compiler. It is primarily C++ with a little bit of preprocessing done to your code to help learners get past some of the places they can trip over easily (adding #include statements when it thinks you need them, for instance).

Here is an [answer I wrote to a similar question][1] a few years ago. I think it's relevant to your question.

  [1]: https://arduino.stackexchange.com/a/824/313


message:
how to put whitespace in long Serial println() input

I have this long, Serial.println() that is in quotes, on multiple lines.
Arduino IDE warns: "Missing terminating character".
I am certain there is a way to break the lines up, while having the entire text enclosed in quotes, but I don't remember how.

    Serial.println("
    <?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
    <svg
       xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
        xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"
       id=\"svg8\" version=\"1.1\" viewBox=\"0 0 227.35277 156.29323\"
       height=\"6.1532764in\"
       width=\"8.9508963in\"
       sodipodi:docname=\"etchasketchborder.svg\">
        <defs
         id=\"defs2\" />
      <path
         style=\"fill:#ff0000;stroke:#ff0000;stroke-width:1.32300019;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\"
         d=\"m 12.000819,0.66145838 c -6.2819637,0 -11.33936062,5.05739692 -11.33936062,11.33936062 V 144.29249 c 0,6.28197 5.05739692,11.33936 11.33936062,11.33936 H 215.35224 c 6.28197,0 11.33885,-5.05739 11.33885,-11.33936 V 12.000819 c 0,-6.2819637 -5.05688,-11.33936062 -11.33885,-11.33936062 z M 18.932696,12.696383 H 205.5854 c 5.02557,0 9.07128,4.04571 9.07128,9.071282 v 77.03923 c 0,5.025575 -4.04571,9.071285 -9.07128,9.071285 H 18.932696 c -5.025572,0 -9.0712819,-4.04571 -9.0712819,-9.071285 v -77.03923 c 0,-5.025572 4.0457099,-9.071282 9.0712819,-9.071282 z\"
        />
      <ellipse
         style=\"fill:#ffffff;fill-opacity:1;stroke:#ff0000;stroke-width:1.32300007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\"
         cx=\"21.16666\"
         cy=\"130.59085\"
         rx=\"10.583334\"
         ry=\"9.0714283\" />
      <ellipse
         style=\"fill:#ffffff;fill-opacity:1;stroke:#ff0000;stroke-width:1.32300007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\"
         cx=\"200.62982\"
         cy=\"131.57361\"
         rx=\"10.583334\"
         ry=\"9.0714283\" />
          </svg>
    ");

body:
Ah, I figured it out.
you cant do this:

    Serial.println("foo
                                    bar");

but you can do this:

    Serial.println("Foo"
                    "Bar");

So then in bash I write a little command, to take my svg files, and escape the quotes that exist in the file, then another line to add quotes at the start and end of every newline. then I can just copy paste my svg images into the println() function.

    $ sed -i 's/"/\\"/g' input.svg

and

    $ xargs -I{lin} echo \"{lin}\" <input.svg

respectively.


message:
Arduino Uno stops accepting command from PS3 Wireless controller?? although it remains connected!

so I was trying to control a bot wirelessly with the help of ps3 controller and USB host shield, i am using Arduino UNO as micro-controller. I was able to connect PS3 controller with Arduino and checked all button presses. It works very smoothly for button presses and shows on serial monitor which button was pressed without any lag. But the issue I am facing is that when I try to call any function on button press, the entire function is getting executed and execution comes back to void loop but Arduino stops accepting commands from ps3. But it shows that PS3 is still connected and the connection isn't lost. I went through different blogs and I found out that some say that issue is with new HOST SHIELD library 2.0 and some say that UNO computation takes time.
this is what I have tried.
  ```
#define motopinl1 8
#define motopinr1 9
# define motopine1 10

#define motopinl2 11
#define motopinr2 12
#define motopine2 13

#define val 200

void setup() {
  Serial.begin(115200);
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}

void moveforward()
{

 // digitalWrite(motopinl1,LOW);
  digitalWrite(motopinr1,LOW);
  digitalWrite(motopinl2,LOW);
 // digitalWrite(motopinr2,LOW);
  analogWrite(motopine1,200);
  analogWrite(motopine2,200);
 // digitalWrite(motopinl1,HIGH);
  //digitalWrite(motopinr2,HIGH);

  Serial.println("MoveForward called");
  Usb.Task();

}

void moveBackward()
{

  digitalWrite(motopinl1,LOW);
//  digitalWrite(motopinr1,LOW);
 // digitalWrite(motopinl2,LOW);
  digitalWrite(motopinr2,LOW);
  analogWrite(motopine1,200);
  analogWrite(motopine2,200);
 // digitalWrite(motopinr1,HIGH);
  //digitalWrite(motopinl2,HIGH);

  Serial.println("Movebackward called");
  Usb.Task();
}

void moveleft()
{

  digitalWrite(motopinl1,LOW);
 // digitalWrite(motopinr1,LOW);
  digitalWrite(motopinl2,LOW);
 // digitalWrite(motopinr2,LOW);
  analogWrite(motopine1,200);
  analogWrite(motopine2,200);
 // digitalWrite(motopinr2,HIGH);
  //digitalWrite(motopinr1,HIGH);

Usb.Task();
  Serial.println("Moveleft called");
}

void moveright()
{

 // digitalWrite(motopinl1,LOW);
  //digitalWrite(motopinr1,LOW);
  digitalWrite(motopinl2,LOW);
  digitalWrite(motopinr2,LOW);
  analogWrite(motopine1,200);
  analogWrite(motopine2,200);
 // digitalWrite(motopinl1,HIGH);
  //digitalWrite(motopinl2,HIGH);

  Serial.println("Moveright called");
  Usb.Task();
}

void stopit()
{
  digitalWrite(motopinl1,LOW);
  digitalWrite(motopinr1,LOW);
  digitalWrite(motopinl2,LOW);
  digitalWrite(motopinr2,LOW);
  analogWrite(motopine1,0);
  analogWrite(motopine2,0);
  Usb.Task();
}

void loop() {
  Usb.Task();

  if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
    if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
     // Serial.print(F("\r\nLeftHatX: "));
      //Serial.print(PS3.getAnalogHat(LeftHatX));
      //Serial.print(F("\tLeftHatY: "));
      //Serial.print(PS3.getAnalogHat(LeftHatY));
      if (PS3.PS3Connected) { // The Navigation controller only have one joystick
        //Serial.print(F("\tRightHatX: "));
        //Serial.print(PS3.getAnalogHat(RightHatX));
        //Serial.print(F("\tRightHatY: "));
        //Serial.print(PS3.getAnalogHat(RightHatY));
      }
    }

    // Analog button values can be read from almost all buttons
    if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
      Serial.print(F("\r\nL2: "));
      Serial.print(PS3.getAnalogButton(L2));
      if (PS3.PS3Connected) {
        Serial.print(F("\tR2: "));
        Serial.print(PS3.getAnalogButton(R2));
      }
    }

    if (PS3.getButtonClick(PS)) {
      Serial.print(F("\r\nPS"));
      PS3.disconnect();
    }
    else {
      if (PS3.getButtonClick(TRIANGLE)) {
        Serial.print(F("\r\nTriangle"));
        moveforward();
        PS3.setRumbleOn(RumbleLow);
      }
      if (PS3.getButtonClick(CIRCLE)) {
        Serial.print(F("\r\nCircle"));
        PS3.setRumbleOn(RumbleHigh);
        moveright();
      }
      if (PS3.getButtonClick(CROSS))
      {
          Serial.print(F("\r\nCross"));
          moveBackward();
      }
      if (PS3.getButtonClick(SQUARE))
      {
        Serial.print(F("\r\nSquare"));
        moveleft();
      }

      if (PS3.getButtonClick(UP)) {
        Serial.print(F("\r\nUp"));
        stopit();
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED4);
        }
      }
      if (PS3.getButtonClick(RIGHT)) {
        Serial.print(F("\r\nRight"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED1);
        }
      }
      if (PS3.getButtonClick(DOWN)) {
        Serial.print(F("\r\nDown"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED2);
        }
      }
      if (PS3.getButtonClick(LEFT)) {
        Serial.print(F("\r\nLeft"));
        if (PS3.PS3Connected) {
          PS3.setLedOff();
          PS3.setLedOn(LED3);
        }
      }

      if (PS3.getButtonClick(L1))
        Serial.print(F("\r\nL1"));
      if (PS3.getButtonClick(L3))
        Serial.print(F("\r\nL3"));
      if (PS3.getButtonClick(R1))
        Serial.print(F("\r\nR1"));
      if (PS3.getButtonClick(R3))
        Serial.print(F("\r\nR3"));

      if (PS3.getButtonClick(SELECT)) {
        Serial.print(F("\r\nSelect - "));
        PS3.printStatusString();
      }
      if (PS3.getButtonClick(START)) {
        Serial.print(F("\r\nStart"));
        printAngle = !printAngle;
      }
    }
#if 0 // Set this to 1 in order to see the angle of the controller
    if (printAngle) {
      Serial.print(F("\r\nPitch: "));
      Serial.print(PS3.getAngle(Pitch));
      Serial.print(F("\tRoll: "));
      Serial.print(PS3.getAngle(Roll));
    }
#endif
  }
#if 0 // Set this to 1 in order to enable support for the Playstation Move controller
  else if (PS3.PS3MoveConnected) {
    if (PS3.getAnalogButton(T)) {
      Serial.print(F("\r\nT: "));
      Serial.print(PS3.getAnalogButton(T));
    }
    if (PS3.getButtonClick(PS)) {
      Serial.print(F("\r\nPS"));
      PS3.disconnect();
    }
    else {
      if (PS3.getButtonClick(SELECT)) {
        Serial.print(F("\r\nSelect"));
        printTemperature = !printTemperature;
      }
      if (PS3.getButtonClick(START)) {
        Serial.print(F("\r\nStart"));
        printAngle = !printAngle;
      }
      if (PS3.getButtonClick(TRIANGLE)) {
        Serial.print(F("\r\nTriangle"));
        PS3.moveSetBulb(Red);
      }
      if (PS3.getButtonClick(CIRCLE)) {
        Serial.print(F("\r\nCircle"));
        PS3.moveSetBulb(Green);
      }
      if (PS3.getButtonClick(SQUARE)) {
        Serial.print(F("\r\nSquare"));
        PS3.moveSetBulb(Blue);
      }
      if (PS3.getButtonClick(CROSS)) {
        Serial.print(F("\r\nCross"));
        PS3.moveSetBulb(Yellow);
      }
      if (PS3.getButtonClick(MOVE)) {
        PS3.moveSetBulb(Off);
        Serial.print(F("\r\nMove"));
        Serial.print(F(" - "));
        PS3.printStatusString();
      }
    }
    if (printAngle) {
      Serial.print(F("\r\nPitch: "));
      Serial.print(PS3.getAngle(Pitch));
      Serial.print(F("\tRoll: "));
      Serial.print(PS3.getAngle(Roll));
    }
    else if (printTemperature) {
      Serial.print(F("\r\nTemperature: "));
      Serial.print(PS3.getTemperature());
    }
  }
#endif
}```

I haven't connected to bot. I was checking whether function are being executed on button press or not or serial monitor. so there cannot be issue of power supply. problem is PS3 still remains connected, also line of execution returns to void loop, then why it stops further commands. please please do suggest any ideas and methods by which I can solve this problem. thank you.

body: I found that when you use delay inbuilt function, it completely blocks Arduino from accepting any command, that causes some communication barrier. Although ps3 remains connected, it doesn't accept commands. so all you have to do is to remove all delays from your function and build logic based Millis.


message:
Can pin mode damage Arduino with connected electronics?

I am not that experienced with electronics, so this might be a silly question. But I dont know. Assume that I have connected some electronic circuit (transistors, leds, anything else) to the Arduino pins, is there any chance that I damage the hardware if I change the pinmode to input? What role do the integrated pullup/pulldown resistors play? Basically, is it possible to create some "unintended" flow of current, that damages the board or external hardware, if I change the pinmode or disable/enable the pullup/pulldown resistors (or something else that I dont know about)? Can I break the hardware by programming mistakes?

body:
You are coming with some good questions about a complicated subject. You will be going through a learning process. If you do not violate the design parameters of the micro (voltage and current to name a few) you normally will not damage it. Knowing all of those parameters and what the circuirity surrounding the micro has a huge impact on your what can damage your micro and design. Without a schematic, this will change with each circuit and integration, it is impossible to give a definitive answer but I will take a SWAG.

Question: "is there any chance that I damage the hardware if I change the pinmode to input?"  and it depends on what mode the pin is in before you change it and what is connected to the pin. Generally you will not damage it assuming your voltages are equal to or less then the voltage supplying the microprocessor and the pin is not connected to an inductive component. You can get changes in your external hardware.

You ask "Can I break the hardware by programming mistakes?". Again I cannot give a definitive answer unless the circuit and what is connected is known. LEDs etc are generally no problem. If in doubt place a resistor in series with the load, something in the range of 330 to 500 ohms and see what happens. If you turn on some external device that damages stuff that is one possibility.

You ask: "if I change the pinmode or disable/enable the pullup/pulldown resistors..."Probably not but it depends on what is connected to the pins. Generally if the pull up resistors are needed such as for a button turning them off will cause some intermittent problems where it is on then off but that will not damage the micro, the effect on external devices is unknown as are the devices.

This stuff is not going to be assimilated in a few days but over a much longer period. There is always more then one way to do a project, the best is probably what you decide. You will make mistooks, and possibly destroy some of your Arduinos, this is to be expected, that is why I have spares. The most important part of the process is to enjoy and have fun.


message:
Can a power cut damage the software?

When unplugging the power source of a device that is writing some data "A" to an SD card, also other data "B" might get corrupted. (This is detailed [here][1].)

Regarding Arduino projects *without* an SD card, is it OK to remove the power source of Arduino microcontrollers anytime because the memory inside them uses a different technology than SD cards do (what are the names or differences of the respective technologies)?

Or are there several entirely independent memories - one for data and one for software/sketches?

Or do Arduino projects have to be programmed such that there are periods without data-writing and an LED indicates when it is safe to cut off the power?

  [1]: https://raspberrypi.stackexchange.com/questions/50345/is-it-okay-to-just-pull-the-plug/50347#50347

body:
First we need to look at the different memory technologies in a microcontroller:
- First you have the flash memory. This is where the program is saved, but it can also be used to hold user data. On AVR based Arduinos it can only be written while programming or by the bootloader. But boards like the various ESPs can also have a little file system in it. Here you can get problems with a power loss while write operations happen.
- The RAM holds the current value of all variables. But it also always looses all data when unpowered. This is normal behavior because it is volatile memory. A power loss won't change anything here.
- That leaves us with EEPROM, a non-volatile memory type. You can corrupt your data with a power loss during write operations.

Then we need to look at the data structures. Most memory in Arduinos and similar boards a organized as a simple array of bytes. EEPROM is usually handled this way. If you write a data structure and have a power loss during that time, you must view this data structure as corrupt (for example writing a string with 20 characters, but while writing the 6th byte the power goes out). Other data is not harmed. On the other hand when you use a filesystem in flash like SPIFFS a write action in a file also involves handling a filesystem table. Outage during handling of the table might corrupt your filesystem integrity, thus can also harm other files.

SD cards are a special case, since their internal controllers move the data around to some unknown algorithm to implement wear leveling. This is not done with standard microcontrollers (you would need to implement it yourself if needed). The actual memory technology is also just flash, but you don't want to disturb the SD card while its handling its wear level algorithmus. That might corrupt the SD card completely. Also the linked answer talks about the SD card of a Raspberry Pi, which has a complete OS running on it. Running an OS involves way more changing non-volatile data than a microcontroller typically needs. So its way less likely to have the same situations with a microcontroller.

> Or do Arduino projects have to be programmed such that there are periods without data-writing and an LED indicates when it is safe to cut off the power?

Normally that is not needed, though it depends on your application and how the sketch handles the data. Are you saving data to non-volatile memory? How often do you do it? How often do you cut the power? If you are writing to byteswise memory like EEPROM, can you tolerate specific data corruptions? How much data are you writing each time?

Without assessing all these questions you cannot really say. Typically beginners just start without precaution in that direction. When you see problems after replugging, then you still can add an activity LED to the project.


message:
Where does the 5v Output power on the Arduino uno come from?

I am wondering where the extra 5v output power on the Arduino uno come from. Is it directly from the atmega328 microcontroller or from the external power source (usb or 9v battery). Thanks.

body:
If you are connected to USB then it comes direct from the USB port's 5V.

If you have an external power supply connected (either to the barrel jack or to the VIN pin) then it comes from the onboard 5V regulator.

The only thing that ever comes from the ATMega chip is digital signals.