body:
You can use "objcopy" to produce an object file from the file's contents, if you declare it as binary.

    objcopy -I binary echarts.min.js -O <your-bfd-format> echarts.min.js.o

To find out which BFD format you need, run `objdump -t <any object file>` and look at its output.

The resulting object file contains an object named after the input file in the `.data` section. There are 3 symbols in the symbol table:

- _binary_echarts_min_js_start
- _binary_echarts_min_js_end
- _binary_echarts_min_js_size

The "start" symbol marks the beginning of the file's content, and the "end" symbol marks the address **after** the last byte. The "size" symbol is hard to use in C or C++, because it is an absolute value.

Commonly I just use "start" and "end" like this:

```c
extern const char _binary_x_bin_start[];
extern const char _binary_x_bin_end[];
```


sender: user

message:
Properly escaping very large strings

On an ESP8266 I want to create a little webserver that shows me a dashboard with charts and stuff. For this I want to include the [echarts][1]-library as it works offline. To access it the only way I can see this working is that I write:

    const char libData[784674] PROGMEM = "the entire 700 KB library goes here";

And then deliver it on request with `server.on('./echarts.min.js', handleLibRequest)` or something like that.

Now my problem is that in this 700KB of text there are `'` and `"` characters all scattered arround. The C++11 way of `R("hard escapable '"'''" string")` isn't working in my environment. How would one go about this to include this file in my code?

Is there mybe some way utilize the preprocessor for this? Or maybe an online tool that converts `"str" to ['s','t','r']`?

  [1]: https://echarts.apache.org/en/index.html

sender: assistant

body:
Its simple, paste all you page between "()" on the below line

```
const char live_html[] PROGMEM = R"rawliteral(your date here)rawliteral";
```


message:
Variable Fan Controller - Properly Sized Transistor

I would like to a build a temperature sensing variable speed fan controller for my truck. Currently using a purchased 2 speed on/off relay based controller, but my fans are overloading the whole circuit when the controller is powered on during a high speed temperature scenario. On low speed, I have the fans wired in series to spin both slower - works great. Each fan initially draws 100 amps at full 12v. On the low speed (6v/series), they cruise about 20a together. On high speed, they settle in around 25a each.

I am somewhat experienced with arduino and using a few references to build in specific features I want, but here is the main example I am going by.
https://circuitdigest.com/microcontroller-projects/automatic-temperature-controlled-fan-project

My question is around the type and size of transistor that I would need to handle the amount of current these fans draw. Some examples have MOSFET while others have FET or even standard PNP. I am pretty new to working with transistors and can't find any references that make sense. Would love to get a reference to learn this calculation and appropriate type.

Edit: removed picture with incorrect wiring diagram.

body:
Doing a quick search for high-current MOSFET transistors, I ran across the following:

https://www.digikey.com/en/products/detail/ixys/IXFK170N20T/2126313

The important spec here is the Rds ON (max) of 11mOhm @ 60A, 10V

At your peak current of 100A, you would drop 1.1V across the transistor, for a power dissipation of 110W.

The advertised P(max) is 1150W, so assuming the junction temp can be held to under 175C (and with an entire metal truck to use for a heat sink, this shouldn't be a problem) you should be OK with this device.  In the 'cruise' configuration with 25A motor current, you should have no problem controlling the fans.

YMMV ;-)


message:
Can i connect in pin of relay module to Analog pins of arduino instead of digital pin?

Im a complete beginner

Im making a project using relay modules and arduino. but all the digital pins of my arduino are filled.
I wanted to ask if i can use the analog pins to connect my relay module to my arduino? If yes can anyone give me the statements to write high and low using analog.

body:
Yes, you can  use the analog pins as digital pins.
Quoting this [Arduino tutorial][1]:

```
pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH);
```

EDIT:

Here is the code snippet for digital input:

```
pinMode(A0, INPUT);
digitalRead(A0);
```

  [1]: https://www.arduino.cc/en/Tutorial/Foundations/AnalogInputPins


message:
Asymmetric encryption on a Teensy?

I want to monitor an input and then send the information in an encrypted way that can't be easily unlocked even if a malicious actor gets access to the device itself. I'm new to using the Teensy although I have done a few simple things with Arduino microcontrollers. I was hoping to find out if anyone has implemented RSA or other asymmetrical encryption on a Teensy or to figure out if it has enough processing power to make it feasible. I would also accept using other Arduinos (I have an MKR1000 as well), for this but I assume because the Teensy has much better performance it's more likely to be able to do computationally expensive encryption.

This won't need to decrypt anything, it will only be sending data encrypted using the public key of the receiving user.

body:
Teensy4.1 has 55 digital IO (serial) pins at up to 200MHz. The USB port supports 480mbps, and ethernet is 10/100mbps. You're limited to 32 DMA channels, though (complicated but these are used to access onboard peripherals/memory). You don't have much contiguous ram, either.

Now, you haven't explained what you're doing with this data. This matters because even though the CPU is running at 600MHz, asymmetric encryption is slow. Are you trying to perform real-time encrypted communication? Are you just sending or receiving data as well?

Nothing stopping you from asymmetrically encrypting on a Teensy. You can find the source code for the OpenSSL functions RSA_public_encrypt and RSA_private_decrypt.
[This question][1] goes into calculating how many CPU cycles are needed to encrypt X bytes of data.

However, asymmetric encryption has problems: Like I said, it's slow - specifically RSA, and the size of the data you can encrypt depends on the size of your key and padding.

If you want to communicate in something resembling real-time, you want to use hybrid encryption. You should read about how TLS works; the short version is that an asymmetric handshake occurs where the two parties agree on a symmetric key. Once you decide what your data actually is, you can quantize it (eg. TLS 'chunks' are up to 16KB which are then sent as multiple TCP packets) then both parties use the symmetric key to send/receive - which can encrypt large data chunks without issue.

  [1]: https://crypto.stackexchange.com/questions/39923/how-to-calculate-time-taken-by-encryption


message:
Always HIGHT line on Oscilloscope when UNO's Fast PWM TOP ICR1

I have been trying to get an answer my question for a 2 days *already. It's good for knowledge collecting and playing with different things, but there haven't been a solution so far.*

I'm trying to leverage the `HXT500` Servo with the `Fast PWM with a TOP ICR1`

I'm using the `DFRobot DFRduino UNO v3.0 (R3)` analog of the `Arduino UNO`. Based on [the `Atmega 328P-PU`][1]

I have an `Oscilloscope till 5 MHz` as additional tool
## Question ##

 1. Why the `Fast PWM, TOP ISC1` always has the HIGHT only on a oscilloscope
 2. Why the Clock `Prescaler` doesn't work

## My investigations & observations ##

I activated the `PWM with TOP ICR1` but on my oscilloscope showed only a `5V straight line`, I checked different diapasons (horizontal bases) `(1a)`. [Connected to `pins 10 or 9`][2]. I assumed that my UNO works on `1 MHz` (9.2.1 Default Clock Source on Page 37) [and calculated][3] ICR1, OCR1A:B for 0 and 180 degree.

```
     void setup() {
      // all as Ports (for outputs)
     DDRB=0xFF;
     DDRC=0xFF;
     DDRD=0xFF;

      // Table 16-4 on Page 141
      // Fast PWM TOP is ICR1
      TCCR1A|=(0<<WGM10)|(1<<WGM11);
      TCCR1B|=(1<<WGM13)|(1<<WGM12);
      ICR1=2499;

      // Table 16-2 on Page 140
      // Clear OC1A/OC1B on Compare Match, set OC1A/OC1B at BOTTOM (non-inverting mode)
      TCCR1A|=(1<<COM1A1)|(1<<COM1B1);

      // Table 16-5 on Page 143
      // clkI/O/8
      TCCR1B|=(0<<CS12)|(1<<CS11)|(0<<CS10); // (2a)
    }

    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);
        // 90 degree
        OCR1A=299;
        OCR1B=299;
      delay(1000);
      digitalWrite(LED_BUILTIN, LOW);
        // 0 degree
        OCR1A=49;
        OCR1B=49;
      delay(1000);
    }
```
There I noticed the following issues:

 - I tried different `Prescale`s - there weren't any differences `(2a)`
 - I tried 1 MHz, 8 MHz, 16 MHz - straight HIGHT line

What I have tried next:

 - To use an Example for Servo leveraging from Arduino IDE. It worked but as I understood it worked via Interrupts, not a Hardware solution
 - To use Fast PWM, 9 & 10-bit. `(2a) Prescale`s didn't work - I had movement
 - To use Fast PWM, 8-bit (with code adjustment and wrong angles). `(2a) Prescaler`s didn't work - I had movement

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf
  [2]: http://arduino.zl3p.com/s_infa/pict/arduino_uno_pins.jpg
  [3]: https://docs.google.com/spreadsheets/d/1HVU97dkSNjiICo6uoFb2yLl0UpHilEODdI35nwU51xE/edit?usp=sharing

