message:
Using CD74HC4067 16-Channel Analog Multiplexer Demultiplexer is not working as expected

I am working on a project that needs multiple digital signals and I am considering the CD74HC4067 (on a break-board) to work as a multiplexer. More specifically i am trying to build a keypad with multiple ttp123 break-boards. Each ttp123 signal is connected to one of the 0-15 pins of the CD74HC4067. The S0-S3 pins are connected to digital Pins D6 to D9 on a pro mini. Signal is on A0 and EN is on A1. A1 and EN have a 4K7 resistor to ground. I power the setup with a separate 5v and the arduino is connected on a pc usb port.

I expect when a ttp123 is pressed to trigger a HIGH and this event to be passed to SIG pin. Here is my code:
```
//Using CD74HC4067 16-Channel Analog Multiplexer
//Mux control pins

int s0 = 6;
int s1 = 7;
int s2 = 8;
int s3 = 9;

//Mux in "SIG" pin
int SIG_pin = A0;
int EN_pin  = A1;

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(EN_pin, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  digitalWrite(EN_pin, LOW);

  Serial.begin(9600);
  Serial.println("keypad interfacing_CD74HC4067 starting...");
}

void loop(){
  String a;
  //digitalWrite(EN_pin, HIGH);
  Serial.println(" press any key to continue ...");
  //digitalWrite(EN_pin, LOW);
  while (!Serial.available());
  while(Serial.available()) {

  //Loop through and read all 16 values
  for(int i = 0; i < 16; i ++){
    //Serial.print("Value at channel ");
    //Serial.print(i);
    //Serial.print("is : ");
    //Serial.println(readMux(i));

      float volts = readMux(i);

      Serial.print("Value at channel ");
      Serial.print(i);
      Serial.print(" is : ");
      Serial.print(volts);
      Serial.println();

    //delay(1000);
  }
  a= Serial.readString();// read the incoming data as string
}
}
float readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

  //loop through the 4 sig

  for(int j = 0; j < 4; j ++){
    digitalWrite(controlPin[j], muxChannel[channel][j]);
  }
  //read the value at the SIG pin
  int val = analogRead(SIG_pin);

  //return the value
  float voltage = (val * 5) / 1024.0;
  return voltage;
}
```
Just for simplicity, I have connected only one ttp123 on the system, ttp123 signal to channel12 on 74HC4067. With ttp123 touched, I would expect to get a high on SIG when I write {0,0,1,1}, to S0-S3. All other channels should be LOW. However here is what I get:

On my first run after a boot:
```
press any key to continue ...
Value at channel 0 is : 2.53
Value at channel 1 is : 2.58
Value at channel 2 is : 2.53
Value at channel 3 is : 2.60
Value at channel 4 is : 2.51
Value at channel 5 is : 2.55
Value at channel 6 is : 2.50
Value at channel 7 is : 2.52
Value at channel 8 is : 2.42
Value at channel 9 is : 2.47
Value at channel 10 is : 2.43
Value at channel 11 is : 2.50
Value at channel 12 is : 2.40
Value at channel 13 is : 2.43
Value at channel 14 is : 2.38
Value at channel 15 is : 2.44
```
and then after each sample run all channels seem to get lower values...
```
press any key to continue ...
Value at channel 0 is : 1.70
Value at channel 1 is : 1.76
Value at channel 2 is : 1.71
Value at channel 3 is : 1.78
Value at channel 4 is : 1.70
Value at channel 5 is : 1.76
Value at channel 6 is : 1.72
Value at channel 7 is : 1.77
Value at channel 8 is : 1.67
Value at channel 9 is : 1.72
Value at channel 10 is : 1.69
Value at channel 11 is : 1.76
Value at channel 12 is : 1.69
Value at channel 13 is : 1.73
Value at channel 14 is : 1.67
Value at channel 15 is : 1.74
```
and I get no HIGH on channel 12 as I should.

Is there a need for a pullup or pulldown resistors in this setup? Should I connect a resistor to each S0-S3 with ground? Why is this not working?

Edit: [![schematic][1]][1]

When the system is resting I measure 4.93V at the ttp's Vs to GND and 0V TTP_SIGNAL to GND. When ttp's are touched TTP_SIGNAL to GND i measure a 3.94-3.88v. But the strange thing is that when i touch the ttp's I measure 2.xx Volts at all the mux channels. I think that there must be some kind of short circuit somewhere but it is not visible. The problem is that I can't test another CD74HC4067 since i  have only one right now. Unless there is another suggestion I will look for a couple of these (CD74HC4067)  as soon as possible.

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

Edit2:

I got hold of a new CD74HC4067 and connected just one capacitive touch pad. When nothing is touched/pressed, i get the following:

    press any key to continue ...
    Value at channel 0 is : 1.01
    Value at channel 1 is : 0.90
    Value at channel 2 is : 0.81
    Value at channel 3 is : 0.62
    Value at channel 4 is : 0.44
    Value at channel 5 is : 0.42
    Value at channel 6 is : 0.43
    Value at channel 7 is : 0.43
    Value at channel 8 is : 0.31
    Value at channel 9 is : 0.28
    Value at channel 10 is : 0.24
    Value at channel 11 is : 0.18
    Value at channel 12 is : 0.15
    Value at channel 13 is : 0.23
    Value at channel 14 is : 0.22
    Value at channel 15 is : 0.13

When i touch the pad (connected to c0) i get:

    press any key to continue ...
    Value at channel 0 is : 4.15
    Value at channel 1 is : 3.74
    Value at channel 2 is : 3.75
    Value at channel 3 is : 3.54
    Value at channel 4 is : 3.76
    Value at channel 5 is : 3.33
    Value at channel 6 is : 2.88
    Value at channel 7 is : 2.64
    Value at channel 8 is : 3.77
    Value at channel 9 is : 3.52
    Value at channel 10 is : 3.07
    Value at channel 11 is : 2.76
    Value at channel 12 is : 2.04
    Value at channel 13 is : 1.83
    Value at channel 14 is : 1.67
    Value at channel 15 is : 1.51

I measure volts between signal and ground at the capacitive touch pad, when touched i get 3.9v

body:
I finally managed to get a solution to my problem. There was a cabling and a software issue as well. Firstly, I pulled down the Signal with a 10K resistor. In this way I stopped having those random volt measurements.
[![enter image description here][1]][1]

Secondly, in the code, I had an elementary failure to initialize the A0 analog pin as:
pinMode(SIG_pin, INPUT);