body:
You might want to set the `TCCR1A` and `TCCR1B` registers to `0` before your code as the [Arduino library sets the WGM10 bit](https://github.com/arduino/ArduinoCore-avr/blob/6ec80154cd2ca52bce443afbbed8a1ad44d049cb/cores/arduino/wiring.c#L305). Or change the first `|=` to a `=`. By leaving the WGM10 bit set, you get fast PWM mode, with TOP set to OCR1A. Combined with your other code, this would result in both pins having a 100% duty cycle.

So use
```
TCCR1A=(0<<WGM10)|(1<<WGM11);
TCCR1B=(1<<WGM13)|(1<<WGM12);
```
or
```
TCCR1A=0;
TCCR1B=0;
TCCR1A|=(0<<WGM10)|(1<<WGM11);
TCCR1B|=(1<<WGM13)|(1<<WGM12);
```
Other than that, you code looks fine, and should give you a 800Hz signal.

PS `"I assumed that my UNO works on 1 MHz"`; no, the UNO runs at 16Mhz.


message:
Is there a limitation of how many instances of the `String` class?

Platform
- Attiny85 with AttinyCores
- 1306 OLED i2c with Tiny4KDisplay

Goal
- using a joystick for menu navigation
  - up/down choose
  - left enter (not finished yet)
  - right back (not finished yet)
  - inverse display the chosen item.

I come from python word which is why I am using a linked list for menu navigation. I found a weird bug that stops me from displaying some of the long text. I found that if the defined Nodes over a certain amount of number, item text over 5 chars will not display. I don't know why this is related to the number of instances. I managed to narrow down the range of the bug. In the code. if those 3 lines are commented, all the items are displayed correct, if not, only up to `ccccc` but not `dddddd`.

[![without the 3 lines, (commented)][1]][1]
[![with the 3 lines, (uncommented)][2]][2]

The flash and RAM consumption of the failure situation is
```
Sketch uses 5180 bytes (63%) of program storage space. Maximum is 8192 bytes.
Global variables use 280 bytes (54%) of dynamic memory, leaving 232 bytes for local variables. Maximum is 512 bytes.
```

My code is as below. I broke it into parts to highlighted the problem. But it is a continuous file actually.

Thank you for any insight.

PS: I know there are methods that avoid oop, but I think this weird bug is so close to being fixed, (or proved to be an actual bug in the package/compiler). So I would like to pursue an answer to this question.

Update:

I tried to use another method that uses a List of Strings instead of a class to achieve the same function. The Bug is still there. I guess it is because there are too many instances of String. The question is not changed: "Is there a limitation of how many instances of the `String` class?".

```c

#include <Tiny4kOLED.h>

// input setup
int x = 512;
int y = 512;
int lastx = 512;
int lasty = 512;

bool left = false;
bool right = false;
bool up = false;
bool down = false;

char input() {
  x = analogRead(A2);
  y = analogRead(A3);
  if( (lastx > 256) & (x <= 256) ){
    left = true;
  }
  if( (lastx < 768) & (x >= 768) ){
    right = true;
  }
  if( (lasty > 256) & (y <= 256) ){
    down = true;
  }
  if( (lasty < 768) & (y >= 768) ){
    up = true;
  }
  lastx = x;
  lasty = y;
}

// item data
class Node
{
  public:
    String text;
    uint8_t id;
    Node * next;
    Node * previous;
    Node * parent;
    Node * child;
    Node(String s, int n){
      text = s;
      id = n;
      next = NULL;
      previous = NULL;
      parent = NULL;
      child = NULL;
    }
    void append_next(Node * other){
      this->next = other;
      other->previous = this;
      other->parent = this->parent;
    }
    void append_child(Node * other){
      this->child = other;
      other->parent = this;
    }
};

Node main_0("aaa", 1);
Node main_1("bbbb", 2);
Node main_2("ccccc", 3);
Node main_3("dddddd", 4);
Node main_4("eeeeeee", 5);
Node main_5("ffffffff", 6);
```
# This is how the error can be repeated.
```c
/* Uncomment The following 3 lines will cause the problem*/
//Node item_0_0("aaa", 7);
//Node item_0_1("bbb", 8);
//Node item_0_2("ccc", 9);
```
```c
Node * current_sel = (&main_0);
Node * screen_top = (&main_0);

void setup() {
  // oled setup
  oled.begin(0,0);
  oled.enableChargePump();
  oled.setRotation(1);
  // oled.setInternalIref(true);
  oled.enableZoomIn();
  oled.setFont(FONT6X8);
  oled.clear();
  oled.switchRenderFrame();
  oled.clear();
  oled.switchFrame();
  oled.on();
  // oled setup end

  // input setup
  pinMode(A2, INPUT); // X
  pinMode(A3, INPUT); // Y
  // input setup end

  // data
  main_0.append_next(&main_1);
  main_1.append_next(&main_2);
  main_2.append_next(&main_3);
  main_3.append_next(&main_4);
  main_4.append_next(&main_5);
}

void loop() {
  // input read
  input();

  // move current;
  if(up){
    up = false;
    if(current_sel->previous != NULL){
      if(screen_top == current_sel){
        screen_top = screen_top->previous;
      }
      current_sel = current_sel->previous;
    }
  }

  if(down){
    down = false;
    if(current_sel->next != NULL){
      if(screen_top->next->next->next == current_sel){
        screen_top = screen_top->next;
      }
      current_sel = current_sel->next;
    }
  }

  // oled update
  oled.clear();

  oled.setCursor(64, 0);
  oled.print(current_sel->text);

  Node * current_draw = screen_top;
  int i = 0;
  while(true){

    oled.setCursor(0,i);
    if(current_draw == current_sel){
      oled.invertOutput(true);
    }
    oled.print(current_draw->text);
    oled.invertOutput(false);

    if(current_draw->next == NULL){
      break;
    }

    current_draw = current_draw->next;
    i++;
    if(i >= 4){
      break;
    }
  }

  oled.switchFrame();
  delay(50);
}
```

  [1]: https://i.stack.imgur.com/usqFz.jpg
  [2]: https://i.stack.imgur.com/Foab3.jpg

body:
**Do not** use `String`. Ever. Especially not on a chip with such a tiny amount of RAM.

`String` uses dynamic allocation to store the string data in RAM. This is very inefficient, especially when you are working with string literals.

Those literals must be stored in flash, not RAM, so you need to be working with `const char *` and `PROGMEM`, along with the `F()` macro.

When using a chip with only a few hundred bytes of RAM you *need* to be as efficient as you possibly can. You *need* to account for each and every byte you use - and you just can't do that with `String`.

---

As an example, let's look at what this does:

```c++
Node main_5("ffffffff", 6);
```

You have a string of 8 characters plus a NULL terminating character. That's 9 bytes.  Those 9 bytes are copied into RAM at boot time. Current total 9 bytes. You then convert that to a `String` and copy the character data into that temporary object - that's now 18 bytes plus the size of the `String` object. Then:

```c++
text = s;
```
You allocate 9 bytes inside the `text` `String` object and copy the data in.  You're now at 27 bytes plus two `String` objects (one of which you created earlier in your class).  A little over 5% of your entire memory just to move text around the place.  A third of that you claw back from your heap as the objects leave scope, but then you have a hole in your heap. And this is the last set of operations after you've already made a complete mess of your heap with the earlier ones.

Whereas

```c++
const char main_5[] PROGMEM = "ffffffff";
```
uses just 2 bytes of RAM to store the pointer and nothing else.


body:
Each instance of your class uses RAM to store its data. There is *always* a limit to the number of instances; not a fixed number, but a limit imposed by the quantity of RAM available. What Majenko wrote about `String`s applies equally to class instances, if instances are constructed and destroyed during the run.

A fixed number of global instances, as you have used, is more efficient but there is still only room for so many. Complicating this is the fact that RAM is a shared resource. Static variables like globals, including global class-instances, are assigned from the bottom of RAM, upward, after all of the compilations are done and before uploading to the chip. The program's run-time stack, which includes each function's automatic local data, builds from the top of RAM, downward, during the run. Stack memory is assigned and released as each function is entered and exited. But when a function calls a function which calls a function, which calls ..., the stack has to keep growing until the final call returns and the previous calls may then return.

If you attempted to define a large number of instances with a small amount of RAM available, the IDE (actually the linker, which puts together all of your code and the libraries you use) would catch the problem before your program gets uploaded.

But in the case where there all of the RAM didn't get assigned at compile- or link-time, then at run time, your stack could still possibly grow downward until it collides with the global- and fixed-data at the bottom of RAM, with (unfortunately) unpredictable results, but definitely unexpected and improper operation.

Update:
I did gloss over some details, as two commenters were kind enough to point out. Yes, the heap - memory allocated dynamically at run-time - occupies the space just above the globals and other static memory allocations. Heap space can grow, the more it is used to allocate and de-allocate memory, and being low in memory, would have to grow upward, toward the stack. It is the heap where String data is allocated and re-allocated and is one of the reason's behind Majenko's warning against using the String type - especially if the strings will be edited at run time, which results in re-allocation that may not be obvious.

It is also worth noting that any class uses memory, whether Strings or user defined classes such as the OP's nodes. They are both classes and their instances will be handled similarly.

Also in OP's case, note that the class instances are allocated 'statically' - all instances are known and allocated during the run setup and not altered during the run. In 'quotes', because the allocation actually does happen during run-time, but at the very start of the run, and prior to the user sketch receiving control.


message:
How do I make two (or more) pins available on my server url?

I have a webserver configured on my esp8266 with is set to fire off electrical relay0 on my 8 port relay board.
The device initializes relay0 perfectly and without errors.
But when I configure the second relay1, i get no response from my second url.

    //note, when you write to low, you turn the switchport on. It's backwards for some reason
    #include <ESP8266WiFi.h>
    #define statusLed 2   // built-in led for the ESP8266-12

    const char* ssid = "myssid";
    const char* password = "mypass";

    int switchPin0 = 16;
    int switchPin1 = 5;
    int switch0;
    int switch1;

    WiFiServer server(80);

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

      pinMode(statusLed, OUTPUT);
      pinMode(switchPin0, OUTPUT);
      digitalWrite(switchPin0, HIGH);

      // Connect to WiFi network
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      digitalWrite(statusLed, HIGH);
      Serial.println("");
      Serial.println("WiFi connected");

      // Start the server
      server.begin();
      Serial.println("Server started");

      // Print the IP address
      Serial.print("Use this URL : ");
      Serial.print("http://");
      Serial.print(WiFi.localIP());
      Serial.println("/");

    }

    void loop() {
      // Check if a client has connected
      WiFiClient client = server.available();
      if (!client) {
        return;
      }

      // Wait until the client sends some data
      Serial.println("new client");
      while(!client.available()){
        delay(1);
      }

      // Read the first line of the request
      String request = client.readStringUntil('\r');
      Serial.println(request);

      client.flush();

      // Match the request

      int value = HIGH;
      if (request.indexOf("/SWITCH=0") != -1){
        digitalWrite(switchPin0, LOW);
        digitalWrite(statusLed, LOW);   // blink led
        delay(1);
        digitalWrite(statusLed, HIGH);
        //set water pump time here
        delay(8000);
        digitalWrite(switchPin0, HIGH);
        value = HIGH;
        ++switch0;
      } else if (request.indexOf("/SWITCH=1") != -1){
        digitalWrite(switchPin1, LOW);
        digitalWrite(statusLed, LOW);   // blink led
        delay(1);
        digitalWrite(statusLed, HIGH);
        //set water pump time here
        delay(8000);
        digitalWrite(switchPin1, HIGH);
        value = HIGH;
        ++switch1;
      } else {

        }

      // Return the response
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println(""); //  do not forget this one
      client.println("<!DOCTYPE HTML>");
      client.println("");

      client.print("Switch pin is now: ");

      if(value == HIGH) {
        client.print("Off");
      } else {
        client.print("On");
      }
      client.println("

");
      client.println("Switch 0");
      client.println("Click here  to send a measured amount
");
      client.println("Number of times plant 0 has been fed is ");
      client.println(switch0);
      client.println("

");
      client.println("Switch 1");
      client.println("Click here  to send a measured amount
");
      client.println("Number of times plant 1 has been fed is ");
      client.println(switch1);
      client.println("");

      delay(1);
      Serial.println("Client disconnected");
      Serial.println("");
      digitalWrite(statusLed, LOW);   // blink led
      delay(1);
      digitalWrite(statusLed, HIGH);

    }

my counter will update, but the relay pin never fires for relay1. relay0 works fine. I can swap the ports and then the second relay will work and not the first. I just can't manage both.

How do I get a second (or more) relay ports to initialize via webpage?

body:
It looks like you forgot to initialize `switchPin1` to be an output.

Add the following to your `setup()` (for example, right after the corresponding initialization commands for `switchPin0`):

    void setup() {
        ....
        pinMode(switchPin1, OUTPUT);
        digitalWrite(switchPin1, HIGH);
        ....
    }


message:
Using a Encoder Feedback to control a 360 degree servo

I pieced together a sketch to control a servo that turns an encoder. Eventually I plan to build this up to a DMX input, so I have the input range from 0 - 255.
Basically, it's supposed to ask you to input range from 0 to 255 and then it changes that value to 0 -180 for servo control. Then it's supposed to compare that to the encoder and rotate the correct direction until the encoder value and requested values match. I'm just learning arduino so I'm sure I've made some mistake. Here is the code:

```c++
// Rotary Encoder Inputs
#define inputCLK 22
#define inputDT 24

#include <Servo.h>

Servo myservo;
int pos = 90;
int counter = 90;
int currentStateCLK;
// Setup Serial Monitor

// Read the initial state of inputCLK
// Assign to previousStateCLK variable
int previousStateCLK;

String encdir ="";

void setup() {
  Serial.begin (9600);
  previousStateCLK = digitalRead(inputCLK);
  // Set encoder pins as inputs
  pinMode (inputCLK,INPUT);
  pinMode (inputDT,INPUT);
  myservo.attach(9);

void loop() {
  Serial.println("Enter a number from 0 to 255");
  while (Serial.available() == 0); {}
  int val = Serial.parseInt(); // read int or parseFloat for ..float...
  long Pos = val;
  Pos = Pos * 180 / 255;
  Serial.println(val);
  Serial.println(Pos);
  if (Pos > Counter) {
    myservo.write 0;
  }
  if (Pos < Counter) {
    myservo.write 180;
  }
  if (Pos = Counter) {
    myservo.write 90;
  }

  // Read the current state of inputCLK
  currentStateCLK = digitalRead(inputCLK);

  // If the previous and the current state of the inputCLK are different then a pulse has occured
  if (currentStateCLK != previousStateCLK) {
    // If the inputDT state is different than the inputCLK state then
    // the encoder is rotating counterclockwise
    if (digitalRead(inputDT) != currentStateCLK) {
      counter --;
      encdir ="CCW";
    } else {
      // Encoder is rotating clockwise
      counter ++;
      encdir ="CW";
    }
    Serial.print("Direction: ");
    Serial.print(encdir);
    Serial.print(" -- Value: ");
    Serial.println(counter);
  }
  // Update previousStateCLK with the current state
  previousStateCLK = currentStateCLK;
}
```
So when I run the program, I'm not getting any movement on the servo.

Thanks.

body:
Your initial problem is here:

```c++
  if (Pos = Counter) {
```

If the result (fall through) of assigning Counter to Pos is non-zero then stop.

That's not right.  You're assigning, not comparing. In C `==` is comparison and `=` is assignment.  Instead it should read:

```c++
  if (Pos == Counter) {
```

However there is another, more sneaky, problem with your code - the usage of `Serial.parseInt()`.

If you send the string `56\r\n` as you typically would (with the CR+LF line ending typical of serial communication) then `parseInt` will read the first portion of the string up to and including the first non-digit character and parse it as a number. That is, the `56\r` and return the value 56.  Then on the next pass it will see there is still data in the serial buffer and parse it, up to and including the first non-digit character - which is just `\n`. So it will return 0.

That means the first pass through `loop()` you get 56, and then immediately after in the next pass through `loop()` you get 0.

And then, looking at your code a third time, there is another bigger problem: you block waiting for serial input, and your `Pos` variable is local and will be lost each iteration. I think you meant to use `pos`, which is a global variable, and not create a new `long Pos` variable each iteration. And where is `Counter` defined? That surely should be the global `counter` variable?

If you're blocking waiting for serial input then how can you be controlling the servo to get it to the desired location?

So, in short, there are so many errors and problems with your code that you need to go back to basics and re-think / re-write many portions of it.


message:
How to make motors start when pressing a button, and then go through a cycle with a specific motor order?

I'm very new to arduino and have to work on a project for school. We have connected 3 motors (Servo, Stepper (180 degrees) and a DC motor) to an Arduino Uno, Adafruit motorshield and a pcb. With the pcb we were able to record values of the motors individually and use these values to create a playback motion. The code which we got for the playback motion is below (I've already filled in my values for the 3 motors).

This is what I want to do with the motors:

When I press a button I want to 'start' the cycle of motor motions
1) first the dc motor starts doing the motion based on the chosen values
2) When this stops after 5 seconds I want the servo motor to do it's motion
3) When the servo motor is done, I want the stepper motor to start doing the motion based on the chosen values for 5 seconds and then stop.