Here is the final code:

    // interfacing mux with tp223

    //Mux control pins

    const int s0 = 6;
    const int s1 = 7;
    const int s2 = 8;
    const int s3 = 9;

    //Mux in "SIG" pin
    int SIG_pin = A0;
    int EN_pin  = 10;

    void setup(){
      pinMode(s0, OUTPUT);
      pinMode(s1, OUTPUT);
      pinMode(s2, OUTPUT);
      pinMode(s3, OUTPUT);
      pinMode(SIG_pin, INPUT);
      pinMode(EN_pin, OUTPUT);

      digitalWrite(s0, LOW);
      digitalWrite(s1, LOW);
      digitalWrite(s2, LOW);
      digitalWrite(s3, LOW);
      digitalWrite(EN_pin, LOW);

      Serial.begin(115200);
      Serial.println("keypad interfacing_CD74HC4067 starting...");
    }

    void loop(){

      //Loop through and read all 16 values
      for(int i = 0; i < 16; i ++){
          int val = readMux(i);

          if (val > 0) {
            Serial.print(i);
            Serial.print(" pressed ");
            Serial.print(val);
            Serial.println();
          }
      }

    }
    float readMux(int channel){
      int controlPin[] = {s0, s1, s2, s3};

      int muxChannel[16][4]={
        {0,0,0,0}, //channel 0
        {1,0,0,0}, //channel 1
        {0,1,0,0}, //channel 2
        {1,1,0,0}, //channel 3
        {0,0,1,0}, //channel 4
        {1,0,1,0}, //channel 5
        {0,1,1,0}, //channel 6
        {1,1,1,0}, //channel 7
        {0,0,0,1}, //channel 8
        {1,0,0,1}, //channel 9
        {0,1,0,1}, //channel 10
        {1,1,0,1}, //channel 11
        {0,0,1,1}, //channel 12
        {1,0,1,1}, //channel 13
        {0,1,1,1}, //channel 14
        {1,1,1,1}  //channel 15
      };

      //loop through the 4 sig
      for(int j = 0; j < 4; j ++){
        digitalWrite(controlPin[j], muxChannel[channel][j]);
      }
      //read the value at the SIG pin
      int val = digitalRead(SIG_pin);
      //return the value
      return val;
    }

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


sender: user

message:
Trouble understanding min and max parameters for the Servo motor

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

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

This picture is from arduino.cc .  Could someone please help me understand these parameters min and max? I was using TinkerCad taking input for the angle using a potentiometer (having mapped correctly the input from (0 to 1023) to (0 to 180) ) but i don't see any change when i vary either min or max in my code. The servo still goes to 180-deg position when input is 1023.

sender: assistant

body:
It's hard coded in the servo library (well it is on the ESp8266 version I used).

    // The following values are in us (microseconds).
    // Since the defaults can be overwritten in the new attach() member function,
    // they were modified from the Arduino AVR defaults to be in the safe range
    // of publicly available specifications. While this implies that many 180°
    // servos do not operate the full 0° to 180° sweep using these, it also prevents
    // unsuspecting damage. For Arduino AVR, the same change is being discussed.
     #define DEFAULT_MIN_PULSE_WIDTH      1000 // uncalibrated default, the shortest duty cycle sent to a servo
     #define DEFAULT_MAX_PULSE_WIDTH      2000 // uncalibrated default, the longest duty cycle sent to a servo
     #define DEFAULT_NEUTRAL_PULSE_WIDTH  1500 // default duty cycle when servo is attached

I discovered this when a servo attached to an ESP8266 was only moving half the expected angle so I modified the library (saving it as MyServo) and used that instead. You need to be careful when doing this as you can strip the servo gears if you try to move the servo outside its capable range.


body:
In your question you're referencing the [servo library][1]. You mention mapping ranges of 0-1023 (the sampling range of your potentiometer) and 0-180 (the degrees of rotary travel of the average hobby servo).

There is an additional important concept to get familiar with as you learn about servos. That is the [Pulse Width Modulated][2] (PWM) signal that the Arduino (or any other controller) uses to communicate with the servo to set what angle of rotation it should assume. PWM is used a few different ways in electronics, but in this scenario it is being used as a [servo control signal][3], and the pulse width (measured as a time duration) communicates the required angle to the servo. The library you're referencing helps users by translating between angles and PWM pulse lengths. But under the covers servos always (close enough for our conversation anyway) receive a signal based on PWM.

Another complicating factor is that servos vary greatly. There is a loose convention that says that a pulse width of 1500 micro-seconds is centre position, 1000 micro-seconds is the minimum -90 degress (or 0 degrees depending on how you look at it), and 2000 micro-seconds is the maximum +90 (or 180) degrees. These match the defaults that @Bra1n notes in their answer.
[![Servo control convention][4]][4]
(Diagram by Wikimedia user Hforesti - https://commons.wikimedia.org/wiki/File:Sinais_controle_servomotor.JPG, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=101951622)

But that convention is broken all the time. Some servos are capable of less than or greater than 180 degrees. Others use different pulsewidths to specify the maximum and minimum rotations. It's for this reason that the library allows the minimum and maximum pulsewidth (expressed in micro-seconds) to be specified for the particular physical servo being attached. This allows the library to correctly map to its range of travel.

Everytime you use a new type of servo (or consider buying one for a new project) you'll need to look at its datasheet to get the important information about how that servo works.

One last thought about traps for new players, I've also seen servo libraries which express the maximum and minimum servo PWM values in the range of 0-4096. Some people also express this as a % [duty cycle][5] (mixing the language of those other purposes I mentioned PWM is also used for). Knowing that these all map back to a PWM pulse width is useful for making sense as you learn more about servos. Good luck!

  [1]: https://www.arduino.cc/reference/en/libraries/servo/
  [2]: https://en.wikipedia.org/wiki/Pulse-width_modulation
  [3]: https://en.wikipedia.org/wiki/Servo_control
  [4]: https://i.stack.imgur.com/dJ73i.png
  [5]: https://en.wikipedia.org/wiki/Duty_cycle


message:
LILYGO TTGO T-Display cannot detect MPU 6050 Accelerometer, Gyroscope and Temperature Sensor

I've been trying to connect a MPU 6050 Accelerometer, Gyroscope and Temperature Sensor to a LILYGO TTGO T-Display to get readings displayed on the serial monitor (for starters). The wiring is pretty straightforward. I need to power up the MPU6050 with 3V, and connect the SDA and SCL. I followed this tutorial ([https://randomnerdtutorials.com/esp32-mpu-6050-accelerometer-gyroscope-arduino/][1]).

This is the code used:

    #include <Adafruit_MPU6050.h>
    #include <Adafruit_Sensor.h>
    #include <Wire.h>

    Adafruit_MPU6050 mpu;

    void setup(void) {
      Serial.begin(115200);
      while (!Serial)
        delay(10); // will pause Zero, Leonardo, etc until serial console opens

      Serial.println("Adafruit MPU6050 test!");

      // Try to initialize!
      if (!mpu.begin()) {
        Serial.println("Failed to find MPU6050 chip");
        while (1) {
          delay(10);
        }
      }
      Serial.println("MPU6050 Found!");

      mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
      Serial.print("Accelerometer range set to: ");
      switch (mpu.getAccelerometerRange()) {
      case MPU6050_RANGE_2_G:
        Serial.println("+-2G");
        break;
      case MPU6050_RANGE_4_G:
        Serial.println("+-4G");
        break;
      case MPU6050_RANGE_8_G:
        Serial.println("+-8G");
        break;
      case MPU6050_RANGE_16_G:
        Serial.println("+-16G");
        break;
      }
      mpu.setGyroRange(MPU6050_RANGE_500_DEG);
      Serial.print("Gyro range set to: ");
      switch (mpu.getGyroRange()) {
      case MPU6050_RANGE_250_DEG:
        Serial.println("+- 250 deg/s");
        break;
      case MPU6050_RANGE_500_DEG:
        Serial.println("+- 500 deg/s");
        break;
      case MPU6050_RANGE_1000_DEG:
        Serial.println("+- 1000 deg/s");
        break;
      case MPU6050_RANGE_2000_DEG:
        Serial.println("+- 2000 deg/s");
        break;
      }

      mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);
      Serial.print("Filter bandwidth set to: ");
      switch (mpu.getFilterBandwidth()) {
      case MPU6050_BAND_260_HZ:
        Serial.println("260 Hz");
        break;
      case MPU6050_BAND_184_HZ:
        Serial.println("184 Hz");
        break;
      case MPU6050_BAND_94_HZ:
        Serial.println("94 Hz");
        break;
      case MPU6050_BAND_44_HZ:
        Serial.println("44 Hz");
        break;
      case MPU6050_BAND_21_HZ:
        Serial.println("21 Hz");
        break;
      case MPU6050_BAND_10_HZ:
        Serial.println("10 Hz");
        break;
      case MPU6050_BAND_5_HZ:
        Serial.println("5 Hz");
        break;
      }

      Serial.println("");
      delay(100);
    }

    void loop() {
      /* Get new sensor events with the readings */
      sensors_event_t a, g, temp;
      mpu.getEvent(&a, &g, &temp);

      /* Print out the values */
      Serial.print("Acceleration X: ");
      Serial.print(a.acceleration.x);
      Serial.print(", Y: ");
      Serial.print(a.acceleration.y);
      Serial.print(", Z: ");
      Serial.print(a.acceleration.z);
      Serial.println(" m/s^2");

      Serial.print("Rotation X: ");
      Serial.print(g.gyro.x);
      Serial.print(", Y: ");
      Serial.print(g.gyro.y);
      Serial.print(", Z: ");
      Serial.print(g.gyro.z);
      Serial.println(" rad/s");

      Serial.print("Temperature: ");
      Serial.print(temp.temperature);
      Serial.println(" degC");

      Serial.println("");
      delay(500);
    }

The pinout config for the TTGO T Display is shown below:
[![enter image description here][2]][2]

I connected the pins based on this as follows:

TTGO        MPU6050

3V  ---->  Vcc

G   ---->  Gnd

22  ---->  SCL

21  ---->  SDA

But I keep getting the following error on the serial monitor.

    ets Jul 29 2019 12:21:46

    rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0030,len:1324
    ho 0 tail 12 room 4
    load:0x40078000,len:13508
    load:0x40080400,len:3604
    entry 0x400805f0
    Adafruit MPU6050 test!
    Failed to find MPU6050 chip

What is strange is that the MPU 6050 works perfectly fine with the same pin connection on the normal Node MCU ESP 32 system. Any idea why it won't work on the TTGO?

  [1]: https://randomnerdtutorials.com/esp32-mpu-6050-accelerometer-gyroscope-arduino/
  [2]: https://i.stack.imgur.com/wQ2jV.png

body: I had exactly the same error (Failed to find MPU6050 chip)on the same program with the same tutorial. I thought it was this, that, and an act of nature. I hade proven the MPU6050 worked fine and the ESP32 worked fine. EVENTUALLY I realised it was dead simple, the ESP32 ( a cheapo one) had different pinout to the one in the tutorial, SCL,SDA and 3.3v were in the wrong place even though the red LED illuminated on my MPU6050 board. Anyway I wired it correctly and it works just fine and the Webserver one too. I did not do the display one! ( Don't take anything for granted). I do not know which incarnation of the MPU6050 you are using but when using mine (looked identical as the one in the tutorial) on an ESP8266 the I2C addressing was a bit finicky and I had to take the address connection hard to GND  with a wire to get it to run consistently, that too caused the same error (Failed to find MPU6050 chip).


message:
Can this display's address be changed?

I need two displays hooked up to an Arduino MKR Wifi 1010, and I saw this video which shows how to do it: [this video][1]. I also would like to have a full color oled display about 1 inch big so I would like to use [this display][2]. But I don't believe that you can change the address and would not like to buy it until I find out if you can.

Thanks in advance.

  [1]: https://youtu.be/yef23sJjiU0
  [2]: https://www.adafruit.com/product/684

body:
There are two different OLED screens in the links you shared.

##### 1. OLED Display on Adafruit Link

The OLED display on the Adafruit link does not have an address as it communicates via the SPI interface.

##### 2. OLED Display on YouTube Link

This OLED display communicates via I2C interface. OLED displays that communicate over the I2C interface have a slave address. This provides the possibility to connect devices with different slave addresses on the same I2C line. The address of this screen can only take two different values. If you solder the 0 Ω resistor to the left field, its address will be `0x7A`; if you solder the 0 Ω resistor to the right field, its address will be `0x78`.

<hr>

##### Suggestions

[This OLED display](https://www.adafruit.com/product/326) with 0.96" screen size communicates via I2C interface and its address can be changed. If a 0 Ω resistor is connected to the **A0** pad, the I2C slave address of the OLED display will be `0x3D`; otherwise the I2C slave address of the OLED display will be `0x3C`.

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

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


message:
Servo keeps rotating

I use a 360° servo with a program I made on an Arduino Uno.

The program was meant to control two separate servos with two potentiometers on a breadboard.

When I used 180° and 90° servos, it worked fine, but when the 180° servo was swapped with a 360° servo, it kept spinning and spinning non-stop.

Could it be the knock-off board (not Arduino brand) I'm using?

```c++
Servo serX;    // create servo object to control a servo for x axis
Servo serY;    // create servo y axis

int pot1 = 0;  // potentiometer pin number on board
int pot2 = 1;  // potentiometer number 2
int val;       // variable to read the value from the analog pin
int val2;      // read value from other analog pin

void setup() {
  serX.attach(9);  // attaches the servo on pin 9 to the servo object
  serY.attach(10); // attach servo to number 10 pin
}

void loop() {
  val = analogRead(pot1);           // reads the value of the potentiometer
  val = map(val, 0, 1023, 0, 180);  // scale it to use it with the servo
  serX.write(val);                  // sets the servo position

  val2 = analogRead(pot2);          // reads the value of the potentiometer
  val2 = map(val2, 0, 1023, 0, 90); // scale it to use it with the servo
  serY.write(val2);                 // sets the servo position

  delay(15);                        // waits for the servo to get there
}
```

body:
The "360°" you refer to is probably a [continuous-rotation servo][1].

These servos behave more like motors than like the normal RC servos; the signal you send such a servo will determine its *speed* and *direction*, **not** its position, and a pulse width of 1.5 ms (the "90° setting") will make it stop.

There's an [article on the Adafruit site][2] where you can read more about this.

  [1]: https://en.wikipedia.org/wiki/Servo_(radio_control)#Continuous-rotation_servos
  [2]: https://learn.adafruit.com/adafruit-motor-selection-guide/continuous-rotation-servos


message:
I2C communication in Arduino

In Arduino I2C we have the following lines of code:
```
wire. beginTransmission(slave addrress)
wire.write(the byte want to send)
wire. endTransmission()

```
As we know in I2C the master must verifies the presence of the slave address and making it sure by getting an ack by the slave. Among the three function listed, who does this job? Is it wire. beginTransmission? in their website it's just mentioned it initializes communication with the slave. I want to know what happens during the execution of wire. beginTransmission from I2C perspective.

Also wire.endTransmission() releases the buffer data which was created by wire. write. So who examines the presence of the slave? The first function or the 3rd?

body:
All the actual I2C communication is done in `Wire.endTransmission()`. Before that nothing is done on the I2C lines.

`Wire.beginTransaction()` only initializes the libraries buffer and saves the slave address in an internal variable. `Wire.write()` puts data into the internal buffer.

`Wire.endTransmission()` can then follow the I2C protocol. It generates a start condition on the bus, sends the address byte, checks for the slaves acknowledgement on the address byte, then sends the data bytes, each followed by the slaves acknowledgement. Finally it generates a stop condition.


message:
uint8_t issues when linking libraries outside of INO file

I've been trying to start my project out split into multiple files, knowing it will grow. I was templating it off of how I've done C++ files in the past: classes in an individual .h/.cpp pair and linked into the main file. I'm using the OneBitDisplay library for my OLEDs. When I include the library in my ino file and call functions within it, all works fine. When I have it linked from one of my class header files, it gives this output:

```
In file included from C:\Users\Kyle\Documents\Arduino\libraries\OneBitDisplay-master\src/OneBitDisplay.h:4:0,
                 from C:\Users\Kyle\Projects\EOS-OSC\OLED.h:1,
                 from C:\Users\Kyle\Projects\EOS-OSC\OLED.cpp:1:
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:67:1: error: 'uint8_t' does not name a type
 uint8_t iSDA, iSCL; // pin numbers (0xff = disabled)
 ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:68:1: error: 'uint8_t' does not name a type
 uint8_t bWire; // use the Wire library
 ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:69:1: error: 'uint8_t' does not name a type
 uint8_t iSDABit, iSCLBit; // bit numbers of the ports
 ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:70:1: error: 'uint32_t' does not name a type; did you mean 'char32_t'?
 uint32_t iDelay;
 ^~~~~~~~
 char32_t
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:75:10: error: 'uint32_t' does not name a type; did you mean 'char32_t'?
 volatile uint32_t *pSDADDR, *pSDAPORT; // data direction and port register addr
          ^~~~~~~~
          char32_t
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:76:10: error: 'uint32_t' does not name a type; did you mean 'char32_t'?
 volatile uint32_t *pSCLDDR, *pSCLPORT;
          ^~~~~~~~
          char32_t
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:82:26: error: 'uint8_t' has not been declared
 int I2CRead(BBI2C *pI2C, uint8_t iAddr, uint8_t *pData, int iLen);
                          ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:82:41: error: 'uint8_t' has not been declared
 int I2CRead(BBI2C *pI2C, uint8_t iAddr, uint8_t *pData, int iLen);
                                         ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:86:34: error: 'uint8_t' has not been declared
 int I2CReadRegister(BBI2C *pI2C, uint8_t iAddr, uint8_t u8Register, uint8_t *pData, int iLen);
                                  ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:86:49: error: 'uint8_t' has not been declared
 int I2CReadRegister(BBI2C *pI2C, uint8_t iAddr, uint8_t u8Register, uint8_t *pData, int iLen);
                                                 ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:86:69: error: 'uint8_t' has not been declared
 int I2CReadRegister(BBI2C *pI2C, uint8_t iAddr, uint8_t u8Register, uint8_t *pData, int iLen);
                                                                     ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:92:27: error: 'uint8_t' has not been declared
 int I2CWrite(BBI2C *pI2C, uint8_t iAddr, uint8_t *pData, int iLen);
                           ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:92:42: error: 'uint8_t' has not been declared
 int I2CWrite(BBI2C *pI2C, uint8_t iAddr, uint8_t *pData, int iLen);
                                          ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:100:1: error: 'uint8_t' does not name a type
 uint8_t I2CTest(BBI2C *pI2C, uint8_t addr);
 ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:104:27: error: 'uint8_t' has not been declared
 void I2CScan(BBI2C *pI2C, uint8_t *pMap);
                           ^~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:110:27: error: 'uint32_t' has not been declared
 void I2CInit(BBI2C *pI2C, uint32_t iClock);
                           ^~~~~~~~
C:\Users\Kyle\Documents\Arduino\libraries\BitBang_I2C-master\src/BitBang_I2C.h:115:36: error: 'uint8_t' has not been declared
 int I2CDiscoverDevice(BBI2C *pI2C, uint8_t i);
...
```
This keeps going for quite a while where any types from the stdint library are referenced.
It seems to only occur when the library is included in a header file, not when it is in the main ino sketch. I have it linked in the ino, knowing that the compiler needs all referenced libraries placed there.
When I remove the include from the header, it gives errors that it can't find types for variables that I've declared (as it should, given that these types are defined in the library I'm trying to include)

Any clues? I've never posted anything on StackOverflow, because I usually can find the answer but this one has stumped me.
I'm happy to provide any other code or debugging output if needed.

body:
Arduino IDE implicitly includes some headers. Especially "arduino.h".
You need to include "stdint.h" into your header files for completeness.


body:
The uint8_t and the uint32_t types reported in your compile errors are defined in the stdint.h file. In .ino the stdint.h is included  with Arduino.h (which is added at ino to cpp conversion by Arduino builder).

The BitBang_I2C.h should include Arduino.h or stdint.h, but the author forgot to add it. Then if BitBang_I2C.h is included in .ino, the Arduino.h is included above it and the types are defined, but if you include BitBang_I2C.h in a cpp file which doesn't include Arduino.h or stdint.h, then the stdint defines are missing.

The workaround for this bug is to add `#include <stdint.h>` at the top of your OLED.cpp file.


message:
Will the pro trinket gamepad library work on an Arduino Uno?

I have an Arduino Uno and I wanted to know if the pro trinket gamepad library works on an Arduino Uno since both have same atmega328p CPU chip.

body:
The Pro Trinket has a USB connector wired to the ATmega328P, and the
Pro\_Trinket\_USB\_Gamepad library uses this connection to impersonate a
USB gamepad.

The Arduino Uno also has a USB connector, but it is _not_ wired to the
ATmega328P. It is instead connected to an auxiliary chip (an ATmega16U2)
which serves exclusively as a USB-to-serial converter. Since your
sketches run on the 328P, and the 328P has no access to the USB port,
you cannot use this library on the Uno.

Well, actually you may be able to use the library if add an extra USB
connector, and link it to the 328P. See how it is done in the [schematic
of the Pro Trinket 5V][schematic]. Beware of the 3.6V Zener diodes:
these are needed to avoid damaging the serial port of your computer.

[schematic]: https://cdn-learn.adafruit.com/assets/assets/000/018/948/original/adafruit_products_protrink5vschm.png


message:
Could I put an arduino in series with a battery charger?

recently in one of my projects I have wanted to make battery powered. I was wondering if I could connect the charger to the battery and the battery to the Arduino without blowing it. The battery is 12v 7.2 Ah and the charger is 12v 1 A.

(See attached)

[![Schematic][1]][1]

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

body:
Just for clarity: your diagram shows the Arduino, the batteries, and the charger connected in *parallel* - which is correct for what you want to do. However, a 12v power supply (batteries, charger, or both) are at, or very close to the maximum input voltage spec the Uno. The Uno's voltage regulator has to waste - as heat - a good deal of power in reducing the voltage to 5v. And if the power supply provides any more than 12 volts, it will exceed regulator's spec.

Update:

> how much do you think it would go over?

We can't know without knowing the specs on the particular batteries and charger. A battery charger has to apply a higher voltage than the present voltage of the battery it is trying to charge, in order to drive current into the battery against its (the battery's) voltage. You need to know more about the charger and the batteries.

Update 2:

> The batteries are 12V 7.2 Ah and they are PK12V7.2 as the product name.

Those Lead/Acid cells. I didn't find a spec for the charger, but  in automotive use, Lead/Acids are charged at 14.2 volts. Your Uno's regulator won't like that. I'm guessing you measured your charger's output voltage with no load.

Try measuring it with the batteries attached and at low, medium, or almost fully charged. That should give you a better idea. We can only guess without the specs but it sounds like these components would be pushing your Uno's regulator pretty hard.

If these components and the Uno part of a system that requires 12v for some other components, I'd suggest using 2 power supplies, 12v for the components that need it, and 7 volts into Vin (or 5v, if well regulated, into the 5v pin) on your Uno. The lower voltage could be supplied by a buck converter powered off of the 12v, which would fairly efficient and require only one charger.


message:
How to set the eeprom initial value when flashing an ESP32

As I use the EEPROM to persist data such as for provisioning the WiFi (SSID and password), I'd like to make sure that the *very first time* the ESP32 runs, it finds the initial '\0' for the SSID so that it does not run into the WiFi connection code block.

For this I need to set the initial values into the EEPROM when I flash the firmware.

I use platform IO.

How to do that?

body:
The ESP32 does not have a real EEPROM; instead, the data is stored in the external flash in the non-volatile storage (NVS) partition. The problem is, that the structure of this partition is proprietary. Only the SDK knows "where to find what" within NVS and any access to this partition is done using the SDK.

Unfortunately, the `EEPROM.h` library uses the NVS partition to store its values.
As the way how data is stored within NVS is closed source, you can't build a flash image that is guaranteed to work in different sketches or different versions of the SDK.
So, if you need to upload pre-made non-volatile data, the `EEPROM.h` library is practically useless.

A convenient alternative is to put that data in a file and store that file in a filesystem like `SPIFFS.h`.
This way, you define how data is stored/accessed yourself, so it's much less likely you run into problems when the core experiences changes.

Data upload is straight forward using `esptool.py`.


message:
Wiring multiple LCD displays to Arduino

I have multiple LCD displays and one Arduino and I just want to show some text on each display separately.

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

Is it possible to Wiring multiple LCD Displays for the single Arduino board?

Or maximum how many display can I connect one single Arduino?

  [1]: https://www.seeedstudio.com/Sipeed-Maixduino-Kit-for-RISC-V-AI-IoT-p-4047.html
  [2]: https://i.stack.imgur.com/unHfj.png

body:
For HD44780 based displays all the data, register select and read/write pins can be shared. A display only exists at the moment the E pin is toggled. They are designed to share a microprocessor's data bus.

So if you have 50 displays then you can (theoretically, see "fan out" below) run them from 50 "E" pins plus 6 (or 10 depending on if you want to run in 4 or 8 bit mode) shared pins.

Here's an example with 2 displays in 4-bit mode - just replicate for more:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/D3u0O.png)

<!-- End schematic -->

Note: power, ground and contrast connections omitted for brevity.

As you can see the LCDs share all their pins except the E pin. A third display will connect to the same pins, except its E pin would be unique.

Fan out
-------

Fan out is an important concept in digital electronics. An IO pin can only deliver a certain amount of current and each device a pin connects to adds "load" to that pin. Too many devices and the IO pin will struggle to control the devices properly.

To combat this a "bus transceiver" (such as the 74HC245) is commonly used. If one IO pin is capable of driving, for the sake of argument, 5 devices, and one bus transceiver is also capable of driving 5 devices then the IO pin could drive 5 bus transceivers giving you control over a potential 25 devices.


message:
7-Segment Display w/ Potentiometer

(Backstory) So, I took an computer engineering class in high school (grade 11 level), where I learned a bit about breadboarding as well as arduinos (I would like to stress a bit). It has been 5 years, and I don't remember much; but the other day my little brother started taking the same class. He has the following assignment, which I have also endeavored to try for fun:

(Not Backstory) I need to make a potentiometer control a 7-segment display so that it displays a number (0-9) based on the potentiometers value. I hopped on to tinkercad to test stuff out before acuatally doing anything, and I came up with the following real quick:

[![][1]][1]

  [1]: https://i.stack.imgur.com/UDoPS.png
I've tested the above model and I know it works, but the following code does not work.
```
int a = 2;
int b = 3;
int c = 4;
int d = 5;
int e = 6;
int f = 7;
int g = 8;
int potentiometer = 9;

void setup() {
  for(int pins = 2; pins <=8; pins++){
  pinMode(pins, OUTPUT);
 }
  pinMode(potentiometer, INPUT);
}

void loop() {
  int pRes;
  pRes = analogRead(potentiometer);
  if (pRes >=0 && pRes <=101){
    //0
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, LOW);
    digitalWrite(f, LOW);
    digitalWrite(g, HIGH);
    }
  else if (pRes >=102 && pRes <=203){
     //1
    digitalWrite(a, HIGH);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    }
  else if (pRes >=204 && pRes <=305){
     //2
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(c, HIGH);
    digitalWrite(d, LOW);
    digitalWrite(e, LOW);
    digitalWrite(f, HIGH);
    digitalWrite(g, LOW);
    }
  else if (pRes >=306 && pRes <=407){
    //3
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, LOW);
    }
  else if (pRes >=408 && pRes <=509){
    //4
    digitalWrite(a, HIGH);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, LOW);
    digitalWrite(g, LOW);
  }
  else if (pRes >=510 && pRes <=611){
    //5
    digitalWrite(a, LOW);
    digitalWrite(b, HIGH);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, HIGH);
    digitalWrite(f, LOW);
    digitalWrite(g, LOW);
    }
  else if (pRes >=612 && pRes <=713){
    //6
    digitalWrite(a, LOW);
    digitalWrite(b, HIGH);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, LOW);
    digitalWrite(f, LOW);
    digitalWrite(g, LOW);
    }
  else if (pRes >=714 && pRes <=815){
    //7
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    }
  else if (pRes >=816 && pRes <=917){
    //8
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, LOW);
    digitalWrite(f, LOW);
    digitalWrite(g, LOW);
    }
  else if (pRes >=918 && pRes <=1023){
    //9
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, LOW);
    digitalWrite(g, LOW);
    }
}
```

Can someone explain to me what I've done wrong (and offer corrections)?

body:
1. Only the pins with labels starting with “A” (A0 through A5 on the Uno)
   can be used as analog inputs.
2. The pin of the potentiometer that is currently not connected has to
   be connected to 5V.


message:
Pressed Buttons are permanently low and one of them is not working

I am a beginner to Arduino, and I'm having a problem in a project that I am currently working on.

I was just beginning to write the code, after preparing the components and the wiring, and suddenly two of my buttons never stopped outputting, despite my instructions to only output when the buttons are low, and the other one doesn't do anything at all.

I am using three buttons, one of them is a interruptor switch.

Here is my code:

    #include <Adafruit_NeoPixel.h>

    #define PIN 3  // input pin Neopixel is attached to
    #define NUMPIXELS 28 // number of neopixels in strip

    #define TRAVAO 8
    #define PISCA 13
    #define QUATRO_PISCAS 11

    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

    int redColor = 0;
    int greenColor = 0;
    int blueColor = 0;

    void setup() {
      pixels.begin();

      pinMode(TRAVAO, INPUT_PULLUP);
      pinMode(PISCA, INPUT_PULLUP);
      pinMode(QUATRO_PISCAS, INPUT_PULLUP);

      Serial.begin(9600);
    }

    void loop() {
      if(digitalRead(TRAVAO) == LOW) {
       Serial.print("bbb");
      }

      if(digitalRead(PISCA) ==  LOW) {
       Serial.print("ccc");
      }

      if(digitalRead(QUATRO_PISCAS) ==  LOW) {
       Serial.print("ddd");
      }

      delay(1);
    }

Here is my arduino:

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

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

body:
Here's your problem:

    #define TRAVAO 8

As you can see from your wiring diagram, nothing is connected to pin 8.


message:
atTiny85 5V and servo usage

I have an AtTiny85 that I would like to move a servo on I/O "4" for [this][1] project.

I can't seem to get it to work, no matter what I do. I had tons of issues getting it to program, but I've gotten it to a place where it will program a blink, and it will also blink the LED in the circuit diagram in the link provided. I have the servo wired, and I'm pretty darn sure the wiring is correct (when are we 100% sure?). I've tried these programs to no success:

    // Trinket Servo Monster sketch
    // Hardware: Adafruit Trinket (3V or 5V), micro servo, LED + resistor
    // Libraries: uses Adafruit_TiCoServo library to manage servo pulses,
    // even though NeoPixels are NOT being used here.

    #if !defined(__AVR_ATtiny85__)
     #error "This code is for ATtiny boards"
    #endif
    //#include <Adafruit_TiCoServo.h>
    #include <ServoManager.h>
    #include <avr/power.h>

    // Servo parameters.  Pin MUST be 1 or 4 on a Trinket.  Servo position
    // is specified in raw timer/counter ticks (1 tick = 0.128 milliseconds).
    // Servo pulse timing is typically 1-2 ms, but can vary slightly among
    // servos, so you may need to tweak these limits to match your reality.
    #define SERVO_PIN  4 // Pins 1 or 4 are supported on Trinket
    #define SERVO_MIN  4 // ~1 ms pulse
    #define SERVO_MAX 26 // ~2 ms pulse

    #define LED_PIN    0 // "Eye" LED is connected here

    PrecisionServo* servo;

    void setup(void) {
      ServoManager::setup(1);
      servo = ServoManager::createServo(4);
      //servo->setSetting(SERVO_MEDIUM_ENDPOINT);

    //#if (F_CPU == 16000000L)
      // 16 MHz Trinket requires setting prescale for correct timing.
      // This MUST be done BEFORE servo.attach()!
    //  clock_prescale_set(clock_div_1);
    //#endif
      //servo.attach(SERVO_PIN);
      pinMode(LED_PIN, OUTPUT);
      digitalWrite(LED_PIN, HIGH);
    }

    uint32_t lastLookTime = 0; // Time of last head-turn

    void loop(void) {

      //unsigned long t = millis(); // Current time

      // If more than 1/2 second has passed since last head turn...
      servo->setTarget(0);
      ServoManager::waitUntilFinished();

      servo->setTarget(180);
      ServoManager::waitUntilFinished();

      // Unrelated to head-turn check,
      if(random(10) == 0) { // there's a 1-in-10 chance...
        // ...of an "eye blink":
        digitalWrite(LED_PIN, LOW);  // The LED turns OFF
        delay(random(50, 250));      // for just a short random moment
        digitalWrite(LED_PIN, HIGH); // then back ON
      }

      //delay(1000); // Repeat loop() about 10 times/second
    }

SO I scaled back and just tried to write a high out as follows:

    void setup() {
      pinMode(4, OUTPUT);
    }

    void loop() {
      digitalWrite(4, HIGH);
      delayMicroseconds(1000);
      // 1 millisecond determines the servo going forwards
      digitalWrite(4, LOW);
      delay(19);
    }

But this didn't work either.

Shouldn't the servo move with just a write to 'high' and 'low'?

  [1]: https://learn.adafruit.com/guardian-robot-zelda-botw

body:
The servo requires a PWM signal to the control lead to move.

This datasheet kind of bears that out...

http://www.datasheetcafe.com/sg90-datasheet-pdf-9-g-micro-servo/


message:
Drivers for CH9102X serial port chip

Some ESP-family cheap boards manufacturers had recently moved to CH9102X serial port chip (from CP2102), and it seems the drivers for CH9102X are hard to find.

Where can I download them?

body:
It can be found on manufacturer's website: http://www.wch.cn/search?q=CH9102&t=downloads

Please note, that some drivers' downloading pages are only available in Chinese, so make sure you open Chinese (not English) site version.

Windows CDC driver: http://www.wch.cn/downloads/CH343CDC_ZIP.html

Windows SER driver: http://www.wch.cn/downloads/CH343SER_ZIP.html

MacOS driver: http://www.wch.cn/downloads/CH34XSER_MAC_ZIP.html

P.S. For Windows 7 x64 I recommend using the first one (CDC). SER driver didn't work for me because of signing issues.


message:
How do I run 4 LEDs sequentially based off of a push button input?

I am trying to create a program that runs 4 LEDs sequentially while also being able to do other things with different inputs and outputs. Because of this, I am using the millis function and not the delay. I have the code working but not exactly how I want it. It runs through the LEDs and turns them off then runs through again like it is supposed too but there are two problems:
1. It will pass through the first if statement, then the first again then to the second, then it will go through the first, the second, then the third, etc. I want it to cascade through the if statements, keeping the LED from the previous steps on without repeating. It is causing the LEDs to flash super quick.
2. The code still runs even if the input is read as LOW as it is dependent on millis. I somehow need it to start from the beginning every time the button is pushed and reset when the button is not pressed.

below the code is a picture of the serial monitor showing the program running through every if statement and not staying in one and moving to the next. If needed, I can add a video showing what the LEDs do.

below is the code
```
//Code to build 4 sequentially run LEDs that reset everytime there is not input
int RTS_IN  = A0; //input button

//Output LEDs, assigning them to pins
int LED_5 = 5;
int LED_6 = 6;
int LED_7 = 7;
int LED_8 = 8;

//1 second for each time interval
unsigned long Time1 = 1000;
unsigned long Time2 = 2000;
unsigned long Time3 = 3000;
unsigned long Time4 = 4000;
unsigned long Time5 = 5000;

//variables for holding millis values
unsigned long currentMillis;
unsigned long newMillis = 0;

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

  pinMode(RTS_IN, INPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
  currentMillis = millis();

  //using sequential method if the input button pressed and held
  if(digitalRead(RTS_IN) == HIGH)
  {
    sequential();
  }
  //keeping LEDs OFF if button has been released
  else
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

//method to run LEDs sequentially
void sequential()
{

  //if statement checking to see if a second has passed to allow the first led to turn on
  if(currentMillis - newMillis >= Time1)
  {
    Serial.println("5 is on");

    digitalWrite(LED_5, HIGH);
    delay(1);

    //if statement checking to see if 2 seconds has passed to allow the second led to turn on
    if(currentMillis - newMillis >= Time2)
    {
      Serial.println("6 is on");

      digitalWrite(LED_6, HIGH);
      delay(1);

      //if statement checking to see if 3 seconds has passed to allow the third led to turn on
      if(currentMillis - newMillis >= Time3)
      {
        Serial.println("7 is on");

        digitalWrite(LED_7, HIGH);
        delay(1);

        //if statement checking to see if 4 seconds has passed to allow the fourth led to turn on
        if(currentMillis - newMillis >= Time4)
        {
          Serial.println("8 is on");

          digitalWrite(LED_8, HIGH);
          delay(1);

          //if statement to turn off LEDs and wait a second before turning the first back on
          if(currentMillis - newMillis >= Time5)
          {
            Serial.println("All off");

            digitalWrite(LED_5, LOW);
            digitalWrite(LED_6, LOW);
            digitalWrite(LED_7, LOW);
            digitalWrite(LED_8, LOW);

            //this is in order to add a period of this process to each of the
            //interval times to keep up with millis without this, they would all stay on
            Time1 = Time1 + 5000;
            Time2 = Time2 + 5000;
            Time3 = Time3 + 5000;
            Time4 = Time4 + 5000;
            Time5 = Time5 + 5000;
            delay(1);

          }
        }
      }
    }
  }
}

```
updated code below with if else statements and the other programming combined
```

const int RTS_IN  = A0;
const int LTS_IN = A1;

//break signal
const int BS_IN  = A2;
const int BS_OUT = 11;

//reverse signal
const int RS_IN  = A3;
const int RS_OUT = 10;

const int NR_OF_LEDS = 4;
const int RIGHTLEDS[NR_OF_LEDS] = { 6, 7, 8, 9 };
const int LEFTLEDS[NR_OF_LEDS] = { 5, 4, 3, 2 };
const int interval = 100;

int nrOfRightLedsOn = 0;
int nrOfLeftLedsOn = 0;

unsigned long t = 0;

void StateRight();
void StateRightProcess();

void StateLeft();
void StateLeftProcess();

boolean oldSwitchStateRS = LOW;
boolean newSwitchStateRS = LOW;
boolean oldSwitchStateBS = LOW;
boolean newSwitchStateBS = LOW;

void setup()
{
  Serial.begin(9600);
  pinMode(RTS_IN, INPUT);
  pinMode(LTS_IN, INPUT);

  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    pinMode(RIGHTLEDS[led], OUTPUT);
  }

  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    pinMode(LEFTLEDS[led], OUTPUT);
  }

}

void loop()
{
  StateRight();
  StateLeft();

  newSwitchStateBS = digitalRead(BS_IN);
   if(newSwitchStateBS != oldSwitchStateBS)
  {
    if(newSwitchStateBS == HIGH)
    {
      digitalWrite(BS_OUT, HIGH);
    }
    else
    digitalWrite(BS_OUT, LOW);
    oldSwitchStateBS = newSwitchStateBS;
  }

 newSwitchStateRS = digitalRead(RS_IN);
  if(newSwitchStateRS != oldSwitchStateRS)
  {
    if(newSwitchStateRS == HIGH)
    {
      digitalWrite(RS_OUT, HIGH);
    }
    else
    digitalWrite(RS_OUT, LOW);
    oldSwitchStateRS = newSwitchStateRS;
  }

}

void StateRight()

{
  if(digitalRead(RTS_IN) == LOW)
  {
    SwitchRightLedsOff();
    nrOfRightLedsOn = 0;
    t = millis() + interval;
  }
  else if (nrOfRightLedsOn < NR_OF_LEDS)
  {
    StateRightProcess();
  }
  else
  {
    if(millis() >= t + interval)
    {
      t = millis();
      SwitchRightLedsOff();
      nrOfRightLedsOn = 0;
    }
  }
}

void StateRightProcess()
{
  if(millis() >= t + interval)
  {
    t = millis();
    digitalWrite(RIGHTLEDS[nrOfRightLedsOn], HIGH);
    nrOfRightLedsOn++;
  }
}

void SwitchRightLedsOff()
{
  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    digitalWrite(RIGHTLEDS[led], LOW);
  }
}

void StateLeft()
{
  if(digitalRead(LTS_IN) == LOW)
  {
    SwitchLeftLedsOff();
    nrOfLeftLedsOn = 0;
    t = millis() + interval;
  }
  else if (nrOfLeftLedsOn < NR_OF_LEDS)
  {
    StateLeftProcess();
  }
  else
  {
    if (millis() >= t + interval)
    {
      t = millis();
      SwitchLeftLedsOff;
      nrOfLeftLedsOn = 0;
    }
  }
}

void StateLeftProcess()
{
  if (millis() >= t + interval)
  {
    t = millis();
    digitalWrite(LEFTLEDS[nrOfLeftLedsOn], HIGH);
    nrOfLeftLedsOn++;
  }
}

void SwitchLeftLedsOff()
{
  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    digitalWrite(LEFTLEDS[led], LOW);
  }
}

```

body:
To be honest, I don't understand exactly the problems, but I try to give some guideline and hope you can use the idea to fix your problems.

What you need is a so called 'state machine'.

I think (according to your problem) that you have 6 states:

    0 Idle (no sequence)
    1 One LED on
    2 Two LEDs on
    3 Three LEDs on
    4 Four LEDs on
    5 No LEDs on

For this you can best use an `enum` type and global variable with similar values:

    enum EState
    {
        Idle,
        OneLedOn,
        TwoLedsOn,
        ThreeLedsOn,
        FourLedsOn,
        NoLedsOn
    }

    EState _state;

You need a function to check the new state, depending on the current state. In words something like:

    current     When                          Action           New
    state                                                      state
    --------    ----------------------------  ---------------- -----
    Idle        digitalRead(RTS_IN) == HIGH   Start counter    OneLedOn
                                              Switch on LED 0
    OneLedOn    digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
                5 seconds have passed         Switch on LED 1
                                              Start counter    TwoLedsOn
    TwoLedsOn   digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
                5 seconds have passed         Switch on LED 2
                                              Start counter    ThreeLedsOn
    ThreeLedsOn digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
                5 seconds have passed         Switch on LED 3
                                              Start counter    ThreeLedsOn
    FourLedsOn  digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
                5 seconds have passed         Switch LEDs off
                                              Start counter    NoLedsOn
    NoLedsOn    digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
                5 seconds have passed         Switch on LED 0
                                              Start counter    OneLedn

(if you would draw one circle for each state and arrows between them, a so called UML State Diagram, you will see a much clearer way to depict the states and flows).

I don't have a compiler so I do it out of my head.

    void Process()
    {
        switch (_state)
        {
        case EState::Idle:
            if ((digitalRead(RTS_IN) == HIGH)
            {
                _time = millis();
                digitalWrite(LED_5, HIGH);
                _state = EState::OneLedOn;
            }
            break;
        case EState::OneLedOn:
            if ((digitalRead(RTS_IN) == LOW)
            {
                SwitchLedsOff();
                _state = Idle;
            }
            else if (millis() > time + 5000)
            {
                _time = millis();
                digitalWrite(LED_6, HIGH);
                _state = EState::TwoLedsOn;
            }
            break;
        case EState::TwoLedsOn:
           ...
    }

The function `SwitchLEDsoff` sets all LEDs to low, and you only need one `unsigned long _time` global variable which you update when a new state starts and check in most states.

Note that high likely you can optimize this (like making each state its own function and removing almost duplicated code), but the main goal is to let you understand how to use a state machine and to use it in this sketch and future sketches.

**Update**

The following sketch is the same as yours but:

- Optimized for reducing code duplication (`ProcessState`)
- Introduced constants
- Introduced array for LEDs to iterate over
- Removed the state, instead used `_nrOfLedsOn`
- Removed idle state, handled separately now
- Prefixed global variables with an underscore (personal preference)
- Better names for variables/functions
- Used prototypes to put functions in logical order (high level to low level)

Code:

    const int RTS_IN  = A0;
    const int NR_OF_LEDS = 4;
    const int LEDS[NR_OF_LEDS] = { 5, 6, 7, 8 };
    const int DURATION = 300;

    int _nrOfLedsOn = 0;
    unsigned long _time = 0;

    void ProcessState();
    void ProcessLedsState();
    void SwitchLedsOff();

    void setup()
    {
        Serial.begin(9600);
        pinMode(RTS_IN, INPUT);
        for (int led = 0; led < NR_OF_LEDS; led++)
        {
            pinMode(LEDS[led], OUTPUT);
        }
    }

    void loop()
    {
        ProcessState();
    }

    void ProcessState()
    {
        if (digitalRead(RTS_IN) == LOW)
        {
            SwitchLedsOff();
            _nrOfLedsOn = 0;
            _time = millis() + DURATION + 1;
        }
        else if (_nrOfLedsOn < NR_OF_LEDS)
        {
            ProcessLedsState();
        }
        else
        {
            if (millis() > _time + DURATION)
            {
                _time = millis();
                SwitchLedsOff();
                _nrOfLedsOn = 0;
            }
        }
    }

    void ProcessLedsState()
    {
        if (millis() > _time + DURATION)
        {
            _time = millis();
            digitalWrite(LEDS[_nrOfLedsOn], HIGH);
            _nrOfLedsOn++;
        }
    }

    void SwitchLedsOff()
    {
        for (int led = 0; led < NR_OF_LEDS; led++)
        {
            digitalWrite(LEDS[led], LOW);
        }
    }


message:
ESP32 Access Point and HTTP Web Server, how to send multiple parameters?

I made this minimal example in order to figure out how to get requests (or whatever they are called) to display in the serial monitor. However, none of the query parameters (in the URL) can be seen in the serial monitor at 115200 baud.

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

# File structure

sketch (folder)

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

# sketch.ino

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

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

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

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

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

    AsyncWebServer server(80);

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

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

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

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

    // Route for root / web page
      server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
        request->send(SPIFFS, "/index.html", String(), false );
      });

      // Index.HTML NAVIGATION BUTTIONS ************************************************

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

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

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

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

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

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

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

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

      server.begin();
    }

    void loop() {}

# index.html

    <!DOCTYPE html>

Main Menu

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

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

# selection.html

    <!DOCTYPE html>

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

     Shape Size:

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

Speed:

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

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

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

    </form>

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

How is the data (size and speed) viewable in the serial monitor? What needs to change?

body:
You have two handlers for "/":
```
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", String(), false );
  });
```

and
```
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
  {

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

    for (int i = 0; i < paramsNr; i++)
    {
...
```

Only one will be called when you load the top level page. You'll need to combine them to both serve `index.html` and process the parameters being passed to it.


message:
Convert from raw data to float from DDSU666-H

[![Here is the modbus register Map i find from CHINT][1]][1]

Hi professers, i am trying to read the data from DDSU666-H ( Smart metter) CHINT using modbus RTU, i only get the raw data but i don't know how to convert it to float , in the code below is about Voltage , real data is 233,4V but in the serial is like this, can some one help me to convert this one to float 233,4V, thank you so much!
[![enter image description here][2]][2]

 Here is my code, i get it from modbusmaster library.
/*

  RS485_HalfDuplex.pde - example using ModbusMaster library to communicate
  with EPSolar LS2024B controller using a half-duplex RS485 transceiver.

  This example is tested against an EPSolar LS2024B solar charge controller.
  See here for protocol specs:
  http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf

  Library:: ModbusMaster
  Author:: Marius Kintel <marius at kintel dot net>

  Copyright:: 2009-2016 Doc Walker

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

#include <ModbusMaster.h>

/*!
  We're using a MAX485-compatible RS485 Transceiver.
  Rx/Tx is hooked up to the hardware serial port at 'Serial'.
  The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE      50
#define MAX485_RE_NEG  52

// instantiate ModbusMaster object
ModbusMaster node;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

void setup()
{
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  // Modbus communication runs at 115200 baud
  Serial1.begin(9600);
  Serial.begin(9600);

  // Modbus slave ID 1
  node.begin(12, Serial1);
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}
void loop()
{
  uint8_t i, result;
  uint16_t data[2];
  union
  {
    uint32_t j;
    float f;
  } u;
  // Read 16 registers starting at 0x3100)
  Serial.println("-----------------------");
  result = node.readHoldingRegisters(0x2000, 2);
  if (result == node.ku8MBSuccess)
  {
    for (i = 0; i < 2; i++)
    {
      data[i] = node.getResponseBuffer(i);
    }
    Serial.println(data[0]);
    Serial.println(data[1]);
    u.j = ((unsigned long)data[1] << 16 | data[0]);
    Serial.println(u.f);
  }

  [1]: https://i.stack.imgur.com/3FwyI.png
  [2]: https://i.stack.imgur.com/1Uwo8.png

body:
Seems the data sheet does not specify the endianness. Or maybe it does,
but you are not showing it. From the numbers you get, it appears that
the floats come in big-endian order, whereas your code assumes
little-endian.

Change the assignment of `u.j` as follows:

```c++
u.j = ((unsigned long)data[0] << 16 | data[1]);
```


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

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

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

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

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

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

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

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

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

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

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

* Port the code to the Arduino.

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

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

It would be used like this:

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

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

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

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

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

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

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

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

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

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

  fc ≈ k fs / (2π)

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

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


message:
Wind speed measuring using Hall sensor

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

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

```cpp
volatile byte revolutions;

unsigned int rpmilli;
float speed;

unsigned long timeold=0 ;

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

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

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

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

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

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

         speed = rpmilli 1.288053600;

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

void rpm_fun()
{
    revolutions++;
}

```

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

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

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

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


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

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

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

Our code:

```cpp
#include <SoftwareSerial.h>

int IN1 = 13;
int IN2 = 12;

int IN3 = 8;
int IN4 = 9;

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

}

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

The DC motor is not responding at all

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

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

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

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

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

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

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


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

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

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

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

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

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

# File structure

sketch (folder)

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

# sketch.ino

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

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

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

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

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

    AsyncWebServer server(80);

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

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

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

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

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

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

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

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

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

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

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

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

      server.begin();
    }

    void loop() {}

# index.html

    <!DOCTYPE html>

Main Menu

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

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

# selection.html

    <!DOCTYPE html>

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

     Shape Size:

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

Speed:

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

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

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

    </form>

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

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

I have tried...

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

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

* messing with HTML stuff (nothing changed)

body:
This is not an answer per se.

Posted as an answer because of attached images.

It is unclear what you are actually asking.

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

Here is the trace from the server.

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

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

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

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

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


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

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

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

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

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


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


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

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

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

Here is my code:

    #include  <avr/interrupt.h>

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

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

    #define F_CPU 16000000UL

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

    #define LED     DIO13

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

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

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

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

    volatile uint32_t milliseconds = 0;

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

    #define PULSECOUNT_X2 16
    volatile uint8_t edges = 0;

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

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

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

    }

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

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

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

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

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

      GTCCR = 0; // re-enable clocks
    }

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

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

      uint32_t pingtime = INTERVAL;

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

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

          // reset edge counter
          edges = PULSECOUNT_X2;

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

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

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

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

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

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

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

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

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

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

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

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

    ISR(TIMER0_COMPA_vect) {
      milliseconds++;
    }

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

body:
You have not enabled the comparator interrupt.

Just need to change the line where you set ACSR.

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

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

Can also be achieved with.

    ACSR = 0x0B

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

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

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

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

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

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

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

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

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


message:
Writing Arduino code for MPXV6115V pressure sensor

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

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

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

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

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

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

    P = (Vout/Vs - 0.92)/0.007652

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

    voltage = analogRead(pin) / 1023.0 * 5.0;

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


message:
Problem with IR remote and Pushbutton for digispark

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

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

void loop() {

  int key = getIrKey();

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

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

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

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

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

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

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

  digitalWrite(relay1, Relay1State);
  lastButton1State = reading;

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

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

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

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

Any advise, please?

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

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

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


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

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

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

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

Where I say ...

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

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

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