We were told not to use a delay and someone suggested to use millis() instead of delay() but since I am a beginner I have no idea where to start.

This is the code:

```
// With this code it is possible to play back recorded motion paths for for motors connected to the Adafruit motorshield

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Servo.h> // this is a library that allows you to drive servo's.

// variables
int modeChoice = 0;

int buttons = A2;  // the three buttons share an analog pin, resitors provide different levels that point to which button is pressed
int slide = A1;    // the slide is read through one analog pin, resitors provide different levels that point to which slide position is current
int rotation = A0; // the pin for the potentiometer

int buttonPressed = 0; // a variable to remember which button is pressed, it is used to control leds and motion memory position management

int buttonValRaw = 0; // a variable to store the raw analog reading of the buttons pin
int slideValRaw = 0;  // a variable to sore the raw analog reading of the slide pin
int valButton = 0;    // a variable to store the interpreted value, the exact pointer to a button
int valSlide = 0;     // a variable to store the interpreted value, the exact pointer to a slide position
int idleState = 0;    // a variable to toggle the servo idle behavior
int resetMotion = 0;  // a variable to return the arrayPosition to 0 if a button is pushed so that the behaviour starts at the beginning
int motionVar1;       // a variable to hold a motion position
int motionVar2;       // another variable to hold a motion position

int mySensorArray[20];  // an array with 20 slots to store raw potentiometer readings (for filtering)
int sensorArrayPos = 0; // the array position of interest.

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

int servoMotionArray_B1[50] = {95, 95, 95, 95, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // paste your 50 values in between the brackets

int DCMotionArray_B1[50] = {-85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85};

//recorded motions for position implementation
int StepperMotionArray_B1[50] = {-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200};

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

int arrayPosition = 0;

unsigned long mainTimer = 0; // a variable to time recording and playback
int timeBetweenSamples = 100; // the time between samples.

unsigned long debounceTimer = 0; // a variable to control a timer interval for debouncing of the buttons
int lastValButton = 0; // a variable to help debouncing of the buttons
int debounceFlag = 0; // another variabel to help debouncing of the buttons

// Setup motors
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect a stepper motor with 16 steps per revolution (2048 positions) to motor port #1 (M1 and M2) -- you need to change this if your stepper is on port #2
Adafruit_StepperMotor *myStepper = AFMS.getStepper(16, 1);
// And connect a DC motor to port M3 -- you need to change this if your DC is on a different port
Adafruit_DCMotor *myMotor = AFMS.getMotor(3);

Servo myservo1;   // servo object (employs the servo library that was included above)

// these are dedicated functions to make the steppermotor move
void forwardstep1() {
  myStepper->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
  myStepper->onestep(BACKWARD, SINGLE);
}

//create aStepper object
AccelStepper aStepper(forwardstep1, backwardstep1); // use functions to step

// setup
void setup() {
  Serial.begin(9600); // start serial communication with 9600 baud rate

  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

  myservo1.attach(9); // attach servo object to pin 9

  // turn on motor M3
  myMotor->setSpeed(0);
  myMotor->run(RELEASE);

  // setup the stepper
  aStepper.setSpeed(0); // this is used in the 'speed' implementation

  aStepper.setMaxSpeed(200.0); // these are used in the 'position' implementation
  aStepper.setAcceleration(100.0);
  aStepper.moveTo(0);

  // synchronize the first timer cycle -- because the timer is starting at zero it generates negative values in the first 100 miliseconds after starting up when going through the timer cycle, creating potential erratic bahaviour-- giving it a delay at the end of the setup loop will eradicate this behaviour
  delay(1000);
}

void doButtons() {
  if (buttonPressed != 0) {
    return;
  }
  else {
    buttonValRaw = analogRead(buttons);
    valButton = map (buttonValRaw, 49, 605, 0, 5);
    int localButtonVal = valButton;

    if (valButton > 7) {
      return;
    }

    if (debounceFlag == 0) {
      debounceTimer = millis();
      debounceFlag = 1;
    }

    if (debounceTimer < millis() - 20) {

      buttonValRaw = analogRead(buttons);
      valButton = map (buttonValRaw, 49, 605, 0, 5);

      if (valButton == localButtonVal) {
        debounceFlag = 0;

        switch (valButton) {
          case 1:
            buttonPressed = 1;
            break;
          case 2:
            buttonPressed = 2;
            break;
          case 3:
            buttonPressed = 3;
            break;
          default:
            buttonPressed = 0;
            break;
        }
      }
    }
  }
}

void loop() {
  doButtons(); // this uses the buttons from the PCB, if you use your own implementation you need to reprogram this function

  if (mainTimer < millis() - timeBetweenSamples) { // sampling only once per interval.
    mainTimer = millis(); // time is rewritten to current millis starting a new interval.

    if (buttonPressed == 0) { //'idle play'
      if (idleState == 0) {
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      else if (idleState == 1){
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      motionVar2 = DCMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      if (motionVar2 < 0) {
        myMotor->run(BACKWARD);
        myMotor->setSpeed(abs(motionVar2));
      }
      else if (motionVar2 >= 0) {
        myMotor->run(FORWARD);
        myMotor->setSpeed(motionVar2);
      }
      arrayPosition++;
      if (arrayPosition > 49) {
        arrayPosition = 0;
        idleState = !idleState;
      }
    }

    if (buttonPressed == 1) { //2nd behaviour
      if (resetMotion == 0) {
        arrayPosition = 0;
        resetMotion = 1;
        myMotor->run(RELEASE); // release the DC motor, otherwise it will continue spinning at the last known RPM
      }
      motionVar1 = servoMotionArray_B3[arrayPosition];
      motionVar2 = StepperMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      aStepper.moveTo(motionVar2);
      arrayPosition++;
      if (arrayPosition > 49) {
        arrayPosition = 0;
        buttonPressed = 0;
        resetMotion = 0;
      }
    }
  }

  // one of these needs to be called to make the stepper motor work, comment out the one you do not need (position or speed)
  //aStepper.run(); //stepper position implementation
  aStepper.runSpeed(); //stepper speed implementation

}
```

body:
You're almost correct already:

    if (millis() - mainTimer >= timeBetweenSamples) {
      mainTimer = millis();
      // executing only once per interval.

      ... the action for current arrayPosition ...

      arrayPosition++;
      if (arrayPosition > 49) {
         arrayPosition = 0;
         buttonPressed = 0; // Show ends
      }
    }


message:
3v3 ESP one way communication with 5 V Arduino?

Perhaps I'm not fully understanding a difference between logic level and the function of the TX and RX pins? I'm just wondering if an ESP can send, one-way, data to an Arduino. (I found that two-way communication would need a logic level converter.)

ESP32 Datasheet
[![enter image description here][1]][1]
https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf#page=42

---

Arduino datasheets do not appear to specify logic level tolerances. It appears from [this Arduino Forum post][2], it would work.

Is it universally assumed that 3v3 will be in tolerance for logic high?
[![enter image description here][3]][3]
https://learn.sparkfun.com/tutorials/logic-levels/all

  [1]: https://i.stack.imgur.com/rO9Xs.png
  [2]: https://forum.arduino.cc/index.php?topic=386191.0
  [3]: https://i.stack.imgur.com/7Y3iU.png

body:
Yes, it will work, but only just. It's borderline.

The ESP32 gives out at most 3.3V as a HIGH signal. The Arduino accepts "above 0.6Vcc" as a HIGH signal. That means that it needs to see a voltage that is at least 60% of the voltage on the Vcc pin (5V pin) of the Arduino.

If the Arduino has exactly 5V then 60% of that is 3V. Since 3.3V is higher than 3V it sees it has a HIGH.

However if the Arduino is being powered by a slightly higher voltage than 5V (some USB ports can give out 5.2V and it's still in spec) and if the ESP32 is being powered slightly below 3.3V, then that 0.3v margin of error gets narrower and narrower. Eventually it disappears and HIGH can no longer be detected.

For example if the Arduino has 5.2V and the ESP32 has 3.1V then the Arduino expects at least 3.12V and the ESP32 gives out no more than 3.1V.

So in  most circumstances it does work, but there are factors that can stop it from working. Those factors can be mitigated by using logic level translation.


message:
SoftWire Library Programming Questions for I2C with Digital Pins

I am trying to use 3 TOF10120 Laser Sensors with one Arduino that all have the same, fixed I2C Address. I don't believe it is possible to change the I2C address of the TOF10120, but if I am wrong, please let me know (also, I need 3 different addresses). This being said, I am trying to use the SoftWire Library (https://github.com/stevemarple/SoftWire - very interesting library, but not great documentation) to help me to use my three sensors with Digital Pins. Does anyone have any experience with the SoftWire Library and how to get readings from a laser sensor?

I can provide the code I have, but it probably wouldn't be very helpful anyway. I am particularly curious as to how to use the DigitalWrite() and DigitalRead() functions for I2C with SoftWire.

Thanks for all the help in advance!

body: You can change the tof10120 to any i2c address between 1 and 254. you need to write the serial string 's7-xxx#' where xxx is the decimal address required (in string form). I wrote a simple python program for the raspberry pi to change my sensor addresses via the Rx Tx.


message:
EEPROM programmer works with serial monitor but not with pySerial

I'm trying to modify Ben Eater's eeprom programmer to flash a 32K eeprom, since the arduino has 32K of program data total the data wouldn't fit in the program. So I wrote a python program using pySerial to send the data in chunks of 256 bytes over serial. The arduino program works correctly when I manually send the data over the serial monitor, and the python program works correctly when I print the values to a console as a test, but when I actually run the program over serial it seems to only write zeros to the eeprom. Additionally, the Rx led on the arduino seems to be lighting up with the correct data, but like I said only zeros are written.

Here's the relevant arduino code:
```
void setup() {
  pinMode(SHIFT_DATA, OUTPUT);
  pinMode(SHIFT_CLK, OUTPUT);
  pinMode(SHIFT_LATCH, OUTPUT);
  digitalWrite(WRITE_EN, HIGH);
  pinMode(WRITE_EN, OUTPUT);

  Serial.begin(57600);
  dataArrPage = 0;

  //delay(1000);
  //Serial.println("Reading EEPROM");
  //printContents();

}

void loop() {
  if (Serial.available() > 0) {
    int len = Serial.readBytes(dataArr, 256);

    for (int i = 0; i < 256; i++) {
      writeEEPROM(dataArrPage + i, dataArr[i]); // writeEEPROM(address, data)
    }
    dataArrPage += 0x100;

    Serial.write('s'); //success, writing is done
  }
}
```
And the relevant python code:
```
import time
import serial
ser = serial.Serial('/dev/ttyUSB0', 57600)
time.sleep(4) # wait for arduino to initialize

filename = input("Enter file name: ")
f = open(filename, "rb")
data = f.read()

page = 0
for x in range(128): # 128 pages in 32K eeprom
    for i in range(256):
        #print(hex(data[(page * 256) + i])) # printing prints the correct values
        ser.write(data[(page * 256) + i])
    page += 1

    #wait until receive 's' from arduino
    while True:
        if ser.in_waiting > 0:
            suc = ser.read(size=1)
            if suc == b's':
                print("Success")
                break

print("Writing done")
f.close()
ser.close()
```
I'm a beginner so sorry if it's something obvious.

body:
I figured out the problem. The for loop was writing one byte at a time, which probably wasn't fast enough and caused a timeout in the arudino. The code is now:
```
page = 0
for x in range(128): # 128 pages in 32K eeprom
    datalst = []
    for i in range(256):
        datalst.append(data[(page * 256) + i])

    ser.write(datalst)

    #wait until receive 's' from arduino
    while True:
        if ser.in_waiting > 0:
            suc = ser.read(size=1)
            if suc == b's':
                print("Success")
                break

    page += 1
```
I also changed the data types in the arduino sketch to use the ones in stdint.h which solved an unrelated bug. Let me know if I should post the full code for both.


message:
How to connect an lcd i2c using only pins A0 and A1 (SDA, SCL, GND, and VCC are given)

I want to know how to connect an lcd i2c, with an led 8x8 matrix at the same time. The problem is, all the analog in pins are used, except A0 and A1. Using this tutorial:

https://www.makerguides.com/character-i2c-lcd-arduino-tutorial/

It says I must have analog pins A0-A2 with nothing connecting, except I have A2 connected, which is why both screens don't work right. So how can I use only pins A0-A1 with an lcd i2c? Thanks.

body:
You may be finding `Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)` confusing.  These refer to the I2C address selection lines of the IO expander (the PCF8574T) used on the I2C LCD display and not to the A0-A2 analog pins of the Arduino itself.

[![Location of address selection jumpers on I2C Adapter][1]][1]

The note `// Wiring: SDA pin is connected to A4 and SCL pin to A5.` **is** referring to the analog pins of an UNO (or Nano) because these pins also happen to carry the ATMega328P's I2C ("Wire") signals.

So there's nothing about using the I2C display that prevents you from using the Analog A0-A2 pins of the Arduino for other purposes.  Only the  Arduino's A4 and A5 pins are used to carry I2C/Wire.

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


message:
Testing 433MHz Transmitter

Folks,

There is a document named "[Complete Guide for RF 433MHz Transmitter.pdf][1]" available in the GitHub.

There is a a connection diagram showing the Data pin of the Transmitter connected to the pin 12 of the Arduino Uno.

The Transmitter sketch given in it is as follows:

```c++
#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

void setup()
{
 Serial.begin(9600); // Debugging only
 if (!driver.init())
 Serial.println("init failed");
}

void loop()
{
 const char *msg = "Hello World!";
 driver.send((uint8_t *)msg, strlen(msg));
 driver.waitPacketSent();
 delay(1000);
}
```

There is no mention of Pin 12 as part of the sketch. I am not sure how the Arduino knows the Transmitter Data input is connected to the Pin 12? Can someone please help?

Ranjith

  [1]: http://www.energiazero.org/arduino_sensori/Complete Guide for RF 433MHz Transmitter.pdf

body:
In [RH_ASK.h][1] is:

```c++
RH_ASK(uint16_t speed = 2000, uint8_t rxPin = 11, uint8_t txPin = 12, uint8_t pttPin = 10, bool pttInverted = false);
```

So the argument has a [default value][2] specified here.  If you don't specify it, it assumes that default.

  [1]: http://www.airspayce.com/mikem/arduino/RadioHead/RH__ASK_8h_source.html#l00278
  [2]: https://en.cppreference.com/w/cpp/language/default_arguments


message:
Use a simple LED with no digital pins to spare

Problem: I've made a circuit consisting of an 8x8 led matrix, which uses all of the digital pins on the Arduino UNO board, and I want to add an LED too it.

I tried looking around the internet but so far, I have not seen any solution on how to use a simple LED with no digital pins to spare.

So I ask, is it possible to connect an LED with no leftover digital pins? I just want to be able to turn the LED on and off.

Thanks.

body:
Just found this:

https://forum.arduino.cc/index.php?topic=311099.0

Turns out you can use the analog pins of an Arduino UNO using this:

```
pinMode(A1,OUTPUT);
digitalWrite(A1,HIGH);
```
You just have to list it as an analog pin. Seems to be working, don't think there are any downsides, as far as I see.


message:
snprintf doesn't display float values

I don't understand why the formatted string is displaying ?? instead of float values.
My code:

    #include <Arduino.h>
    #include <Wire.h>
    #include "SparkFunCCS811.h"
    #include <DFRobot_SHT3x.h>

    DFRobot_SHT3x sht3x(&Wire, /*address=*/0x44, /*RST=*/4);

    //* Get SHT31 readings

    void readSHT(float &temp, float &humid)
    {

        DFRobot_SHT3x::sRHAndTemp_t data = sht3x.readTemperatureAndHumidity(sht3x.eRepeatability_High);

        char shtVal[50];

        if (data.ERR == 0)
        {
            temp = data.TemperatureC;
            humid = data.Humidity;

            Serial.println(data.TemperatureC);
            Serial.println(data.Humidity);
        }

        snprintf(shtVal, 50, "Temp = %f  Humidity = %f", temp, humid);
        Serial.println(shtVal);
    }

    void setup()
    {

        Serial.begin(115200);

        //*Initialize the chip
        while (sht3x.begin() != 0)
        {
            Serial.println("SHT31 Initialization Failed");
            delay(1000);

            Serial.print("Chip serial number");
            Serial.println(sht3x.readSerialNumber());

            if (!sht3x.softReset())
            {

                Serial.println("Failed to Initialize the chip....");
            }
        }
    }

    void loop()
    {

        unsigned long newTime = millis();
        static unsigned long oldTime = 0;

        if (newTime - oldTime >= 5000)
        {

            float temp = 0.0;
            float humid = 0.0;

            oldTime = newTime;

            readSHT(temp, humid);
        }
    }

 & here is the output:
Here is what I get as output:

    21.23
    41.06
    Temp = ?  Humidity = ?

The function readSHT()has no problem displaying the actual values but why the formatted string shows ???. Am I doing something wrong?

body:
The standard avr-libc does not have float support enabled in the `printf` family of functions. This is because float support would bloat your code massively, and most people don't need it.

It is possible to enable it through some black magic (I don't know what, but someone else may), but in general you don't want to since there are better ways.

Typically you would use `dtostrf()` to format your float into a `char` array separately. Or if all you are doing is printing to serial then you wouldn't even format it into a string in the first place.

```c++
Serial.print(F("Temp = "));
Serial.print(temp);
Serial.print(F("  Humidity = "));
Serial.println(humid);
```


message:
Can RX pin(s) be used as TX instead?

1. Title question. I do not need any receive communication pins, only transmission.

Actually, I need as many transmission pins as possible on any Arduino besides a Mega2560 (to re/write the EEPROM of slave devices). A Mega2560 has 23 TX/RX pin pairs.

Maybe I'm misunderstanding serial communication. And maybe some sort of multiplexing deal can work like One-Wire temperature sensors...such as `softwareSerials[x].write()`...

---

    SoftwareSerial serialOne(2, 3); // Software Serial ONE
    SoftwareSerial serialTwo(8, 9); // Software Serial TWO
                         // RX, TX

2. Is there a way to make all the pins using SoftwareSerial TX? Or do half need to be RX?

---

"Just take a better microcontroller, and that is all." - [user1829200][1]

3. What off-the-shelf microcontroller is geared for serial communication?

  [1]: https://stackoverflow.com/a/13415523/14327713

body:
You should be (though I haven't tested it) be able to set the RX pin to an unused pin number, such as 255.  Then the RX pin will do nothing.

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

SoftwareSerial s0(255, 2);
SoftwareSerial s1(255, 3);
SoftwareSerial s2(255, 4);
SoftwareSerial s3(255, 5);
SoftwareSerial s4(255, 6);
// ... etc ...
```

The "can't have more than one instance" thing is to do with reception. You can't have more than one SoftwareSerial instance *receiving* at once - but you don't care about that, since reception is not being used.


body:
One way to communicate Arduino to Arduino device is UART (and Software Serial for additional pins). For the ESP32, it seems this allows 28 TX pins using Majenko's method (in their answer). In other words, slave 28 devices.

After further research, isn't I2C the clear route to go?

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

 - With more slave devices the less times per second to talk to them all
 - The application needs to have all the slave devices execute commands synchronously:
    - At least, the slave devices need to start functioning at the same time.

---

 - How many slave Uno's/Nano's can be connected to an ESP32?

> Each device on an i2c network has a 7-bit address, so a single network theoretically supports up to 128 slave devices. In practice though, the limit is much lower. i2c slave chips often support only 8 different bus addresses, no more than 8 of that chip can be attached to the same i2c network.

https://mindbleach.com/words/2012/10/23/i2c-and-device-limits

Unclear answer:

 - https://forum.arduino.cc/index.php?topic=159860.0
 - https://forum.arduino.cc/index.php?topic=367961.0

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


message:
Why use \" in arduino code?

While working with JSON parsing I noticed that the char type data string is written like this:

    char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
Why there are (escapes) \" ---\" used in the code? Why can't we use the string normally?

body:
> Why there are (escapes) " ---" used in the code? Why can't we use the string normally?

Because escapes are required.

In C `"` means 'The start or end of a string', but `\"` means 'A double-quote character'.

There has to be a way to distinguish a double-quote character from a string delimiter so the compiler knows which is which. Without escapes your string would look like:

```c++
char json[] = "{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}";
```
and the compiler would find the end of the string at the second `"`, and then a load of junk before it finds the end-of-statement `;` character. It can't work out what `sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}"` is supposed to be, since it isn't in the string, but after it.


message:
Can someone help me figure out why my menu gets stuck?

When I try to run my code so far with the menu and select buttons, it seems that it works, except that the main menu will not move past "Main Garden" to "Currants". There's also a problem with the submenu where after the first watering warning, pressing the select button makes it simply return to the main menu without lighting the LED on the LEDPower pin or running that watering routing for the whole watering interval.

The one guess I still haven't tried is that maybe I should change void MainMenu() to a Switch Case structure instead of If-Else?

.

edit:
```
.

body:
Problem One (Menu not moving past `Main Garden` to `Currants`):

`MainOld` is used to increment `MenuState` but `MainOld` never gets incremented, which means it will never have a value greater than 0. Accordingly `MenuState` can
never be greater than 0 + 1.

Problem Two (Sub Menu looping back to main):

'Checking' the state of `LEDPower` like in `Water1()` is not the best way to accomplish what you want to accomplish. It *may* work but is not technically correct as `LEDPower` is a pin state and you never actually read the state.

The other issue in `Water1` is that `previousWaterMillis` doesn't get updated anywhere in your code, which means that anytime `Water1` is called more than 10 seconds after boot your solenoid will activate and then immediately deactivate. I would recommend a `while` loop inside your `Water1` function. ex.

```
void Water1(){
  digitalWrite(Relay1, HIGH);
  unsigned long currentMillis = millis();
  previousWaterMillis = millis();
  int LEDPowerState = digitalRead(LEDPower);

  while(currentMillis - previousWaterMillis <= WateringInterval){
    digitalWrite(LEDPower, HIGH);
    Serial.println("Watering Garden with LED Lit");
    currentMillis = millis();
  }

  digitalWrite(Relay1, LOW);
  digitalWrite(LEDPower, LOW);
  SubMenuState = 0;
  SubMenuOld = 0;
}

^^ This will illuminate your LED and activate the solenoid for the 10 secs you wish to water.


message:
ESP32 USB HID/MIDI library (not the BLE one)

I couldn't find any library to use an "old" ESP32 (not the new ESP32-S2) as an HID connected physicaly to the Usb port (not over BLE pairing) to send keystrokes to the PC ...

Is there any solution? Any code example, so far?

Thanks in advance!

body:
The ESP32 doesn't have USB. You can't do USB communication. All it has is (like the UNO) a USB to UART interface chip. Unlike the UNO this is *not* programmable (more like a cheap Chinese knock-off UNO clone in that respect).

You would need to couple it with a microcontroller that *has* USB and program *hat* to be your USB interface and communicate with it over some other communication medium, such as UART or I2C.


message:
Can i store a SqlLite DB into an (old) ESP32? (not using SD card)

I would like to know if it is possible to store a (little, basic) SqlLite DataBase (or of any other type) into the (old) ESP32.

I don't want to use an SD card for that (for which I already know it is possible).

Thanks in advance for any hint on this

body:
I found these two post to be a useful answer to my question:

* [ESP32: Best way to store data frequently?][1]

* [Sqlite3 Library for ESP32 Arduino Core][2]

  [1]: https://stackoverflow.com/questions/63780850/esp32-best-way-to-store-data-frequently
  [2]: https://www.hackster.io/arun/sqlite3-library-for-esp32-arduino-core-a76ad1


body:
Yes you can - or you can certainly store it. ESP32 can use its flash as a filesystem (SPIFFS, LittleFS, FAT, etc) so you can store whatever data you like on there.

Whether the SQLite library can work with that file is another matter though, and is something you would have to explore yourself.

However for your use case using a database file is a bit silly. If all you want is some pre-defined runtime settings then all you really need is a simple text file. Maybe something like an INI file (key=value pairs) would be plenty for your needs, and pretty simple to parse without any libraries.


message:
SIM800L module on Arduino nano

I am trying to get Arduino nano and SIM800L module working together. I provided the module with the recommended external voltage of 4.0V (documentation states 3.6V - 4.2V) transformed via LM2596. The original source is 5V 3A.

LED on SIM800L blink once a second as stated in documentation when in an unconnected state.

The schema is the following:
```
                  Antena
                   \_/
                    |
Arduino    SIM800L  |  External 4.0V
             NET ---/
             VCC ----- +4.0V
D2 --------- RST
D3 --------- RX
D4 --------- TX
             GND ----- GND
```

I have already tried 3 different libraries for AT communication and also sending raw AT commands using writing to serial manually. I also tried another SIM800L module because I thought the module is faulty.

Here is the dump from serial communication:
```
[551135] ### TinyGSM Version: 0.10.9
[551139] ### TinyGSM Compiled Module:  TinyGsmClientSIM800
AT
��AT
�AT
H�j���[552012] ### Unhandled: Hj
AT
AT-���[552317] ### Unhandled: AT-
AT
��AT
��AT
�Z5
[553228] ### Unhandled: Z5
AT
␚)O���[553532] ### Unhandled: ␚)O
AT
AT���[553836] ### Unhandled: AT
AT
��AT
��AT
�)OK��[554748] ### Unhandled: )OK
AT
���[555053] ### Unhandled: 5
AT
���AT
��AT
��AT
�j�H�[556266] ### Unhandled: jH
AT
CC����[556570] ### Unhandled: CC
AT
AT���[556875] ### Unhandled: AT
AT
��AT
AT
���[557787] ### Unhandled: T
AT
�H����[558091] ### Unhandled: H
AT
AT���[558395] ### Unhandled: AT
AT
��AT
��AT
AT
jRO���[559610] ### Unhandled: jRO
AT
AT���[559915] ### Unhandled: AT
AT
��AT
��AT
AT
�
OK��[561128] ### Unhandled: OK
Failed to initialize SIM800L
```

As you can see the module is trying to negotiate the baudrate. By default, I use speed 9600 as stated in the documentation. When I use a different baudrate the module does not respond at all.

It seems the module replies and sometimes even correctly. Response to `AT` command should be `OK`.

Do you know how do I successfully negotiate the speed and establish reliable serial communication with the module? Do I miss any electrical components in my circuit like a capacitor or resistor? I tried to use capacitor 35V / 3300µF but without any difference. I think my power source is strong enough.

The source code is the following:
```c++
#define PIN_GSM_RST             2
#define PIN_GSM_TX              3
#define PIN_GSM_RX              4
#define GSM_BAUDRATE            9600

#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_DEBUG          Serial
#define TINY_GSM_USE_GPRS       true
#define TINY_GSM_USE_WIFI       false

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <TinyGsmClient.h>
#include <StreamDebugger.h>

SoftwareSerial serial_SIM800L(PIN_GSM_RX, PIN_GSM_TX);
StreamDebugger debugger(serial_SIM800L, Serial);
TinyGsm modem(debugger);
TinyGsmClient client(modem);

void setup() {
    Serial.begin(9600);
    delay(1000);

    Serial.println(F("Serial initialized"));

    serial_SIM800L.begin(GSM_BAUDRATE);
    delay(5000);

    while (!modem.init()) {
        Serial.println("Failed to initialize SIM800L");
    }
}

void loop() {
    //
}
```

body:
Thanks to @PeterPaulKiefer here is the answer.

External power for SIM800L module GND pin needs to be connected to both SIM800L module GND pin and Arduino nano GND pin. (e.g between RST and R2 pin on Arduino nano)

In order for the calling function to work, you also need to use a capacitor on SIM800L VCC and GND pins. I used 35V, 3300µF.

Schema:
```
                  Antena
                   \_/
                    |
Arduino    SIM800L  |  External 4.0V
             NET ---/
             VCC ----- +4.0V
 D2 --------- RST   |
 D3 ---------  RX  === Capacitor (35V, 3300µF)
 D4 ---------  TX   |
GND --------- GND ----- GND
```


message:
Non-blocking SoftwareSerial.Write

How to use `SoftwareSerial.Write` without blocking if buffer is full? `Serial.write` blocks if the buffer is full. So I need to check `Serial.availableforwrite` before calling write to prevent blocking. But there is no `SoftwareSerial.availableforwrite`. How can I use `SoftwareSerial.Write` without blocking?

body:
In short, you don't.

The SoftwareSerial implementation for AVR [doesn't have an outbound buffer][1] at all.
It just turns the interrupts off during each character outbound and it [sends them all immediately][2].

This means a call to SoftwareSerial's write simply **will** block until all of the data you've tried to send has in fact been sent.  If you can't afford to wait for your data to go out on the TX line *now*, then it's up to you to send it later when you *can* afford to wait.

SoftwareSerial has no [flow control][3].  When you write(), the data is sent out on the TX pin regardless of whether anything is present on the other side of the connection.  And when present, the data is still transmitted regardless of whether other side considers itself "ready" to receive.  There's simply no feedback from the receiver to tell the sender to stop.  So SoftwareSerial itself will never block owing to these things.

  [1]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/libraries/SoftwareSerial/src/SoftwareSerial.cpp#L472
  [2]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/libraries/SoftwareSerial/src/SoftwareSerial.cpp#L436
  [3]: https://en.wikipedia.org/wiki/Flow_control_(data)


message:
Where is the positive and negative holes on the arduino mini breadboard?

I have the mini arduino breadboard. The pins go from A to J and 1 to 17. On the larger breadboard, there are symbols + and -. My breadboard doesn't have those two sections to put wires in. Does anyone know what to do?

body:
> Does anyone know what to do?

Do whatever you want to do.

There's nothing special about the +/- rails of a breadboard - they're just chunks of metal that go along instead of across, and are longer, with more holes, and someone has helpfully coloured them red/blue and added some symbols.

If you want a common place for + and - then just choose a common place for + and -.


message:
Adafruit_Arcada' does not name a type;

I am trying to program an adafruit pygamer (which says it's compatible with Arduino). I have added the ZIP folder for the library into the library folder om my PC where all of my folders are supposed to be stored, one thing I managed to find out for a start was that the library folder for the library itself that was installed from GitHub contained a dash in the filename so I replaced that for an underscore. The actual error message that seems to come up now is this:

    'Adafruit_Arcada' does not name a type; did you mean 'Adafruit_SPITFT'?

This error comes up from when I try to use the:

    #include "Adafruit_Arcada.h"

    Adafruit_Arcada arcada;
lines

Within the library folder that I want to try and use there are the code examples within the library folder inside the examples sub-folder

I have tried following a step by step guide into one potential way of trying to solve this problem by looking at a tutorial by adafruit on how to step by step install zip folder libraries. Something tells me though that this error that I am getting is to do with one of the .h or .cpp files within the library itself.

The link for the library itself is here: https://github.com/adafruit/Adafruit_Arcada

In addition, when I look in the `Adafruit_Arcada.h` file I can actually see that there is no `Adafruit_Arcada` class but there is an `Adafruit_SPITFT` one. I know this point might seem like a bit of a no-brainer but I just thought it would be useful to try and find out what could potentially be going on and provide evidence of what I have already tried to do.

When I changed the `Adafruit_Arcada arcada;` to `Adafruit_SPITFT arcada;` (thinking this could potentially resolve the issue because within the `Adafruit_Arcada.h` file there is a class called `Adafruit_SPITFT and not`Adafruit_Arcada`), this brought up another error which was the following:

    simpletest:2:17: error: no matching function for call to 'Adafruit_SPITFT::Adafruit_SPITFT()'

body:
There are some instructions at:

[Pygamer setup][1]

That need to be followed in order to permit the Arduino IDE to work with the Pygamer.  It's not clear that you have followed any or all of these instructions.

I recommend that you carefully follow ALL the steps and then start with the simple example to test that you are building and uploading properly.

Then move on to the Adafruit example that uses the Arcada library.

  [1]: https://learn.adafruit.com/adafruit-pygamer/setup


message:
How much voltage and amps for 2 SG90 servos?

Question is pretty straight forward: How much amps and voltage do I need for 2 SG90 servos? I want to use 4 but you might already know that Arduino Uno only has 2 5V ports.

body:
The SG90 servo datasheet is here:

[SG90 Servo Datasheet][1]

As you can see, the voltage specification is 4.8 - 6.0 Volts.  But you do NOT want to power this or any other servo via the Arduino.  Servos are quite "noisy" electrically and this can cause instabilities with your Uno.

You want to supply power to the servo directly from a +5V power supply.

I don't see the current draw for this servo specified so you will need to do your own measurements based on the loading of the output shaft.  Be aware that these draw more current with increased load on the shaft.

As far as the control signal, the Arduino Uno can certainly drive it via its PWM outputs.

  [1]: http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf


message:
strcmp doesn't seem to work

I'm trying to compare a char array that I'm assembling to a string and I'm having trouble comparing the strings.

I'm getting the data for the char array as a set of bytes and I'm compiling it into a char array like this:

```
void messageHandler(char *topic, byte *payload, unsigned int length)
{
  char buffer[length];
  for (int i = 0; i < length; i++)
  {
    buffer[i] = (char)payload[i];
  }
```

So grabbing each of the ASCII codes and converting it into a character as I add it to the buffer.

After I do that I'm trying to print the buffer to the monitor and then compare it to a string. Though it's not working:

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

I know I'm getting all of those extra characters in the println b/c the buffer doesn't end in `0` so print keeps reading out memory bytes till it hits the zero, but I don't know why `strcmp` isn't showing the buffer matching the string `"ravenclaw"`.

I'm sure it's for the same "missing the null terminator" issue, but I'm not sure how to fix it. Help is appreciated!!

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

body:
You seem to already understand that it's not null-terminated and that's why it's not working the way you expect.  So, I'll take a different tact for "how to fix it".

You can simply not treat the payload as a string, and instead use `memcmp`, as in:

```c++
if (length == 9 && memcmp(payload, "ravenclaw", 9) == 0) {
```

`memcmp` behaves similarly to `strcmp`, except that it isn't looking for a null terminator. It just compares however many bytes (chars) you specify.  In practice you may want to use a variable to hold "ravenclaw" and to strlen() on it rather than specifying the length separately as I've done above, e.g.:

```c++
static const char ravenclaw[] = "ravenclaw";
static const size_t ravenclaw_len = sizeof ravenclaw - 1;
if (length == ravenclaw_len && memcmp(payload, ravenclaw, ravenclaw_len) == 0) {
```

or any number of variations on that which might use `strlen()`, or a pointer rather than array (if not using `sizeof`) or `PROGMEM` with `strlen_P()` and `memcmp_P()` or... etc, etc, possibly putting this into a function so you can reuse it.

---

As a side note, if you know payload contains non-null-terminated text that you want to print, you can use the overload of `write()` that allows you to specify the length.

```c++
Serial.write(payload, length);
```


body:
The easier way to simply the code is to use `strcpy` to create a buffer that is 1 byte longer than the `length` and then terminate it with `\0`.

    void messageHandler(char *topic, byte *payload, unsigned int length) {
      char buffer[length+1];
      strcpy(buffer, (const char*) payload);
      buffer[length] = '\0';

      Serial.println(buffer);

      int matched = strcmp(buffer, "ravenclaw");
    }


message:
Import into Arduino a vintage data bus from TMS1000

For experimentation I want to import or receive into Arduino the output data from a TMS1000 (1980s) data bus.  For model train controller Hornby Zero1, and the bus sends data to receivers, for loco number, speed, direction etc. I have all the data structure etc) Is it feasible  to import to Arduino, and export from the same Arduino back to the original bus.    Just to see it working, and then later experiment with the data in the Arduino.
What libraries would be best ?
Thanks
Charles Harris

body:
You're not going to find any pre-built libraries for this task which is somewhat unusual but not at all impossible.

Basically all you need to do is to connect the TMS1000 address/data and strobe lines to Arduino inputs and write yourself some relatively simple code to detect the various TMS1000 bus states and capture them when they happen.  In order to detect specific events as you have mentioned you will need to know more about the TMS1000 software that's running and what I/O devices that it's selecting.  But again, that's all pretty straightforward.

Keep in mind, however, that you are going to have to perform level shifting on ALL the inputs from the TMS1000.  This old TI chip was implemented using a PMOS (i.e. a predecessor to both NMOS and CMOS) and uses a NEGATIVE power supply instead of the more common today POSITIVE supply.

So rather than being powered by a +5V supply the way an Arduino is, the TMS1000 is powered by a -15V supply.  In this case ground is still at 0V but Vdd is -15V.  That means the I/O signals adhere to a different scheme as noted in the datasheet:

[![TMS1000 Data][1]][1]

You can view the datasheet yourself at:

[TMS1000 Datasheet][2]

But what this means is that a LOW (i.e. Vil) is at -15V and a HIGH (i.e. Vih) is at 0V.  You will need to translate these voltages so that you don't damage either the TMS1000 or the Arduino and you get the correct levels on the pins that you are watching.

The TMS1000 datasheet has some suggested circuits for interfacing to 74LSxx series parts (i.e. 5V logic) which will probably get you started.  Note that the simplest method involves running the 5V logic with its VDD at 0V and it's "ground" at -5V.  While this might seem odd, the Arduino will not know the difference as voltage is always relative.

  [1]: https://i.stack.imgur.com/QDrpF.png
  [2]: http://www.bitsavers.org/components/ti/TMS1000/TMS_1000_Series_Data_Manual_Dec76.pdf


message:
ESP8266 SocketIOclient constant disconnect with Python WebServerSocket

I am writing a program that echos back the message sent to the web socket server on a host machine. When running the ESP module, the connection is established but immediately disconnects as seen in the first image. I originally thought this maybe a result to the host machines firewall, however, using my laptops connection, I was able to produce the desired echo. Is the constant disconnect a result in different protocols or something I am missing?

WebSocketServer on host machine (modeled off example)
```
import asyncio

from autobahn.asyncio.websocket import WebSocketServerProtocol, \
    WebSocketServerFactory

class MyServerProtocol(WebSocketServerProtocol):

    def onConnect(self, request):
        print("Client connecting: {0}".format(request.peer))

    def onOpen(self):
        print("WebSocket connection open.")

    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
        else:
            print("Text message received: {0}".format(payload.decode('utf8')))

        # echo back message verbatim
        self.sendMessage(payload, isBinary)

    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))

if __name__ == '__main__':
    factory = WebSocketServerFactory("ws://127.0.0.1:9000")
    factory.protocol = MyServerProtocol

    loop = asyncio.get_event_loop()
    coro = loop.create_server(factory, '0.0.0.0', 9000)
    server = loop.run_until_complete(coro)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        server.close()
        loop.close()
```

ESP8266 modeled in [arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets/blob/master/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino)
```
#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ArduinoJson.h>

#include <WebSocketsClient.h>
#include <SocketIOclient.h>

#include <Hash.h>

ESP8266WiFiMulti wiFiMulti;
SocketIOclient socketIO;

void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
    switch(type) {
        case sIOtype_DISCONNECT:
            Serial.printf("[IOc] Disconnected!\n");
            break;
        case sIOtype_CONNECT:
            Serial.printf("[IOc] Connected to url: %s\n", payload);
            socketIO.send(sIOtype_CONNECT, "/");
            break;
        case sIOtype_EVENT:
            Serial.printf("[IOc] get event: %s\n", payload);
            break;
        case sIOtype_ACK:
            Serial.printf("[IOc] get ack: %u\n", length);
            hexdump(payload, length);
            break;
        case sIOtype_ERROR:
            Serial.printf("[IOc] get error: %u\n", length);
            hexdump(payload, length);
            break;
        case sIOtype_BINARY_EVENT:
            Serial.printf("[IOc] get binary: %u\n", length);
            hexdump(payload, length);
            break;
        case sIOtype_BINARY_ACK:
            Serial.printf("[IOc] get binary ack: %u\n", length);
            hexdump(payload, length);
            break;
    }
}

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

    //Serial.setDebugOutput(true);
    Serial.setDebugOutput(true);
    Serial.printf("[SETUP] starting up");

    Serial.println();
    Serial.println();
    Serial.println();

      for(uint8_t t = 4; t > 0; t--) {
          Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
          Serial.flush();
          delay(1000);
      }

    // disable AP
    if(WiFi.getMode() & WIFI_AP) {
        WiFi.softAPdisconnect(true);
    }

    wiFiMulti.addAP("ssid", "password");

    //WiFi.disconnect();
    while(wiFiMulti.run() != WL_CONNECTED) {
        delay(5000);
        Serial.println("Retrying...");
    }

    String ip = WiFi.localIP().toString();
    Serial.printf("[SETUP] WiFi Connected %s\n", ip.c_str());

    // server address, port and URL
    socketIO.begin("local host address", 9000);
    // event handler
    socketIO.onEvent(socketIOEvent);
}

unsigned long messageTimestamp = 0;
//int attempts = 0;
void loop() {
    socketIO.loop();
}
```
[![Serial Monitor Output of the ESP8266 ][1]][1]
[![Connection output from Python WSS][2]][2]

  [1]: https://i.stack.imgur.com/AKIR1.png
  [2]: https://i.stack.imgur.com/O7cR9.png

body:
After testing the server on the host machine using an additional computer, I was able to produce the desired output. I would suspect it is an issue within the library or mis-use/understanding. I found a [post](https://forum.arduino.cc/index.php?topic=522526.0) that suggested the library was the problem and ended up using this [library](https://github.com/gilmaimon/ArduinoWebsockets) instead.

Using the [example implementation](https://github.com/gilmaimon/ArduinoWebsockets/blob/master/examples/Esp8266-Client/Esp8266-Client.ino) , I was able to achieve the desired results.


message:
What processor can I replace on behalf of ATMEGA328P, to get more processing power for machine learning in UNO

I wanted to do a machine learning project in Arduino UNO R3. But I came to know that the processor(ATMEGA328P) isn't capable of supporting the processing power needed for machine learning. So is there any other processor that is better than ATMEGA328P for machine learning that is supported in UNO? If not any other way that I can do it?

body:
The Arduino blog recommends this: https://store.arduino.cc/nano-33-ble-sense.

See: https://blog.arduino.cc/2019/10/15/get-started-with-machine-learning-on-arduino/

I know Arduino has been talking about machine learning for about a year or so. Here's the Google search I used to find this: [Arduino machine learning](https://www.google.com/search?q=Arduino+machine+learning&oq=Arduino+machine+learning&aqs=chrome..69i57j69i60.9678j0j7&client=ms-android-google&sourceid=chrome-mobile&ie=UTF-8).

Here's a kit you can buy too: https://store.arduino.cc/usa/tiny-machine-learning-kit.


body:
You can't just replace the processor on the UNO with something better. The 328P is pretty much the best MCU there is in the pinout for that board.

Instead you can replace the whole UNO with something more powerful.

My board of choice for AI work would have to be one based on the Kendryte K210 chip, such as the [Maixduino](https://www.seeedstudio.com/Sipeed-Maixduino-for-RISC-V-AI-IoT-p-4046.html) (which is helpfully in an UNO footprint).  The K210 is a dual-core 64-bit 400MHz RISC-V CPU with embedded neural network co-processor. On the Maixduino it's also coupled with an ESP32 for WiFi/Bluetooth.  That's 2x 400MHz 64-bit cores, 2x 32-bit 240MHz cores, one low-power FSM core, and a neural network core all on one board.


message:
Measure the time between 2 inputs

I am making a small project, and for that, I need to measure the time between 2 inputs.
basically, a program to measure the time elapsed from when digital pin 2 is high to when it again becomes high.

body:
You could do something like this:

    unsigned long startTime;
    unsigned long elapsedTime;

    // Any needed setup stuff
    void setup()
    {
      ...
    }

    void loop()
    {
      // Wait for input to go high
      while(digitalRead(2) == LOW);

      // Start timing
      startTime = millis();

      // Wait for input to go low
      while(digitalRead(2) == HIGH);

      // Now wait for it to go high again
      while(digitalRead(2) == LOW);

      // Now get the time interval
      elapsedTime = millis() - startTime;

      // Do whatever with the result.
      ...
    }

Keep in mind that the millis() value will overflow every 50 days or so.  If you need to run this continuously, you need to check for an overflow and adjust things accordingly.


body:
The way to go depends on the time range, that the event will have. The Arduino framework already includes a function for timekeeping: `millis()`. It returns the number of milliseconds since the startup (much like a clock) and measures the time via the hardware Timer0 and it's interrupts. This function will work good in the 2 digit millisecond range and above. With single digit millisecond or the microsecond domain, you should instead use `micros()` with works similar, but returns the microseconds since startup. For the low microsecond range and below you would need to work directly with a dedicated hardware timer, configuring it via its hardware registers.

Here I would show the principle of `millis()`/`micros()`, since that is most likely what you need. In the following I will only write `millis()`, but all the calculations can also be done with `micros()`. The only difference for the calculations is the factor 1000 between milli- and microseconds.

When you look at your watch and want to measure a time difference, you take note of the start time and the end time. Then you calculate the difference to get the event duration. You can do the same with `millis()`:

    unsigned long starttime = millis(); // take note of start time
    // here the event to measure
    unsigned long endtime = millis(); // take note of end time
    unsigned long duration = endtime - starttime; // duration of the event in ms

So in your code you need to check for a rising edge of your signal. On every rising edge you calculate the time difference between the last timestamp and the current time. Then you reset the timestamp. Something like this:

    int last_input_state = LOW;
    unsigned long timestamp;

    //setup here

    void loop(){
        int current_input_state = digitalRead(2); // get current signal level
        if(current_input_state && !last_input_state){ //check, if signal is now high and was low before
            unsigned long current_time = millis(); // take note of the current time
            unsigned long duration = current_time - timestamp; // calculate the duration and do something with it
            timestamp = current_time; // update the timestamp with the current time
         }
         last_input_state = current_input_state; // update the last input state with the new measured one
    }

Note:

- This code is non-blocking. It needs to run fast and continuously to work correctly. You cannot do long blocking things in the rest of your code, like using high `delay()` calls, but you shouldn't do that either way, since that will block anything from going on.
- You can go even further to lift the weight from your CPU and use an interrupt to sense the rising edge. You could use `attachInterrupt(digitalPinToInterrupt(pin), service_function, RISING);` and provide a `void service_function()`, which does the timestamp measurement and calculation (basically the same code as in the if statement of the code above).


message:
Rounding to the next upper (or lower) 0.1

I'm reading from a temperature sensor. I get float values with 2 decimals. I want to round them to nearest 0.1.

This is my sketch:

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

void loop() {
  float temperature = 21.81;
  float rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.81 ->");
  Serial.println(rounded_temperature);
  delay(1000);

  temperature = 21.79;
  rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.79 ->");
  Serial.println(rounded_temperature);
  delay(1000);

  temperature = 21.77;
  rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.77 ->");
  Serial.println(rounded_temperature);
  delay(1000);

  temperature = 21.70;
  rounded_temperature = round(temperature * 10) / 10.0;
  Serial.print("21.70 ->");
  Serial.println(rounded_temperature);
  delay(1000);
}
```

This is the output:

```shell
21.81 ->21.85
21.79 ->21.75
21.77 ->21.75
21.70 ->21.75

```

And this is the output I would... Rounded to "0" and not "5".

```shell
21.81 ->21.80
21.79 ->21.80
21.77 ->21.80
21.70 ->21.70
```

body:
`float` variables do not have a number of decimal places. They are merely an approximation anyway. Instead it's when you *print* that you decide how many decimals to display.

```c++
Serial.println(temperature, 1); // Print with 1 decimal place
```

Or to put it into a string:

```c++
char buf[8]; // Room for 7 characters plus NULL terminator
float val=23.81;

dtostrf(val, -7, 1, buf); // 7 characters with 1 decimal place and left aligned (negative width)
```


body:
I often store the floating point data that I get from a sensor in integer to preserve the decimal precision that I want by multiple it by 10 before casting it into an integer. It is easier and more efficient (compare to string or float) to send over to another system. This is also how many sensors representing and store the floating data (e.g. TMP275) as well.

To achieve what you want, here is what I would do:

    #include <math.h>

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

      float i=21.81;
      float j=21.79;
      float k=21.77;
      float p=21.70;

      // convert to integers
      int l = (int) round(i*10);  // 218
      int m = (int) round(j*10);  // 218
      int n = (int) round(k*10);  // 218
      int o = (int) round(p*10);  // 217

      // Convert back to actual floating point for display
      Serial.println((float)l/10);  //21.80
      Serial.println((float)m/10);  //21.80
      Serial.println((float)n/10);  //21.80
      Serial.println((float)o/10);  //21.70
    }


body:
Using roundf() function:

float rounded_temperature = roundf(temperature * 10) / 10;


message:
Arduino Nano Every Vin 5V fixes I2c problems

I had problems with connecting my devices via I2C. The "requestfrom" constantly hanged and the endtransmission sometimes gave NACK responses.

After disconnecting the devices from 12V and powering one of them via USB (vin with which it was connected to the other arduino's became 3.8V) they stopped misbehaving and worked together in harmony.

How is this possible? Am I missing something? An Arduino Nano Every should be driven between 6-21V?

All devices are "Arduino Nano Every"'s. They used to get 12V directly on Vin and are connected together in a chain by Vin,GND,A5(SCK),A4(SDA)

The master is in the middle of the chain so that the distance is max 20cm.

I also tried powering them via vin with 9V and 5V. Had the same issue.

Already big thanks for the help.

body:
SO... In the datasheet it says you should use 7-21V on VIN. This gave the problem. I powered the arduinos directly from 5V on the vin. This fixed all I2C problems. Haven't had any problems anymore after changing this.

cheers to all.


message:
Ethernet Shield web server - Can't find the index.htm file

i've just got the EthernetShield and watched a tutorial on how to host a html page with it but i can't find my html page on the SD card.

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

    byte mac[] = {0xA8, 0x61,0x0A, 0xAE, 0x3A, 0xC4 };

    EthernetServer server(80);

    File webPage;

    void setup() {
      Ethernet.begin(mac);
      server.begin();
      Serial.begin(9600);

      Serial.println(Ethernet.localIP());

      Serial.println("Initializing SD card...");
      if(!SD.begin(4)){
        Serial.println("ERROR - SD card initialization failed!");
        return;
      }
        Serial.println("SUCCESS - SD card initialized.");
        if(!SD.exists("index.htm")){
          Serial.println("ERROR - Can't find index.htm file!");
        }
          Serial.println("SUCCESS - Found  index.htm file.");
    }

    void loop() {
       EthernetClient client = server.available();
       if(client){
        boolean currentLineIsBlank = true;
        while(client.connected()){
          if(client.available()){
            char c = client.read();
            if(c == '\n' && currentLineIsBlank){
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println("Connection: close");
              client.println();

              webPage = SD.open("index.htm");
              if(webPage){
                while(webPage.available()){
                  client.write(webPage.read());
                }
                webPage.close();
              }
              break;
            }
            if(c == '\n'){
              currentLineIsBlank = true;
            }
            else if(c != '\r'){
              currentLineIsBlank = false;
            }
          }
        }
        delay(1);
        client.stop();
       }
    }
[![enter image description here][1]][1]

When i save the HTML file i can't save it with the .htm format

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

  [1]: https://i.stack.imgur.com/KKpuJ.png
  [2]: https://i.stack.imgur.com/CaiR4.png

body:
Windows is hiding the extension from you.

The file you showed is either `index.htm` or `index.html`. If it's the latter, you could change the windows setting to "show extensions for know filetypes", <strike>or change the sketch so it uses `index.html` instead of `index.htm. I'd go with the latter, as it's the easiest.</strike>

EDIT: the SD library doesn't seem to like file extension that are longer than 3 characters. So changing the code to use "index.html" doesn't work.


message:
Is it possible to check for correct architecture on OTA update (ESP32 or ESP8266)?

Having a skech running on ESP8266 as well as ESP32 with the ability to update via OTA, uploading the wrong binary (upload to ESP8266 compiled for ESP32, and vice versa) leads to crashing the MCU and not being able to do OTA Updates any more.

The Update is done in the simple usual way: Upload binary file and call the methods from the Update Class (begin(), write(), and end()).

Is there any way to check if the uploaded file matches the architecture of the MCU before starting the update?

Edit:

Both the ESP8266 and the ESP32 Updater class check for an "IMAGE_MAGIC" value in the upload header; but that is defined as "ESP_IMAGE_MAGIC = 0xe9" in both cores. So none of them will refuse to update the wrong one.

Edit 2:

Found a simple workaround that satisfies our needs at the moment: As the arduino IDE saves the binaries with a name like <sketch_name>.<board_name>.bin, we just compare the board name as part of the uploaded filename: `if (upload.filename.indexOf(MATCH) > 0) ...`, where `MATCH` is the respective board name. As they are pin compatible, we use "d1_mini.bin" and "d1_mini32.bin".

Edit 3:

When the webserver tries to abort the upload with `403 Forbidden` (because of wrong file), the browser continues to send data until the upload is done. After that, it displays the error message. Thus, even when the filename does not match, it is a waste of time and bandwidth. The only possibility to avoid this is to do a `server.client().stop()`, but then the browser will not display the message sent, just something like "connection broken". This does not confirm with the respective RFCs.

This is not really a final solution, so I'ld appreciate any better idea.

Richard

body: I assume you are the one creating the OTA update.  If so, then why don't you just include a "signature" in the code that is the architecture, i.e. ESP8266 vs. ESP32 and then check for that in your updater code so that it will not install an update for the wrong CPU.


message:
How to transfer constants from one loop to next one

```c++
#include "VernierLib.h"

VernierLib Vernier;

#define led 13

float sensorReading;

void setup() {
  Serial.begin(9600);
  Serial.println(Vernier.sensorName());
  Vernier.autoID();
}

void loop() {
  float base_temp;
  base_temp = Serial.parseFloat();
  sensorReading = Vernier.readSensor();
  Serial.print(sensorReading);
  Serial.print(" ");
  Serial.println(Vernier.sensorUnits());
  Serial.println(base_temp);
  if (base_temp > sensorReading) {
    digitalWrite(led, HIGH);
  } else {
    digitalWrite(led, LOW);
  }
  delay(3000);
}
```

That's the code, I have a question. When I write the temperature to Serial, it lasts only until the end of one loop.

How to keep the same temperature in the next loop?

body:
There are two things here you need to consider.

First is that your variable is a "local" variable. This kind of variable is created at the start of each iteration, then discarded at the end of that iteration.

There's two things you can do to "fix" this:

1. Make the variable "global" - that is, move the definition out of `loop()` to the "global" scope (put it at the top of your program). It is then only created once and never discarded.
2. Make the variable "static" - that is, add the `static` keyword to it. It is then created on the first iteration only, and never discarded.

The second thing to consider is that you have no "There is no value" concept. Every iteration you parse a new float, whether there is one there or not. And if there isn't one then it just gives you `0`. So you need to come up with some way of saying "I have entered a number, so parse it". The simplest thing is just to assume that all values of 0 are "no number entered", but that of course prevents you ever entering 0 as a valid input.


body:
Something like this should work (untested, but you get the idea; the explanation is in the comments):

```c++
void loop() {
  static float base_temp = 21;     // Or whatever default starting value you want
  static float t = 0;              // A temporary store for Serial.parseFloat()

  t = Serial.parseFloat();         // Read t; if Serial.parseFloat() times out, it will return 0.00
  if (t != 0.00) {                 // If something else than 0.00 is in t
    base_temp = t;                 // Update base_temp with t
  }                                // Note: You can't set base_temp to exactly 0.00 with this set-up
  sensorReading = Vernier.readSensor();
  Serial.print(sensorReading);
  Serial.print(" ");
  Serial.println(Vernier.sensorUnits());
  Serial.println(base_temp);
  if (base_temp > sensorReading) {
    digitalWrite(led, HIGH);
  } else {
    digitalWrite(led, LOW);
  }
  delay(3000);
}
```

In this code `0.00` means that "no value was entered", so you can't set the temperature to *exactly* 0.00 with this set-up; 0.01 should work fine, though.


message:
Set TX, RX to LOW before sleeping, re-enable uart after waking up

I have an ATmega1284p and I need to have the TXD0 (i.e. pin 9) set to LOW, before going to sleep. After waking up, I want to restore UART0 communication to work as expected. Here is my code:

    Serial.begin(38400,SERIAL_8N1);

    *do Stuff*

    Serial.end();
    //pinMode(9,OUTPUT);
    //digitalWrite(9,LOW);
    //UCSR0B &= ~bit (RXEN0);  // disable receiver
    //UCSR0B &= ~bit (TXEN0);  // disable transmitter
    cli();
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    // turn off brown-out enable in software
    //MCUCR = bit (BODS) | bit (BODSE);  // turn on brown-out enable select
    //MCUCR = bit (BODS);        // this must be done within 4 clock cycles of above
    sleep_bod_disable();  //disable brown-out detection
    sei();             // guarantees next instruction executed
    sleep_cpu ();              // sleep within 3 clock cycles of above
    sleep_disable();

    //  UCSR0B |= bit (RXEN0);  // enable receiver
    //  UCSR0B |= bit (TXEN0);  // enable transmitter
    //pinMode(9,OUTPUT);
    //digitalWrite(9,HIGH);
    //delay(100);
    //pinMode(9,INPUT_PULLUP);
    Serial.begin(38400,SERIAL_8N1);
    delay(1000);
    Serial.println("- Good Morning");

    *do Stuff*

You can see in comments all the different things I tried:

 - Using `Serial.end()` and then, after waking up, `Serial.begin()`
 - Using the `UCSR0B` register
 - Using `digitalWrite` to set the pin to `LOW` and then, after waking up, either setting it to `high`, or setting it as `input`

All of the above combinations have the common problem that the cpu hangs after waking up, and the Serial is never restarted to print `good morning` message, neither does the program continue to execute further down.

body:
After trying many different alternatives, it turns out that my mistake was that, foolishly, **I had included Serial printing inside my ISR routines**, which where accessed when my interrupt fired, in order to wake my uP. As a result, **`Serial.print` was called, with *Serial* being closed** (before issuing the `Serial.begin` command to restart it), thus breaking my uP.

**Extra:** Just wanted to comment about using Serial.print inside ISRs. Although it can lead to unexpected problems like this one, or timing issues (ISR would take too long to execute) and is definitely a bad practice, it can sometimes be useful for debug purposes during development to print some kind of message there.

Printing a message takes long, and the ISR will return before the message is completely transmitted, with the potential to cause a lot of headache. Also, interrupts are disabled inside ISRs, so delay() is not working to do some kind of flow control. The best way to print messages in ISRs that I have come across so far, is by using Serial.flush() before exiting the ISR, making sure the message is completely transmitted.


message:
How can I execute a string in my Arduino Uno board?

I was making a project with Arduino Uno ,
It's working is like this it connects to a key pad and a 7segment display ,and when you press a run button connected to Arduino it should run the code written.

I don't want code for display and keypad but for executing a string like we can do in python- **exec("print (8)")**

Please help me and ask any information you need to solve it

body:
Unless you want to implement some form of scripting engine, you can't.

Arduino code is compiled code, not interpreted code. There is no way of converting text into runnable code, since that is done by your computer at compile time, not by the Arduino at run-time.

The only thing you could possibly do is write some form of scripting engine which reads text and interprets it in some meaningful way to perform operations. That is not a trivial task, so you have to ask yourself: is this *really* what you want to do? Are you going about tackling your problem in the right way?


body:
As stated in Majenko's answer, you would need an interpreter running on
the Arduino. Python is too large to run on an Uno, although [it can run
on some more powerful microcontrollers][uPi].

A Web search for Arduino interpreters yields quite a few promising
options. I have not tested any of them:

* [Firmata][]
* [Forth][]
* another [Forth-ish language][]
* [Lisp][]
* [BASIC][]
* a [C-like language][]

The Forth language is quite popular when you need an interpreter with
minimal footprint.

[uPi]: https://micropython.org/
[Firmata]: https://github.com/firmata/arduino
[Forth]: https://flashforth.com/
[Forth-ish language]: https://github.com/tschaer/tofish
[Lisp]: http://www.ulisp.com/
[BASIC]: https://github.com/robinhedwards/ArduinoBASIC
[C-like language]: https://n.mtng.org/ele/arduino/iarduino.html