body:
Working on an IoT project.
Environment:
- Adafruit Feather M4 Express
- Adafruit MusicMaker FeatherWing (amplified, this is a VS1053 at heart)
- Silicognition PoE FeatherWing (electrically compatible with the Adafruit Ethernet FeatherWing)
- PlatformIO with Visual Studio Code on a Mac (all libraries are up-to-date)

The Problem:
I can get either the Ethernet to work or the MusicMaker to work, but not both at the same time.
There are no errors during initialization, they just don't work.

Specifically, the MusicMaker's `sineTest()` method doesn't generate any sound if Ethernet has been initialized. Likewise, the Ethernet client's `connect()` method is unable to connect if the MusicMaker is initialized. Both methods work fine if the other device hasn't been initialized.

Feather Pins:
```
Purpose                    Pin
-------------------------- ---
VS1053 Chip select           6
VS1053 Data/command select  10
VS1053 Data request          9
SD Card Chip select          5
Ethernet Chip select        14
```
Note that I'm not currently using the SD card and haven't called its `begin()` method.
Note also that the Ethernet chip select is on a non-standard pin because the default conflicts with the VS1053 data/command select.

Also, the PoE FeatherWing has an EEPROM on it with a unique MAC address and reading this works fine.

One other note: I thought that I had this combination working in an earlier prototype a few months ago, but that may have been with the Feather 32U4.

TIA.

The prototype code:
```
#include <Arduino.h>
#include <Adafruit_VS1053.h>
#include <Ethernet.h>
#include <IPAddress.h>
#include <SPI.h>
#include <Wire.h>

//
// Pins for the Ethernet and MusicMaker FeatherWings.
// NOTE: These definitions assume a Feather M4 Express with a PoE FeatherWing
//       modified to have its chip select on pin 14 because the default conflicts
//       with the MusicMaker's DCS pin.
//
#define VS1053_CS       6     // VS1053 chip select pin (output)
#define VS1053_DCS     10     // VS1053 Data/command select pin (output)
#define SD_CARD_CS      5     // Card chip select pin
#define VS1053_DREQ     9     // VS1053 Data request, ideally an Interrupt pin
#define ETHERNET_CS    14     // Ethernet chip select pin. Note that this is custom because the default conflicts with VS1053_DCS.

//
// PoE FeatherWing.
//
#define MAC_EEPROM_I2C_ADDRESS      0x50  // I2C address of the 24AA02E48 EEPROM chip that contains our MAC address (on the PoE FeatherWing).
#define MAC_EEPROM_REGISTER         0xFA  // Register within the 24AA02E48 that contains the first byte of our MAC address.

#define HANG      while( true ){ delay( 10 ); }
IPAddress         host = { 172, 24, 110, 1 };
uint16_t          port = 8000;
const char*       path = "/sounds/DingDong.mp3";
Adafruit_VS1053   player{ Adafruit_VS1053( -1, VS1053_CS, VS1053_DCS, VS1053_DREQ ) };
EthernetClient    client;
uint8_t           mp3Buf[VS1053_DATABUFFERLEN];
uint32_t          contentLength;
byte              macAddress[6]{};

uint32_t          beginRequest();
void              readMacAddress( byte* );

void setup()
{
  Serial.begin( 115200 );
  while( !Serial ){ delay( 10 ); }
  Serial.println( "MusicMaker/Ethernet Prototype" );

  Wire.begin();

  Ethernet.init( ETHERNET_CS );
  readMacAddress( macAddress );
  if( !Ethernet.begin( macAddress ))
  {
    Serial.printf( "Unable to initialize the network; hardware status is %d\n",
                   Ethernet.hardwareStatus());
    HANG;
  }

  Serial.print( "Mac address: " );
  for( int ii = 0; ii < 6; ii++ )
  {
    if( macAddress[ii] < 16 ) { Serial.print( '0' ); }
    Serial.print( macAddress[ii], HEX );
    if( ii < 5 ) { Serial.print( ':' ); }
  }
  Serial.println();
  Serial.print( "DNS IP:      " ); Serial.println( Ethernet.dnsServerIP());
  Serial.print( "Local IP:    " ); Serial.println( Ethernet.localIP());
  Serial.print( "Gateway IP:  " ); Serial.println( Ethernet.gatewayIP());
  Serial.print( "Subnet mask: " ); Serial.println( Ethernet.subnetMask());

  if( !player.begin())
  {
    Serial.println( "Unable to initialize the MusicMaker" );
    HANG;
  }
  Serial.println( "Initialized the MusicMaker" );
  player.setVolume( 40, 40 );
  player.sineTest( 0x44, 1000 ); // 1KHz tone for one second.

  contentLength = beginRequest();
  Serial.printf( "HTTP content length: %d\n", contentLength );
}

void loop()
{
  if( player.readyForData())
  {
    if( client.available() > 0 )
    {
      uint8_t bytesRead = client.read( mp3Buf, VS1053_DATABUFFERLEN );
      if( bytesRead > 0 )
      {
        player.playData( mp3Buf, bytesRead );
        contentLength -= bytesRead;
        if( contentLength <= 0 )
        {
          Serial.println( "That should be all of our sound" );
        }
      }
    }
  }
}

uint32_t beginRequest()
{
  if( !client.connect( host, port ))
  {
    Serial.print( "Unable to connect to " );
    Serial.print( host ); Serial.print( ':' ); Serial.println( port );
    HANG;
  }

  Serial.print( "GET " ); Serial.print( path ); Serial.print( " HTTP/1.1\r\n" );
  Serial.print( "Host: " ); Serial.print( host ); Serial.print( "\r\n" );
  Serial.print( "Connection: close\r\n\r\n" );

  client.print( "GET " ); client.print( path ); client.print( " HTTP/1.1\r\n" );
  client.print( "Host: " ); client.print( host ); client.print( "\r\n" );
  client.print( "Connection: close\r\n\r\n" );

  char http[] = "HTTP/";
  client.find( http );                  // Skip over the HTTP/ part of the header.
  client.parseFloat( SKIP_WHITESPACE ); // Skip over the HTTP version number.

  int httpStatus = client.parseInt( SKIP_WHITESPACE );
  if( httpStatus < 200 || httpStatus > 299 )
  {
    Serial.printf( "GET request failed; HTTP status is %d\n", httpStatus );
    client.stop();
    HANG;
  }

  char lengthHeader[] = "Content-Length:";
  client.find( lengthHeader );
  int contentLength = client.parseInt();

    char endOfHeaders[] = "\r\n\r\n";
  if( !client.find( endOfHeaders ))
  {
    Serial.println( "Invalid HTTP response (missing trailing line endings)" );
    client.stop();
    HANG;
  }
  return contentLength;
}

void readMacAddress( byte* addr )
{
  Wire.beginTransmission( MAC_EEPROM_I2C_ADDRESS );
  Wire.write( MAC_EEPROM_REGISTER );
  int failed = Wire.endTransmission();
  if( failed )
  {
    Serial.printf( "Unable to retrieve MAC address; endTransmission returned %d\n", failed );
    HANG;
  }

  byte* b = addr;
  int bytesRead = Wire.requestFrom( MAC_EEPROM_I2C_ADDRESS, 6 );
  if( bytesRead < 6 )
  {
    Serial.printf( "Unable to retrieve MAC address; fewer than six bytes\n" );
    HANG;
  }

  while( Wire.available())
  {
    *b++ = Wire.read();
  }
}
```

title: Can't get Adafruit MusicMaker and Ethernet to work at the same time

Answers: 1

body:
Turned out to be a hardware problem.

The PoE FeatherWing's default CS pin conflicts with the MusicMaker's DCS pin. The PoE CS pin can be changed by cutting a trace on the back of the board and bodging a wire from a pad to whatever pin you want to use instead. I had done that.

Turns out though, that I hadn't cut it completely. This was causing the Ethernet library to pull the MusicMaker DCS low every time it pulled the Ethernet CS low.

I finally figured it out when I hooked up a logic analyzer to all of the CS pins and the SPI pins. It was very clear that MusicMaker DCS was going low with Ethernet CS.

Yay Logic Analyzer.


body:
I am trying to compare two string but each time i am getting awkward results. When i use Equals() function i always get the wrong answer and never satisfy the IF statement. When i use compareTo() function i always get the right answer (which is btw not correct) but it always just satisfy the IF statement.

```c++
String input;
String Answer = "cat";

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

void loop()
{
  while (Serial.available() == 0)
  {
    Serial.readStringUntil('\n');
    if (input.equals(Answer))
    {
      Serial.println(input + ", Correct");
    }
    else
    {
      Serial.println(input + ", wrong");
    }
  }
}
```

Above is the code i am using to learn the string Comparison.

title: String Comparison

Answers: 1

body:
You have defined a variable named `input`, but you never assign a value
to it. It should thus always have its initial value, which is an empty
string.

Here:

```c++
Serial.readStringUntil('\n');
```

you probably meant

```c++
input = Serial.readStringUntil('\n');
```


body:
## Problem

If the loop runs only one simulated pin and uses a filter, it will output normally (analog 1600~2200, filter 0~500), but creating an array to store multiple filtered simulated pin values will cause problems, and the output will be abnormal (10000~80000).

![2022-04-15--15-00-07_fps=8_scale=720_max_colors=128|690x298](https://aws1.discourse-cdn.com/arduino/original/4X/6/9/5/6950edfbf1acdc9eed2746e95fa0e06828356b4f.gif)

If analog read six sensors, and their value is 1600~2200.

It used the code below.

```C
#include "EMGFilters.h"
#define SERIAL_TX_BUFFER_SIZE 4096 //修改串口接收缓冲区大小为2048
const int SensorInputPin[] = {A0, A1, A2, A3, A4, A5};
EMGFilters myFilter[6];
SAMPLE_FREQUENCY sampleRate = SAMPLE_FREQ_500HZ;
NOTCH_FREQUENCY humFreq = NOTCH_FREQ_50HZ;

void setup()
{

    for (int i = 0; i < 6; i++)
    {
        myFilter[i].init(sampleRate, humFreq, true, true, true);
    }
    Serial.begin(115200);
    Serial1.begin(250000);
    analogReadResolution(12);
}
void loop()
{
    long time = millis();
    int x[6] = {0,0,0,0,0,0};
    int analog[6] = {0,0,0,0,0,0};

    for (int index = 0; index < 6; index++)
    {
        //x[index] = myFilter[index].update(analogRead(SensorInputPin[index]));
        analog[index] = analogRead(SensorInputPin[index]);
    }
    while ((millis() - time) < 2)
    {
        delayMicroseconds(100);
    }
    Serial.printf("filter:%d %d %d %d %d %d analog:%d %d %d %d %d %d\n", x[0], x[1], x[2], x[3], x[4], x[5],analog[0],analog[1],analog[2],analog[3],analog[4],analog[5]);
    Serial1.printf("<%d,%d,%d,%d,%d,%d>", x[0], x[1], x[2], x[3], x[4], x[5]);
}
```

Change `index<6` to `index<2`, and uncomment `\\x[index] = myFilter[index].update(analogRead(SensorInputPin[index]));`

It will be a normal output using two inputs and filters.

![2022-04-15--15-15-26_fps=8_scale=720_max_colors=128|690x341](https://aws1.discourse-cdn.com/arduino/original/4X/5/e/9/5e9e39c25020a7816c04deb0cc7cdabc3f2de437.gif)

But changing `index=0;index<2` to `index=0;index<6` will be abnormal output.
![2022-04-15--15-29-32_fps=8_scale=720_max_colors=28|690x323](https://aws1.discourse-cdn.com/arduino/original/4X/e/b/c/ebc212b30692150bc1cfb0c29c4d9733a6195105.gif)

If changing to `index=3;index<4` or `index=2;index<3`...etc, it will be normal output:
![2022-04-15--15-15-43_fps=8_scale=720_max_colors=128|690x459](https://aws1.discourse-cdn.com/arduino/original/4X/0/5/8/05885f12cbba1c227d4f4349a169a8979a2f8caa.gif)

Sketch:
![image|470x500](https://aws1.discourse-cdn.com/arduino/optimized/4X/b/f/b/bfb266cf4e5eb7357b6804bb7bb3a9fbd7f75694_2_705x750.png)
![image|667x500](https://aws1.discourse-cdn.com/arduino/original/4X/5/5/3/553b46bb94559258b980463677a5bdee60e6a63d.png)
![](https://aws1.discourse-cdn.com/arduino/optimized/4X/1/b/c/1bccfe458e8f9843f7c8312806ff5909fd09b390_2_517x351.jpeg)
![](https://aws1.discourse-cdn.com/arduino/optimized/4X/d/1/4/d140c573d60e65c1333760ca63b1a9155da322bd_2_601x750.jpeg)
![](https://aws1.discourse-cdn.com/arduino/optimized/4X/6/e/c/6ec16040627057412528f8ec8bf60ee7da128bf1_2_273x373.jpeg)

XIAO MCU schematic in the HTML: https://files.seeedstudio.com/wiki/Seeeduino-XIAO/res/Seeeduino-XIAO-v1.0-SCH-191112.pdf

I don't have a sensor schematic.

Filter code: https://github.com/oymotion/EMGFilters/blob/master/EMGFilters.cpp

I hope each simulation output to look like the first Gif(normal output), what should I do to achieve this?

  [1]: https://i.stack.imgur.com/uzcRR.gif

title: Why use multiple filters output thousands value, use one or two filter can output normal value?

Answers: 1

body:
This is a bug in the filter library you are using. [It has already been
reported][bug] (by you, maybe?).

As Majenko and chrisl suggested in comments, the crux of the problem is
that you need one filter per input channel. Using multiple instances of
`EMGFilters` seems like the obvious solution. Alas, the library keeps
the filter state in global variables, which essentially means your six
filter objects all reference the same actual filter.

[bug]: https://github.com/oymotion/EMGFilters/issues/3


body:
```
#include <Preferences.h>

Preferences preferences;

const char* roomname_long = "String 1";
const char* roomname_short = "String2";
const char* roomname_long_test = "String 3";
String roomname;

void setup() {
  Serial.begin(115200);
  preferences.begin("app",false);

  preferences.begin("credentials", false);
  preferences.putString("roomname_long", roomname_long);
  preferences.putString("roomname_short", roomname_short);
  preferences.putString("roomname_long", roomname_long_test);

  roomname = preferences.getString("roomname_long", "");

  Serial.println(roomname_long);
  Serial.println(roomname_short);
  Serial.println(roomname);

  preferences.end();
}

void loop() {

}
```

I try to save some data on my esp32 it works actually but if I try to save another variable with the same key it writes over the String before how can I interrupt that?

on the Serial Monitor I got this:

```
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
String 1
String 2
String 3
```

I want that if I put another variable in "roomname_long" key it must not be overwritten.

So it should be stay on String 1

title: How to prevent replacing of the value for a key in Preferences?

Answers: 1

body:
You can use `isKey` to test if the preferences key is already set.

```
preferences.putString("roomname_long", roomname_long);
preferences.putString("roomname_short", roomname_short);
if (!preferences.isKey("roomname_long")) {
  preferences.putString("roomname_long", roomname_long_test);
}
```


body:
I have a Arduino Nano 33 BLE that I've been using for a while. I usually upload new programs to the board through USB with the board in a bootloader loop. The other day this stopped working. The board can successfully be put in the bootloader (slow pulsing light), however it does not appear as a TTY device on my computer. The last program I put on my device still works, and successfully outputs serial output (and I can even connect to the bluetooth module).

This leads me to believe my board is working, though I don't understand why I cannot upload via the bootloader. Interestingly the bootloader running makes the board pretty hot (hotter than my program running, is it in an infinite loop or something?).

I thought the bootloader might've been corrupted, so I re-uploaded the board's bootloader via a raspberry pi over OpenOCD (it's possible I did this incorrectly?). Now the device remains in the bootloader no matter what.

I'm wondering if it's possible I fried just the USB part of my board? is that likely? I did hook up the board to a wall adapter that is rated 12V @ 1.5A. The issue seemed to occur after this. Is the board able to handle 1.5A? Do I need to use an additional circuit to properly power the board off of this power adapter?

title: Arduino port not discovered with bootloader / Did I fry my board?

Answers: 0


body:
So I was reading about `Simple AutomaticLight Controller using LDR.` or with the help of LDRSenso. But I have `LM393 Photoresistor (LDR) Sensor` I like to know are they same thing or somewhat different. So the way they work is detecting

`light intensity and It is associated with both analog output pin and digital output pin labelled as AO and DO respectively on the board.When there is light, the resistance of LDR will become low according to the intensity of light. The greater the intensity of light, the lower the resistance of LDR.`

And before that I was reading about `Analog Piezoelectricity Ceramic Piezo Vibration Sensor For Arduino`

So LDR sensor needs some kind of resister. And Analog Piezoelectricity Ceramic Vibration sensor needs some IC.

Can Anyone be specific to these specific resister and IC for each sensor types. I have them both as module for arduino Uno. I like to code in gcc avr. Thats how I am restricted. And will use C code to control but Can any please be briefly explain this type of resister for LDR sensor and Piezoelectric vibration sensor IC. Just few words to help me relate to some explanation and easily get poped in my mind when ever I hear about these two modules again. So Just some brief on this specific types of resister and IC related to these two modules why they needed how to code, and control through code

These are pictures of two sensors as Chrisl asked

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

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

  [1]: https://i.stack.imgur.com/K25Nd.jpg
  [2]: https://i.stack.imgur.com/tXirc.jpg

https://www.daraz.pk/products/i140816069-s1300868385.html?urlFlag=true&mp=1

https://www.daraz.pk/products/i162290793-s1329534669.html?urlFlag=true&mp=1

title: Do I need to use resisters and ICes for specific sensors.What if I dont use it,Will it impact my arduino board some how like making it useless &faulty

Answers: 1

body:
Both images, that you included, show breakout boards. They are circuit boards (PCB - Printed Circuit Board), which contain all the components, that are needed to connect the corresponding part (in your case a piezo and an Light Dependent Resistor (LDR)). They are called this way, because they are "breaking out" simple output pins from the sensor circuitry for directly connecting them to the Arduino. So instead of having to build the circuit with the pure components you have a simple board, which gives you standard pin headers for connecting to the your Arduino. They are also often called "modules".

That means, that you don't need any additional circuitry or ICs to connect these boards to the Arduino. For the piezo sensor the image even shows the wiring diagram. You can see there, that you don't need any additional parts besides the breakout board, piezo and the Arduino itself. The same applies for the LDR breakout board.

**Connections:**

For the piezo sensor you have an analog output. Thus you need to connect that to an analog input on the Arduino (A0 to A7) and read the signal with `analogRead()`.

For the LDR breakout board I cannot be sure without a link to the product page, but it seems, that it has a digital output (DO). You can connect it to a digital input of the Arduino. It will switch between HIGH and LOW at a certain threshold brightness, which you can control by using a small screwdriver to rotate the little potentiometer on the board (the blue box with the hole in the middle).


body:
DISCLAIMER : I have just started Arduino, like 2 days ago, I've been following some tutorials on YouTube, and I tried to do this myself, but I can't figure out why it isn't working, can't find what I'm doing wrong.

THE SETUP (I've already tested it with some other code that proved me that the setup is working, each buttons and each pin of the RGB LED, I know for sure that this is the code not working)

[![SIDE PICTURE][1]][1]
[![ABOVE PICTURE][2]][2]

I am trying to light up the led to RED thanks to second button (from LEFT), Green with third, Blue, with fourth, and the first one to put the LED off . I am aswell trying to make a perfect visual transition between each colors going from 255 to 0 decimal..

Here is my code :

```
#define BLUE 10
#define GREEN 11
#define RED 5

int buttonBlueOn = 9;
int buttonGreenOn = 8;
int buttonRedOn = 3;
int buttonRgbLedOff = 2;

void setup() {
  // put your setup code here, to run once:
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(buttonRedOn, INPUT_PULLUP);
  pinMode(buttonGreenOn, INPUT_PULLUP);
  pinMode(buttonBlueOn, INPUT_PULLUP);
  pinMode(buttonRgbLedOff, INPUT_PULLUP);

}

int redValue;
int greenValue;
int blueValue;

void loop() {
  // put your main code here, to run repeatedly:

  // -------------------------------- RED ------------------------------ //

#define delayTime 20

  if (digitalRead(buttonRedOn) == LOW)
  {
    digitalWrite(RED, HIGH);
    redValue = 255;
  }

  if (digitalRead(buttonRedOn) == LOW and GREEN == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out green brings red full
    {
      redValue += 1;
      greenValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  if (digitalRead(buttonRedOn) == LOW and BLUE == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out blue brings red full
    {
      redValue += 1;
      blueValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(BLUE, blueValue);
      delay(delayTime);
    }
  }

  // -------------------------------- GREEN ------------------------------ //

  if (digitalRead(buttonGreenOn) == LOW)
  {
    digitalWrite(GREEN , HIGH);
    greenValue = 255;
  }

  if (digitalRead(buttonGreenOn) == LOW and RED == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out red brings green full
    {
      greenValue += 1;
      redValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  if (digitalRead(buttonGreenOn) == LOW and BLUE == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out blue brings green full
    {
      greenValue += 1;
      blueValue -= 1;
      analogWrite(BLUE, blueValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  // -------------------------------- BLUE ------------------------------ //

  if (digitalRead(buttonBlueOn) == LOW)
  {
    digitalWrite(BLUE, HIGH);
    blueValue = 255;
  }

  if (digitalRead(buttonBlueOn) == LOW and RED == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out red brings blue full
    {
      blueValue += 1;
      redValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(BLUE, blueValue);
      delay(delayTime);
    }
  }

  if (digitalRead(buttonBlueOn) == LOW and GREEN == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out green brings blue full
    {
      blueValue += 1;
      greenValue -= 1;
      analogWrite(BLUE, blueValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  // -------------------------------- OFF ------------------------------ //

  if (digitalRead (buttonRgbLedOff) == LOW)
  {
    digitalWrite(GREEN, LOW);
    digitalWrite(RED, LOW);
    digitalWrite(BLUE, LOW);
  }

}

 ```

WHAT IT DOES : Nothing at all, nothing lights up, nothing happens, I'm a bit confused

I am so new to this, sorry if I'm doing something wrong on this forum

  [1]: https://i.stack.imgur.com/sSSQ8.jpg
  [2]: https://i.stack.imgur.com/zfT1A.jpg

title: Can't figure out why what I'm trying to do isn't working. Trying to light up a RGB with buttons with AnalogWrite

Answers: 1

body:
Your program makes things too complex. You should rethink your whole strategy.

My preferred method is to have a "target" colour and a "current" colour. When you press a button you simply change what your target colour is. And then every iteration through `loop()` (either slowed down with a short `delay()` or triggered with `millis()`) you compare the target and current colours, and if they differ then move the current colour a step closer to the target colour.

That way you remove all the logic of "if this is pressed but not this then fade between these two colours", instead it's just "if this is pressed then I want to go to this colour" and the changing of the colour is completely independent.

I [wrote a blog post](https://majenko.co.uk/blog/our-blog-1/flexible-led-fading-14) on the topic some time ago that you might find helpful.


body: I am trying to change the I2C address of multiple Garmin LidarLite-V3. I am able to change them one at a time using the LidarLite C++ library using the setI2Caddr function, and can see the updated I2C address using i2cdetect. The problem is that when the LidarLite loses power and turns back on, the address is reset to the default 0x62. This means when I have multiple LidarLite connected in parallel, they all default to the same I2C address and I am unable to individually change the addresses using the setI2Caddr function. How can I change the I2C address so that it persists through a power cycle, or alternatively change the addresses when multiple LidarLite are connected in parallel?

title: Changing I2C Address on Garmin LidarLite, resets on reboot

Answers: 1

body:
The [manual][1] of the Garmin Lidar Lite tells you about this. From page 5 under "Configurable I2C Address":

> This can be used to run multiple devices on a single bus, by enabling one,
changing its address, then enabling the next device and repeating the
process.
>
>The I2C address will be restored to default after a power cycle

So you cannot change the fact, that the I2C addresses will be reset to the default value on power cycle. But on startup you can give each sensor its own address. For that you need to wire the Power Enable pins to digital pins on the Arduino. When the digital pin is HIGH, the sensor is deactivated. So you start with all the Power Enable pins on HIGH. Then you set the first Power Enable pin to LOW, set the sensors I2C address via the corresponding I2C command and then proceed to the next sensor. When finished every sensor has its corresponding address and you don't get any collisions on the bus, since you always have only one sensor with the default address enabled at any time.

  [1]: https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf


body:
I am building a project with Arduino Nano and the component in the subject, which, as far as I understand, can be assimilated to a DFPlayerMini (not sure if it's the same thing or it's just a cheap knockoff).

Following one of the millions of tutorials on the net I managed to make it work, I can correcly play audio files out of an SD card, but the weird thing is, that it only works while I'm connected to the Arduino with the serial monitor open on my IDE: the moment I close the IDE and power everything via `Vin` or via any other means - including USB power from the PC - it fails to do anything.

If this can be helpful, the wiring is as follows (taken from the instructables website where I found the first tutorial) [![Basic DFPlayer Wiring][1]][1]

And the code running everything is the following

`main.cpp`
```c++
#include <Arduino.h>
#include <modules/Sound.h>

#define BTN 3
#define TX 10
#define RX 11

Sound sound(TX, RX);

void setup() {
  Serial.begin(9600);
  Serial.println("Init");
  pinMode(BTN, INPUT);

  if (!sound.init()) {
    Serial.println("Nope");
  }

  sound.playInitSound();
}

void loop() {
  // unrelated stuff
}

```

`modules/Sound.h`
```c++
#include <Arduino.h>
#include <DFRobotDFPlayerMini.h>
#ifndef __SOUND__
#define __SOUND__

#define SOUND_POWER_UP   1
#define SOUND_POWER_DOWN 2

class Sound {
    public:
        Sound(uint8_t txPin, uint8_t rxPin);
        boolean init();
        void playInitSound();
    protected:
        DFRobotDFPlayerMini soundboard;
        uint8_t txPin;
        uint8_t rxPin;
};

#endif
```

`modules/Sound.cpp`
```c++
#include <Arduino.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include "modules/Sound.h"

Sound::Sound(uint8_t txPin, uint8_t rxPin) {
    this->txPin = txPin;
    this->rxPin = rxPin;
}

boolean Sound::init() {
    SoftwareSerial mySerial(txPin, rxPin);
    mySerial.begin(9600);
    boolean working = soundboard.begin(mySerial);
    if (working) {
        soundboard.volume(10);
    }
    return working;
}

void Sound::playInitSound() {
    soundboard.play(SOUND_POWER_UP);
}
```

As I said, everything works as long as I'm connected to the serial monitor from the IDE (if it's any relevant, I'm using PlatformIO on VSCode, on Linux).

I also tried to use the `if (!sound.init())` part to make the arduino LED cyclically blink if there is a failure, and indeed it starts blinking.

Any thought? Any way I can add more info to help troubleshooting?

**EDIT**:

I tried removing all instances of usage of the `Serial` but it doesn't help

I started thinking that maybe it was a faulty Arduino, so I switched to another controller and this one behaves a bit differently: the sound module gets initialized (I don't see the blinking led that would mean failure) but no sound is played.

The main difference between the two controllers is that the "faulty" one has the new bootloader, the one that is partially working has the old bootloader instead. Not sure if this is meaningful in the least.

**EDIT 2**:

The arduino with the old bootloader works just fine, beats me why

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

title: MP3-TF-16P only works while connected to serial monitor

Answers: 0


body:
I have been working on a project that I program using the ATMEGA 328p inserted into an Arduino Uno, and then remove it to put it on my breadboard. I now have realized how inadvisable this is, since I had a pin breakoff. I have spare ATMEGA 328 chips and a borrowed functional Arduino Uno. Starting with the instructions [here from the official Arduino site][1], and then progressing to the instruction set [here for using the different device signiture][2], I eventually gave up on using the IDE and ran avrdude from the command line. Here is my command:

    C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\bin>avrdude -v -v -c arduino -p m328p -P com9 -b19200 -F
And the following results:

```
avrdude: Version 5.10, compiled on Jan 19 2010 at 10:45:23
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch`

         System wide configuration file is "C:\WinAVR-20100110\bin\avrdude.conf"

         Using Port                    : com9
         Using Programmer              : arduino
         Overriding Baud Rate          : 19200
         AVR Part                      : ATMEGA328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

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

         Programmer Type : Arduino
         Description     : Arduino
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e9514
avrdude: Expected signature for ATMEGA328P is 1E 95 0F
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as 7

avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as 7
avrdude: safemode: Fuses OK

avrdude done.  Thank you.
``````

From these results, I want to conclude that the bootloader is now installed onto my ATMEGA 328. However, when I try to upload to it using the Arduino Uno "shell" with its 328p removed,I get the following error:
```
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x80

```
(and the next 10 tries)
Is there something I am missing? I am connecting the reset pin to pin 1 of my ATMEGA 328, and the RX/TX to pins 2 and 3, respectively.

Any help on this one would be greatly appreciated.

  [1]: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoToBreadboard
  [2]: http://www.crash-bang.com/resource/bootload-atmega328/

title: ATmega 328 Bootloaded, but Cannot Upload

Answers: 0


body:
I'm trying to run a Fuzzy Logic MPPT Algorithm in Arduino UNO, [here's the Simulink File][1]

However when I try to upload the code, I get the following error

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

Is this project possible with UNO, if yes, what shall I do? Else which Arduino board would be suitable for this project?

  [1]: https://drive.google.com/drive/folders/1b2aHGw1rrPcKOgMciU1zWIJqr5E1oU8Y?usp=sharing
  [2]: https://i.stack.imgur.com/WDVDp.png

title: Which Arduino board would be sufficient for the following simulink project?

Answers: 1

body:
We cannot answer about your Simulink program (since this site is only about Arduino). But currently you are using 3 times the RAM an Uno has. You can try to optimize your Simulink program, though I doubt that you will be able to reduce the needed memory that much.

So you should switch to a board with significantly more RAM. There are many to choose from, with different RAM, flash, peripherals, pin numbers. Write down all your requirements and then look for a fitting board


body:
I'm implementing an example in which 2 ESP32's communicate each other using the HTTP Protocol. One acts as Server the other as Client. In the examples provided, I am curious about the declaration on the server, as its implementation is declared in the setup() function (I am using the standard Arduino IDE), which is supposed to have code that executes only once, rather than the loop() function (at least in this example), which is supposed to refresh the call every cycle, yet it remains empty:

```/* Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-client-server-wi-fi/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Import required libraries
#include "WiFi.h"
#include "ESPAsyncWebServer.h"

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

// Set your access point network credentials
const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";

/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

String readTemp() {
  return String(bme.readTemperature());
  //return String(1.8 * bme.readTemperature() + 32);
}

String readHumi() {
  return String(bme.readHumidity());
}

String readPres() {
  return String(bme.readPressure() / 100.0F);
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
  Serial.println();

  // Setting the ESP as an access point
  Serial.print("Setting AP (Access Point)…");
  // Remove the password parameter, if you want the AP (Access Point) to be open
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readHumi().c_str());
  });
  server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readPres().c_str());
  });

  bool status;

  // default settings
  // (you can also pass in a Wire library object like &Wire2)
  status = bme.begin(0x76);
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // Start server
  server.begin();
}

void loop(){

}
```
You can see the "server.on(....)" declarations in the setup() side of the code, and the empty loop() function in the end.
```
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
```
So, my assumption is that the server is already running in the background when executing server.begin() and does not need to be explicitly called, but it still confuses me because there is no explicit declaration on the loop() such as server.loop() or something similar.
Can you explain how this works and why it is not necessary to explicitly declare the function on the loop()?

Thanks
-EZ

title: Why is the server.on() function from "ESPAsyncWebServer.h" executed in the setup() side and not on the loop() side?

Answers: 3

body:
`Server.on()` sets a *callback function*. That registers a function to be executed when a certain event happens at a later date. In this case it's when a certain URL is requested with a `GET` method.

Any time a request is made to the web server a list of "on" registered events is examined for one that matches the request, then the associated function (in this case a *lambda function*) is executed.

And all that is done *asynchronously* (hence the name) in the background in another thread so you don't need to explicitly do anything.

body:
The construct with a lambda function
```
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
```
is same as

```
server.on("/temperature", HTTP_GET, onGetTemperature);
```
where `onGetTemperature` is a function defined before `void setup()`
```
void onGetTemperature(AsyncWebServerRequest *request) {
  request->send_P(200, "text/plain", readTemp().c_str());
}
```
Would you in this case ask why it is "executed in the setup()?"

body:
Yes, `server.on()` is a callback function, but that's not the entirety of the story.

You don't see anything related to the server in `loop()` either, because somewhere in the backend of all that code, probably in `server.begin()`, the server attaches a callback or ISR of its own to the networking stack of the ESP. Now, when the ESP gets a message across the network of the right type, the networking stack redirects the message into the server's internal callback, at which point the server checks the page that was viewed and executes the appropriate `server.on`-specified function that you put in `setup()`.

I haven't yet had the chance to look into exactly how the server's callback is attached to the networking stack, but that's how it operates asynchronously. Either it's originally activated by a Wi-Fi hardware ISR (allowing it to temporarily pause your code's execution to run the server) or it's run by a small scheduler-like section of code that is executed outside of `loop()` (meaning that between iterations of `loop()`, it might be handling the server. It's probably this case since this is when some parts of the networking stack are handled anyway).

One minor note: this operation has a potential side effect of causing memory use or CPU use by the server when you might have *intended* to allocate either to your own application code, so if you start seeing odd timing errors or memory corruption on a *really* large application, you may want to look into this as a potential cause.


body:
[![This is the code][1]][1]

- I want pin 11 to give a square wave of once 3 sec

- and want pin 12 to act as a switch to glow pin 13 Built in led..

 - connected pin 12 to GND with 10k resistor

If i fed the switch code alone it is fast(the led turn on instantly), but when i fed this code (the on in picture) it has a 1 sec lag to turn on the led. why?

And also if i connect pin 11 to 12 i assume the builtin led should turn on and off according to the wave form coming out of  but the led is always low.

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

title: Arduino Code is slow when running two task

Answers: 1

body:
Basically, the code comprises Two Parts

 1. Square Wave with 3-sec delay on and 3-sec delay off
 2. if the pin 12, is high pin 13 will be high and if 12 is low 13 is also low(a simple on/off switch)

---------

The second block of code executes only after the first Block of code is done executing.

That's why when I connected the pin 11 to 12 the led wasn't shining because when the WAVE code(that first block of code which gives a square wave) was running, the second block of code was quiet hence the 12th pin was still not become a switch yet.

And the delay I told was due to this, actually, the delay is 6 sec.
Because after the switch code completes its run, it will take a whole six seconds for the Arduino to come back to switch code in the loop because the wave signal of 3 sec on and 3 sec off should run.

if you want to run two tasks at the same time you need to learn the topics of millis() and protothreading.

----------

You can ask me why I was this dumb to ask a question like this, because the only programming language I have ever snorted is python and in there I learned python is an interpreter and it executes line by line, Since Arduino ide code is built around c++ which is the compiler.

I thought the code won't run line by line instead the code will be compiled but now only I understood that even though the file is compiled there is no chance every code can be run at the same time as the actual meaning of the compiler.


body: For example constant of ```MSBFIRST```, It used to as input in ```SPI.setBitOrder(MSBFIRST)```. But sadly i don't know the type data of ```MSBFIRST```. This is applied to like ```SPI_MODE0``` and other.

title: How to know the data type of constant in arduino IDE?

Answers: 1

body:
From SPI.h:

    #ifndef LSBFIRST
    #define LSBFIRST 0
    #endif
    #ifndef MSBFIRST
    #define MSBFIRST 1
    #endif

As you can see, there is no type. The compiler merely substitutes literally "1" for "MSBFIRST". So your code would read, after pre-processing:

     SPI.setBitOrder(1)

To know exactly what type "1" is (I'm not sure why you need to know) then you would look up "C++ integer promotion". In other words, how are literal integers handled by the C++ compiler.

---

From a comment:

> In which case it's better to look at the desired type of the destination function not the type of the macro or const.

Quite right. If you look further into the SPI.h file you see this:

      // This function is deprecated.  New applications should use
      // beginTransaction() to configure SPI settings.
      inline static void setBitOrder(uint8_t bitOrder) {

So, ignoring what type MSBFIRST is, you can see that the function expects uint8_t.


body:
So Let say I want to access Digital Pin 13. Thats port B pin. Is there an memory address associated with this pin 13 of Arduino Uno r3?

How Port B pins are addressed with corresponding pin numbers like What is the address of digital pin 13?

Currently I am assuming its pin address is `0x05` so my pointer looks like this

     uint8_t *adr=0x00+0x05;

Now If I do

      *adr |= 0x20;

then should I expect that I am writing to some pin so I like to know which data sheet I should refer for pin addresses of port B?

Currently my code is not working because no matter which pin I connect my LED to it blinks. What if I dont want to use any library and just write to address and I need PORT B pin address how to refer to different pins?

Now assume I have a code that uses avr gcc

    #include <avr/iom328p.h>//avr/io.h
    #include    <util/delay.h>
    #include <avr/sfr_defs.h>

    #define     BLINK_DELAY_MS  18000

    int main (void)
    {
        DDRB |= _BV(DDB5);

        while(1)
        {
            PORTB |= _BV(PORTB5);
            _delay_ms(BLINK_DELAY_MS);

            PORTB &= ~_BV(PORTB5);
            _delay_ms(BLINK_DELAY_MS);
        }

        return 0;
    }

What is the values correspond to `DDRB` and `_BV(DDB5);` and `PORTB` and `_BV(PORTB5);`? I like to do it with pointers so I need addresses of PORT B all pins I know the macros but I like the actual addresses . there should be a some datasheet for this what  its called. Does arduino has it that gives memory mapped addresses?

The above code is simply for blinking LED light

title: How arduino PORTB pins are addressed if I want to access them with pointer?

Answers: 1

body:
The address of `PORTB` can be found in the [ATmega328P datasheet][328p],
section “I/O-Ports”, subsection “Register Description”. It is repeated
near the end of the section “Register Summary”, where it is documented
as:

    0x05 (0x25)

Admittedly, this is confusing: there are two addresses! There is a
footnote that gives some hint on the reason:

> When using the I/O specific commands IN and OUT, the I/O addresses
> 0x00 - 0x3F must be used. When addressing I/O Registers as data space
> using LD and ST instructions, 0x20 must be added to these addresses.

To clarify, this register is mapped in two different address spaces:

- It has I/O address `0x05`. The I/O address space is a small (6 bits)
  address space dedicated to I/O registers. It is actually too small to
  host all the I/O registers. It can be accessed with the `in` and `out`
  instructions. Addresses lower than 32 can also be bit-addressed with
  the instructions `sbi`, `cbi`, `sbis` and `sbic`.

- It has data address `0x25`. This is a much larger address space that
  gives access to all the I/O registers and to the RAM. It is used with
  the `ld`/`st` family of instructions.

Since the C and C++ languages are not aware of the I/O address space, a
regular data pointer is assumed to always point to the data address
space. Thus, if you want to create a pointer to this register, you may
write:

```c++
volatile uint8_t *adr = 0x25;  // PORTB
```

Note the `volatile` qualifier. This is required to prevent the compiler
being too “smart” and optimizing out some of your writes under the
assumption that this is just RAM.

Then you may turn the LED on with:

```c++
*adr |= 1 << 5;  // set PORTB5
```

Withe the proper optimization options, the compiler may be able to
optimize this into `sbi 0x05, 0x05`, if it can prove that the address
stored in the pointer doesn't change.

> I need addresses of PORT B all pins I know the macros but I like the
> actual addresses.

I would recommend this:

```c++
volatile uint8_t *adr = &PORTB;
```

This avoids having [magic numbers][] in your code, and makes the
programmer's intent clear.

One last comment. When compiling your code I got:

```text
include/avr/iom328p.h: [...]
error "Include <avr/io.h> instead of this file."
```

Just include `<avr/io.h>`: this header takes care of including both the
correct `<avr/iomXXX.h>` and `<avr/sfr_defs.h>`.

[328p]: https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf
[magic numbers]: https://en.wikipedia.org/wiki/Magic_number_(programming)


body:
I want to work with two analog sensors connected to [ATmega16][1]. The first one is the temperature sensor (LM35), connected to PA0. The LED should be ON when the temperature goes high. The second one is the photo-resistor and it's connected to PA1. I want to turn the LED ON when the lighting is low.
I was looking for a solution all over the internet, but couldn't find something similar to my situation. They all just say one thing- you can't read two analog sensors at the same time.

I have this code that works just for one sensor:

```c++
#define F_CPU 1600000UL
#include <avr/io.h>

void ADC_Init() {
    DDRA = 0x0;
    ADCSRA = 0x87;
    ADMUX = 0x40;
}

uint16_t ADC_Read(uint8_t channel) {
    ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);
    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC)) ;
    return ADC;
}

int main(void) {
    ADC_Init();
    DDRB = 0xFF;
    while (1) {
        uint8_t value;
        value = ADC_Read(0);
        if (value > 70) {
            PORTB |= (1<<0);
        } else {
            PORTB &= ~(1<<0);
        }
    }
}
```

Can you somehow help me to modify this code, give me advice on how can I do it, or some example?

  [1]: http://ww1.microchip.com/downloads/en/devicedoc/doc2466.pdf

title: Working with two analog sensors, ATmega16

Answers: 1

body:
I just skimmed over the ATmega16 datasheet, so perhaps take this answer with a grain of salt.

It is technically true that you cannot read two ADC channels at the same time because there is only one ADC and you must multiplex the various channel inputs to that one ADC. You can, most likely, change the ADC source at runtime to switch between the different channels.

Take a look at the ADMUX register description in the [datasheet][1]

Right now, you set the mux once during the init() function and then never change it. In your new code, you will have to change the value in the register at runtime (in addition to any other configuration/housekeeping that is required) which should happen in your main loop()

High level description:

    int main()
    {
        system_init();

        while (1)
        {
            set ADMUX to read from PA0
            read ADC

            set ADMUX to read from PA1
            read ADC

            do stuff
        }

    }

  [1]: http://ww1.microchip.com/downloads/en/devicedoc/doc2466.pdf


body:
I'm having troubles understanding this line of code that I see with every Arduino EEPROM tutorial.
```
int saveLocation = 4095;
Wire.write((int)(saveLocation >> 8));
```
*Question 1:* Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

According to the wire library documentation, you can use `wire` to send the following:

```
Wire.write(value) // value to send as a single byte
Wire.write(String) // a string to send as a series of bytes
Wire.write(data, length) // an array of data to send as bytes, the number of bytes to transmit.
```

So my variable, `int saveLocation = 4095` is not a string or array, so it must be a considered as a 'value', which means it's being sent as 1 byte.

*Question 2:* If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

*Question 3:* If `saveLocation` is already an integer, why would cast it to `int`?

*Question 4:* Since `int` is two bytes, does `wire.write` only send out the lower byte?

Thanks in advance for the help.

title: Arduino Wire library and Type Cast help

Answers: 2

body:
> Question 1: Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

Yes. What's in the brackets is evaluated then the result cast to int.

> Question 2: If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

You wouldn't.

> Question 3: If saveLocation is already an integer, why would cast it to int?

You wouldn't

> Question 4: Since int is two bytes, does wire.write only send out the lower byte?

Yes, just the lowest 8 bits.

The cast to an integer is completely redundant here. It's not performing anything other than making the code harder to understand. You can remove it and it won't make any difference.

In fact the presence of the int cast triggers an overloaded function:

    inline size_t write(int n) { return write((uint8_t)n); }

So it just re-casts it to an unsigned 8-bit integer (byte) anyway.

body:
You are right about being confused. This casting doesn't make any sense.

> Question 1: Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

Yes, the bitshift happens before the casting because of the parentheses.

> Question 2: If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

You wouldn't. It is cast to `uint8_t` (aka `byte`) anyway by the parameter type.

> Question 3: If saveLocation is already an integer, why would cast it to int?

Doesn't make sense to me either. You don't need to. Though it also doesn't hurt here (same goes for question 2)

> Question 4: Since int is two bytes, does wire.write only send out the lower byte?

Yes, only the lower byte. The function parameter is of type `uint8_t`, which is exactly one byte. Thats the reason for the bit shifting. By shifting the value right by 8 you effectively shift the high byte to the low byte position.


body:
I need a buffer of the size `153600 bytes` in my ESP32 project, but I could not create a static buffer in code nor can I `malloc` the buffer.

The ESP32 itself reports:
```
  ESP.getHeapSize()  // = 402540
  ESP.getFreeHeap()  // = 376980
  ESP.getPsramSize() // = 0
  ESP.getFreePsram() // = 0
```

`malloc(153600)` returns `NULL`; I wrote a little loop which decrements by one and retries to malloc. The first time it works is `malloc(126888)` so this seems to be the maximum buffer I can get.

*(I tried it with different boards; one from eBay and one from a genuine distributor - no differences.)*

Clearly the heap size is big enough. So I'm thinking that the RAM is possibly split into different chunks and no one is big enough for my buffer?

Is there any documentation which explains this behavior?

title: ESP32: why does malloc can only alloc 126888 bytes with 402540 bytes heap?

Answers: 1

body:
Yes, the ESP32 memory is arranged in a number of different chunks. Those chunks are all aggregated by the memory manager to appear as a single heap, but they're actually separate.

As the [ESP-IDF documentation mentions](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/mem_alloc.html):

> At startup, all ESP-IDF apps log a summary of all heap addresses (and sizes) at level Info:
>
>     I (252) heap_init: Initializing. RAM available for dynamic allocation:
>     I (259) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
>     I (265) heap_init: At 3FFB2EC8 len 0002D138 (180 KiB): DRAM
>     I (272) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
>     I (278) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
>     I (284) heap_init: At 4008944C len 00016BB4 (90 KiB): IRAM

And of course you have some heap fragmentation from other threads allocating and deallocating memory, so the biggest contiguous block of memory you can allocate will be smaller than the biggest region.

To further illustrate I found this handy memory map on the Arduino forums:

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

There you can clearly see the SRAM is split into different chunks. The main reason for this is to better allow concurrent access by the two cores in the dual-core variants of the chip.

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


body: I am using ESP32 and SIM800L for my project. The SIM800L does support SSL, TLS 1.0, and TLS 1.1. But web servers nowadays usually support only TLS 1.2 and 1.3. I heard, that the ESP32 HTTPS client can use lwIP stack from other libraries. Is there some way to implement the lwIP? Is there some other way to get TLS 1.2 and 1.3 working?

title: ESP32 - SIM800 - HTTPS lwIP

Answers: 0


body:
I'm trying to get my code to read multiple thermistors and I can't quite seem to get it correct using my arduino 2560. The first issue is it's not reading more than the first thermistor. The next issue is the for loop that displays the current temperature always reads "TURN OFF" when its below the 60C range.

Here is my code:

```lang-cpp
/* Here we have a few constants that make editing the code easier. I will go
  through them one by one.

  A reading from the ADC might give one value at one sample and then a little
  different the next time around. To eliminate noisy readings, we can sample
  the ADC pin a few times and then average the samples to get something more
  solid. This constant is utilized in the readThermistor function.
  */
const int    SAMPLE_NUMBER      = 10;

/* In order to use the Beta equation, we must know our other resistor
  within our resistor divider. If you are using something with large tolerance,
  like at 5% or even 1%, measure it and place your result here in ohms. */
const double BALANCE_RESISTOR0   = 10060.0; //
const double BALANCE_RESISTOR1   = 10000.0;
const double BALANCE_RESISTOR2   = 10000.0;
const double BALANCE_RESISTOR3   = 10000.0;
const double BALANCE_RESISTOR4   = 10000.0;
const double BALANCE_RESISTOR5   = 10000.0;
const double BALANCE_RESISTOR6   = 10000.0;
const double BALANCE_RESISTOR7   = 10000.0;
const double BALANCE_RESISTOR8   = 10000.0;
const double BALANCE_RESISTOR9   = 10000.0;

// This helps calculate the thermistor's resistance (check article for details).
const double MAX_ADC            = 1023.0;

/* This is thermistor dependent and it should be in the datasheet, or refer to the
  article for how to calculate it using the Beta equation.
  I had to do this, but I would try to get a thermistor with a known
  beta if you want to avoid empirical calculations. */
const double BETA               = 3977.0;

/* This is also needed for the conversion equation as "typical" room temperature
  is needed as an input. */
const double ROOM_TEMP          = 295.950;   // room temperature in Kelvin

/* Thermistors will have a typical resistance at room temperature so write this
  down here. Again, needed for conversion equations. */
const double RESISTOR_ROOM_TEMP = 10980.0;

//===============================================================================
//  Variables
//===============================================================================
// Here is where we will save the current temperature
double currentTemperature = 0;

//===============================================================================
//  Pin Declarations
//===============================================================================
//Inputs:
int thermistorPin0 = 0;  // Where the ADC samples the resistor divider's output
int thermistorPin1 = 1;
int thermistorPin2 = 2;
int thermistorPin3 = 3;
int thermistorPin4 = 4;
int thermistorPin5 = 5;
int thermistorPin6 = 6;
int thermistorPin7 = 7;
int thermistorPin8 = 8;

//Outputs:

//===============================================================================
//  Initialization
//===============================================================================

void setup()
{
 // Set the port speed for serial window messages
 Serial.begin(9600);
}

//===============================================================================
//  Main
//===============================================================================

//===============================================================================
//  Functions
//===============================================================================
/////////////////////////////
////// readThermistor ///////
/////////////////////////////

double readThermistor()
{
 // variables that live in this function
 double rThermistor0 = 0; // Holds thermistor resistance value
 double rThermistor1 = 0;
 double rThermistor2 = 0;
 double rThermistor3 = 0;
 double rThermistor4 = 0;
 double rThermistor5 = 0;
 double rThermistor6 = 0;
 double rThermistor7 = 0;
 double rThermistor8 = 0;

 double tKelvin0     = 0;            // Holds calculated temperature
 double tKelvin1     = 0;
 double tKelvin2     = 0;
 double tKelvin3     = 0;
 double tKelvin4     = 0;
 double tKelvin5     = 0;
 double tKelvin6     = 0;
 double tKelvin7     = 0;
 double tKelvin8     = 0;

 double tCelsius0    = 0;            // Hold temperature in celsius
 double tCelsius1    = 0;
 double tCelsius2    = 0;
 double tCelsius3    = 0;
 double tCelsius4    = 0;
 double tCelsius5    = 0;
 double tCelsius6    = 0;
 double tCelsius7    = 0;
 double tCelsius8    = 0;

 double adcAverage0  = 0;            // Holds the average voltage measurement
 double adcAverage1  = 0;
 double adcAverage2  = 0;
 double adcAverage3  = 0;
 double adcAverage4  = 0;
 double adcAverage5  = 0;
 double adcAverage6  = 0;
 double adcAverage7  = 0;
 double adcAverage8  = 0;

 int    adcSamples0[SAMPLE_NUMBER];  // Array to hold each voltage measurement
 int    adcSamples1[SAMPLE_NUMBER];
 int    adcSamples2[SAMPLE_NUMBER];
 int    adcSamples3[SAMPLE_NUMBER];
 int    adcSamples4[SAMPLE_NUMBER];
 int    adcSamples5[SAMPLE_NUMBER];
 int    adcSamples6[SAMPLE_NUMBER];
 int    adcSamples7[SAMPLE_NUMBER];
 int    adcSamples8[SAMPLE_NUMBER];

 /* Calculate thermistor's average resistance:
    As mentioned in the top of the code, we will sample the ADC pin a few times
    to get a bunch of samples. A slight delay is added to properly have the
    analogRead function sample properly */

 for (int i = 0; i < SAMPLE_NUMBER; i++)
 {
   adcSamples0[i] = analogRead(thermistorPin0);  // read from pin and store
   adcSamples1[i] = analogRead(thermistorPin1);
   adcSamples2[i] = analogRead(thermistorPin2);
   adcSamples3[i] = analogRead(thermistorPin3);
   adcSamples4[i] = analogRead(thermistorPin4);
   adcSamples5[i] = analogRead(thermistorPin5);
   adcSamples6[i] = analogRead(thermistorPin6);
   adcSamples7[i] = analogRead(thermistorPin7);
   adcSamples8[i] = analogRead(thermistorPin8);

   delay(10);        // wait 10 milliseconds
 }

 /* Then, we will simply average all of those samples up for a "stiffer"
    measurement. */
 for (int i = 0; i < SAMPLE_NUMBER; i++)
 {
   adcAverage0 += adcSamples0[i];      // add all samples up . . .
   adcAverage1 += adcSamples1[i];
   adcAverage2 += adcSamples2[i];
   adcAverage3 += adcSamples3[i];
   adcAverage4 += adcSamples4[i];
   adcAverage5 += adcSamples5[i];
   adcAverage6 += adcSamples6[i];
   adcAverage7 += adcSamples7[i];
   adcAverage8 += adcSamples8[i];

 }
 adcAverage0 /= SAMPLE_NUMBER;        // . . . average it w/ divide
 adcAverage1 /= SAMPLE_NUMBER;
 adcAverage2 /= SAMPLE_NUMBER;
 adcAverage3 /= SAMPLE_NUMBER;
 adcAverage4 /= SAMPLE_NUMBER;
 adcAverage5 /= SAMPLE_NUMBER;
 adcAverage6 /= SAMPLE_NUMBER;
 adcAverage7 /= SAMPLE_NUMBER;
 adcAverage8 /= SAMPLE_NUMBER;

 /* Here we calculate the thermistor’s resistance using the equation
    discussed in the article. */
 rThermistor0 = BALANCE_RESISTOR0 * ( (MAX_ADC / adcAverage0) - 1);
 rThermistor1 = BALANCE_RESISTOR1 * ( (MAX_ADC / adcAverage1) - 1);
 rThermistor2 = BALANCE_RESISTOR2 * ( (MAX_ADC / adcAverage2) - 1);
 rThermistor3 = BALANCE_RESISTOR3 * ( (MAX_ADC / adcAverage3) - 1);
 rThermistor4 = BALANCE_RESISTOR4 * ( (MAX_ADC / adcAverage4) - 1);
 rThermistor5 = BALANCE_RESISTOR5 * ( (MAX_ADC / adcAverage5) - 1);
 rThermistor6 = BALANCE_RESISTOR6 * ( (MAX_ADC / adcAverage6) - 1);
 rThermistor7 = BALANCE_RESISTOR7 * ( (MAX_ADC / adcAverage7) - 1);
 rThermistor8 = BALANCE_RESISTOR8 * ( (MAX_ADC / adcAverage8) - 1);

 /* Here is where the Beta equation is used, but it is different
    from what the article describes. Don't worry! It has been rearranged
    algebraically to give a "better" looking formula. I encourage you
    to try to manipulate the equation from the article yourself to get
    better at algebra. And if not, just use what is shown here and take it
    for granted or input the formula directly from the article, exactly
    as it is shown. Either way will work! */
 tKelvin0 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor0 / RESISTOR_ROOM_TEMP)));

 tKelvin1 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor1 / RESISTOR_ROOM_TEMP)));

 tKelvin2 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor2 / RESISTOR_ROOM_TEMP)));

 tKelvin3 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor3 / RESISTOR_ROOM_TEMP)));

 tKelvin4 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor4 / RESISTOR_ROOM_TEMP)));

 tKelvin5 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor5 / RESISTOR_ROOM_TEMP)));

 tKelvin6 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor6 / RESISTOR_ROOM_TEMP)));

 tKelvin7 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor7 / RESISTOR_ROOM_TEMP)));

 tKelvin8 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor8 / RESISTOR_ROOM_TEMP)));

 /* I will use the units of Celsius to indicate temperature. I did this
    just so I can see the typical room temperature, which is 25 degrees
    Celsius, when I first try the program out. I prefer Fahrenheit, but
    I leave it up to you to either change this function, or create
    another function which converts between the two units. */
 tCelsius0 = tKelvin0 - 273.15;  // convert kelvin to celsius
 tCelsius1 = tKelvin1 - 273.15;
 tCelsius2 = tKelvin2 - 273.15;
 tCelsius3 = tKelvin3 - 273.15;
 tCelsius4 = tKelvin4 - 273.15;
 tCelsius5 = tKelvin5 - 273.15;
 tCelsius6 = tKelvin6 - 273.15;
 tCelsius7 = tKelvin7 - 273.15;
 tCelsius8 = tKelvin8 - 273.15;

 return tCelsius0; // Return the temperature in
 return tCelsius1;
 return tCelsius2;
 return tCelsius3;
 return tCelsius4;
 return tCelsius5;
 return tCelsius6;
 return tCelsius7;
 return tCelsius8;

}

void loop()
{
 /* The main loop is pretty simple, it prints what the temperature is in the
    serial window. The heart of the program is within the readThermistor
    function. */
 currentTemperature = readThermistor();
 delay(3000);

 /* Here is how you can act upon a temperature that is too hot,
 too cold or just right. */
 if (currentTemperature > 0.0 && currentTemperature < 60.0)
 {
   Serial.print("It is ");
   Serial.print(currentTemperature);

 }
 else (currentTemperature >= 60.0);

 {
   Serial.print("It is ");
   Serial.print(currentTemperature);
   Serial.println("C. SHUT OFF!");
 }
}
```
I'm no expert in coding, so if you have any suggestions that could help, I would very much appreciate it.

title: Having trouble reading multiple thermistors w/ Arduino 2560

Answers: 1

body:
Welcome to Stack Exchange!

The problem causing the first issue is your multiple `return` statements in the `readThermistor` function. `return` exits the function, so when the code runs `return tCelsius0` it will exit the function and not run any of the later return statements.

Try storing your temperatures in an array and then returning that array. However, you also only read one of the values in the `main()` function anyway.

The problem causing the second issue is you have an `if` and an `else`. To properly check for your second condition `currentTemperature >= 60.0`, you need to have an `else if` instead.


body: I am looking for a very low frequency application like below 300Hz. What is the minimum sampling rate in Arduino due? I am very new to this. I see in the datasheet that max sampling rate is 20MHz.

title: What is the minimum sampling rate in ADC in Arduino due?

Answers: 1

body:
There is no "minimum" sampling rate.

You can better understand why that would be if you first understand how *Successive Approximation* ADCs operate.

An SAR ADC is simply a small capacitor, a DAC, and a comparator - along with a number of digital switches. When you perform a sampling the capacitor is first connected to the IO pin for an amount of time. The capacitor then charges up to the level of the incoming signal. Then the capacitor is disconnected from the IO pin and instead connected to the comparator. The DAC is then used to generate a sequence of voltages which the comparator then compares against the voltage in the capacitor - one voltage for each bit of resolution.

The maximum sampling rate is defined by how long the capacitor takes to be charged up by the incoming voltage. A bigger capacitor will take longer to charge up and thus give you a lower maximum sampling speed. A smaller capacitor charges faster, giving you higher sampling speeds.

However there is a big caveat: a smaller capacitor holds its charge for a shorter length of time, so getting an accurate reading from it when you have to hold the voltage for a number of cycles while you do successive comparisons can be hard. For this reason it's common to reduce the sampling resolution for higher sampling speeds: switch in a smaller capacitor, but take less time to sample it with less bits of data.

So from that it stands to reason that there is a minimum amount of time that you want the capacitor connected to the IO pin, and a predefined amount of time required to perform the comparisons, but there is no lower limit on how long the capacitor can be connected to the IO pin - it will just track the voltage changes for a while until the moment it's switched to conversion mode and the current voltage is captured (successive approximation ADCs are also known as sample-and-hold for this reason). And of course there is no requirement to immediately start a new sampling of the IO pin immediately you have finished a conversion. You can wait any amount of time before triggering a new ADC conversion. Seconds, weeks, decades...

This of course is all for *manual* triggering of the ADC. If you want automatic triggering from one of the internal timers then the minimum sampling speed will be whatever you can configure the timer to. And we can't tell you that, since timers can be configured to run from different clock sources, including your own external clock signal running at whatever speed you like.

So for automatic conversions you should not be looking at the ADC, other than to find what clock sources and interrupts can be used to trigger a conversion, and instead look at the relevant timer sections in the datasheet to work out what frequency you can configure those for to suit your needs.


body:
I am working on a project on my Arduino Uno in which I want to change the text on the LCD every time the potentiometer has been rotated. In order to do this, I have stored the angle values into an `int`, constantly check if the angle has been rotated enough to change the text, and if it has, print the next message. I am not sure if either my code or circuit is wrong as nothing happens at all when i rotate the potentiometer.

Here is my code so far and an image of the circuit (the innermost potentiometer is for the brightness, the one on the right is for changing the text on the LCD. I think I may have wired the second potentiometer incorrectly but I am not sure how to fix this).

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

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

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // removed 3
// set up a constant for the button
const int buttonPin = 6;
// variable to hold the value of the button
int buttonState = 0;
// variable to hold previous value of the button
//int prevbuttonState = 0;
// a variable to choose which reply will be displayed
int reply = -1;
int prevReply = -1;
int potPin = A0;
int potVal = 0;
int angle = 0;
int prevAngle = 0;
//int startTime = 0;
//int timeElasped = 0;
//int workoutTime = 0;

void setup() {
  // set up the number of columns and rows on the LCD
  lcd.begin(16, 2);

  // set up the switch pin as an input
  pinMode(buttonPin, INPUT);

  Serial.begin(9600);
  prevAngle = map(potVal,0,1023,0,300); // set prevAngle to original angle. later, code that if the angle isnt 0 tell user to reset it
  // Print a message to the LCD.
  lcd.print("Pick a");
  // set the cursor to column 0, line 1
  // line 1 is the second row, since counting begins with 0
  lcd.setCursor(0, 1);
  // print to the second line
  lcd.print("Muscle Group!");
}

void loop() {
  // check the status of the switch
  buttonState = digitalRead(buttonPin);
  potVal = analogRead(potPin);
  Serial.print("potVal: ");
  Serial.print(potVal);
  angle=map(potVal,0,1023,0,300);//used to be 179, changed to 300 assuming it equals the max angle available in the potentiometer
  Serial.print(", angle: ");
  Serial.println(angle);
  if (angle > prevAngle+69){ // if the pot has been rotated enough clockwise, display next group
    if (reply!=3)
      reply = reply+1;//provide next muscle group
    else
      reply = 0;//return to first muscle group
    /*if (prevReply==-1)
      prevReply=reply;*/
  }
  else if (angle < prevAngle-69){ // if the pot has been rotated enough counterclockwise, display prev group
    if (reply!=0 && reply!=-1)
      reply = reply-1;//provide previous muscle group
    else if (reply==0)// check if reply is still equal to -1 btw
      reply = 3;//return to last muscle group
    else if (reply==-1){
      reply = 0;
      //prevReply=reply;
    }
  }
  //prevReply = reply;
  if (buttonState == HIGH) { //if the button has been pressed, display new random exercise within muscle group that was chosen
      if (reply == 0)
        reply = random(4,6);
      if (reply == 1)
        reply = random(7,9);
      if (reply == 2)
        reply = random(10,12);
      if (reply == 3)
        reply = random(13,15);
      // clean up the screen before printing a new reply
      lcd.clear();
      // set the cursor to column 0, line 0
      lcd.setCursor(0, 0);
      // print some text
      lcd.print("Time to do some");
      // move the cursor to the second line
      lcd.setCursor(0, 1);
      delay(500);
      lcd.clear();
      lcd.setCursor(0, 0);
      /*if (workoutTime - millis() + startTime==0){
           lcd.clear();
           lcd.setCursor(0, 0);
           lcd.print("You did it!! :]"); //if reply keeps looping, stop loop once timer=0. if reply never loops, figure out how to make it loop for the timer*/
      }
      //if (prevReply != reply) // if we have chosen a new workout, change the starting time
        //startTime = millis(); // record millis() function to see how much time passes btwn start of program to start of timer
      if (prevReply != reply){
      switch (reply) { // choose a saying to print based on the value in reply
        case 0:
          lcd.print("Arms");
          break;

        case 1:
          lcd.print("Core");
          break;

        case 2:
          lcd.print("Chest");
          break;

        case 3:
          lcd.print("Legs");
          break;

        case 4:
          //workoutTime = 2400;
          lcd.print("Arm wrkt 1; " /*+ workoutTime - millis() + startTime*/); // temporary workout names, to be replaced in a later draft
          break;

        case 5:
          //workoutTime = 1200;
          lcd.print("Arm wrkt 2; " /*+ workoutTime - millis() + startTime*/);
          break;

        case 6:
          //workoutTime = 1500;
          lcd.print("Arm wrkt 3; " /*+ workoutTime - millis() + startTime*/);
          break;

        case 7:
          //workoutTime = 1800;
          lcd.print("Core wrkt 1; " /*+ workoutTime - millis() + startTime*/);
          break;

        case 8:
          //workoutTime = 900;
          lcd.print("Core wrkt 2; " /*+ workoutTime - millis() + startTime*/);
          break;

        case 9:
          //workoutTime = 2400;
          lcd.print("Core wrkt 3; " /*+ workoutTime - millis() + startTime*/);
          break;

        case 10:
          //workoutTime = 2100;
          lcd.print("Chest wrkt1; " /* + workoutTime - millis() + startTime*/);
          break;

        case 11:
          //workoutTime = 1200;
          lcd.print("Chest wrkt2; " /* + workoutTime - millis() + startTime*/);
          break;

        case 12:
          //workoutTime = 1200;
          lcd.print("Chest wrkt3; " /* + workoutTime - millis() + startTime*/);
          break;

        case 13:
          //workoutTime = 1500;
          lcd.print("Leg wrkt 1; " /* + workoutTime - millis() + startTime*/);
          break;

        case 14:
          //workoutTime = 2400;
          lcd.print("Leg wrkt 2; " /* + workoutTime - millis() + startTime*/);
          break;

        case 15:
          //workoutTime = 1800;
          lcd.print("Leg wrkt 3; " /*+ workoutTime - millis() + startTime*/);
          break;
        prevReply=reply;
      }
  }
  prevAngle=angle;
}
```

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

title: Can I change the text on the LCD by rotating the potentiometer?

Answers: 1

body:
Here is a (heavily) stripped-down version of your code:

```c++
void loop() {
    potVal = analogRead(potPin);
    angle = map(potVal, 0, 1023, 0, 300);
    if (angle > prevAngle + 69) {
        // stuff...
    } else if (angle < prevAngle - 69) {
        // stuff...
    }
    // lots of more stuff...
    prevAngle = angle;
}
```

Imagine this executing a few thousand times a second. Each time, it
computes the angle of the potentiometer's knob, then copies the computed
angle into `prevAngle`. Unless you turn the pot _really_ fast, the angle
is unlikely to change by more than 69° in that fraction of a
millisecond.

I suggest _not_ updating `prevAngle` on every iteration. Instead, let
`angle` slowly drift away from `prevAngle` through many iterations of
the loop. When the two are more than 69° apart, then you take the action
you wanted to take, _and only then_ you update `prevAngle`.


body:
I know that the topic is not related to Arduino, but I am completely sure that someone can help me find the problem.
I am testing 6 temperature sensors (3 digital, 3 analog). The digital ones are "DS18B20" which I trust, the analog ones are "MCP9701A", "TC1047A" and "MCP9700A".
By reading the analog sensors using Arduino-UNO or Arduino-mega the results of the 6 sensors are almost identical and I don't face any problem. But when make the test using the ESP32-devkitc-v4 I obtain wrong reading from the 3 analog sensors. In the code "serial monitor" I obtain a voltage value completely different from the one I measure physically by a multi-meter

For example :
The 3 digital sensors a giving the value of 23.56C to 23.81C but for the "MCP9701A" analog sensor I obtain 16.26C and the voltage obtain in the serial monitor is 0.718 volts, however it is 0.851 volts by the multi-meter. And according to the calculations from the data-sheet: (0.851-0.4)/(19.5mVolts)= 23.12C which is so close to the digital sensors. I have the same problem with the other analog sensors, so if you can help me find my error, I will appreciate it.

Here are the data-sheets of the analog sensors:

**MCP9701A and MCP9711A**

https://ww1.microchip.com/downloads/en/DeviceDoc/20001942G.pdf

**TC1047A**

https://ww1.microchip.com/downloads/en/DeviceDoc/21498D.pdf

**Here is my code:**
```
#include <OneWire.h>
#include <DallasTemperature.h>
#include "driver/adc.h"

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);

// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);

#define analogInPin0 35
#define analogInPin1 32
#define analogInPin2 33

float analogTempTC1047=0.0;
float analogTempMCP9700=0.0;
float analogTempMCP9701=0.0;

float volt0=0.0;
float volt1=0.0;
float volt2=0.0;

int sensorValue0 = 0;
int sensorValue1 = 0;
int sensorValue2 = 0;

void setup() {
  // Start the Serial Monitor
  Serial.begin(9600);
  // Start the DS18B20 sensor
  sensors.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  sensorValue0 = analogRead(analogInPin0);
  sensorValue1 = analogRead(analogInPin1);
  sensorValue2 = analogRead(analogInPin2);

  volt0= (3.3/4096.0)*sensorValue0;
  analogTempMCP9701= ((volt0-0.4)/0.0195);

  volt1= (3.3/4096.0)*sensorValue1;
  analogTempTC1047= ((volt1-0.5)/0.01);

  volt2= (3.3/4096.0)*sensorValue2;
  analogTempMCP9700= ((volt2-0.5)/0.01);

  sensors.requestTemperatures();
  float temperatureC1 = sensors.getTempCByIndex(0);
  float temperatureC2 = sensors.getTempCByIndex(1);
  float temperatureC3 = sensors.getTempCByIndex(2);
  Serial.print("S1= ");
  Serial.print(temperatureC1);
  Serial.print("ºC");
  Serial.print(", S2= ");
  Serial.print(temperatureC2);
  Serial.print("ºC");
  Serial.print(", S3= ");
  Serial.print(temperatureC3);
  Serial.print("ºC,------- ");

  Serial.print("input sensor1= ");
  Serial.print(sensorValue0);
  Serial.print(", volt1=  ");
  Serial.print("= ");
  Serial.print(volt0, 3);
  Serial.print(", Analog sensor MCP9701 = ");
  Serial.print(analogTempMCP9701);

  Serial.print("----");
  Serial.print("input sensor2= ");
  Serial.print(sensorValue1);
  Serial.print(", volt2=  ");
  Serial.print("= ");
  Serial.print(volt1, 3);
  Serial.print(" --Analog sensor TC1047 = ");
  Serial.print(analogTempTC1047);

  Serial.print("----");
  Serial.print("input sensor3= ");
  Serial.print(sensorValue2);
  Serial.print(", volt2=  ");
  Serial.print("= ");
  Serial.print(volt2, 3);
  Serial.print(" --Analog sensor MCP9700 = ");
  Serial.println(analogTempMCP9700);
  delay(4000);
}
```

**And here is the serial monitor output:**
```
S1= 23.56ºC, S2= 23.81ºC, S3= 23.50ºC,------- input sensor1= 895, volt1=  = 0.721, Analog sensor MCP9701 = 16.47----input sensor2= 747, volt2=  = 0.602 --Analog sensor TC1047 = 10.18----input sensor3= 752, volt2=  = 0.606 --Analog sensor MCP9700 = 10.59
S1= 23.56ºC, S2= 23.75ºC, S3= 23.50ºC,------- input sensor1= 894, volt1=  = 0.720, Analog sensor MCP9701 = 16.42----input sensor2= 747, volt2=  = 0.602 --Analog sensor TC1047 = 10.18----input sensor3= 755, volt2=  = 0.608 --Analog sensor MCP9700 = 10.83
S1= 23.56ºC, S2= 23.75ºC, S3= 23.50ºC,------- input sensor1= 905, volt1=  = 0.729, Analog sensor MCP9701 = 16.88----input sensor2= 746, volt2=  = 0.601 --Analog sensor TC1047 = 10.10----input sensor3= 753, volt2=  = 0.607 --Analog sensor MCP9700 = 10.67
```

title: Obtaining wrong analog readings using the ESP32 devkitc v4

Answers: 1

body:
Not a full answer, only a direction to consider:

The ESP32 ADC seems to be shipped with a ADC calibration tolerance of ±6%, as stated in the [ESP32 datasheet, chapter 4.1.2][1]. [Here are the calibration docs.][2]

It seems like you're still off by more than those 6% (didn't calculate it through). Maybe your power supply is a bit weak, pulling the internal reference voltage down?

  [1]: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf#2f
  [2]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html#adc-calibration


body: I have designed a project using Arduino Every board which uses MCU Atmega4809 chip and I have used Arduino IDE for programming but now I am planning to design my custom board I have used schematics of Arduino every board available on Arduino website . how can i upload the bootloader (Where can I get the bootloader from ) and how can I upload the Arduino code on new Atmega4809 Chips.

title: Bootloader For Atmega4809

Answers: 1

body:
Nano Every doesn't use a bootloader. The ATmega4809 on Nano Every is flashed with the SAMD11 used as UPDI programmer with Arduino firmware.

Optiboot supports ATmega4809 and MCUDude [MegaCoreX][1] supports different ATmega4809 configurations and Optiboot.

  [1]: https://github.com/MCUdude/MegaCoreX


body:
I'm using two different types of code and noticing that in the first set up the last LED is dimmer than the rest. Then in the second set up, the first LED is brighter than the rest. I would like to know what is causing it and how I may fix it. My ultimate goal is to wire 30 LEDs on an Arduino Mega and time them to a sequence. I'm building the project from the ground up starting with 3 LEDs on an Arduino Uno. I really appreciate your insights.

The first set up is using a pushbutton as a switch to turn on 3 LEDs in a timed series, using 220ohm resistors. The first two LEDs wired to pins 2 and 4 are visibly bright while the last you can barely see a little dot of light.

[![pushbutton controlled 3 LEDs on Arduino Uno][1]][1]

Here's the code for it:

    int ledState = 0;
    int ledPin1 = 2;
    int ledPin2 = 4;
    int ledPin3 = 7;
    int buttonState = 0;
    const int buttonPin = 12;
    int buttonNew;
    int buttonOld;
    int fiveInterval = 3000;
    int oneInterval = 1000;

    void setup() {
      Serial.begin(9600);
      pinMode(ledPin1, OUTPUT);
      pinMode(ledPin2, OUTPUT);
      pinMode(buttonPin, INPUT);

    }

    void loop() {
      buttonNew = digitalRead(buttonPin);

      if(buttonOld == 0 && buttonNew == 1){
        if(ledState == 0){
          digitalWrite(ledPin1, HIGH);
          delay(fiveInterval);
          digitalWrite(ledPin2, HIGH);
          delay(fiveInterval);
          digitalWrite(ledPin3, HIGH);
          ledState = 1;
    //      for(int i ){
    //
    //      }
        }else{
          digitalWrite(ledPin1, LOW);
          digitalWrite(ledPin2, LOW);
          ledState = 0;
        }
      }
      buttonOld = buttonNew;
      delay(100);
    }

The second set up is some code I borrowed from a tutorial. The 1st LED (wired to pin 2) is several times brighter than following LEDs. This one is a timed on/off of 3 LEDs, using 220ohm resistors.
[![3 LEDs lighting up in a series on an Arduino Uno][2]][2]
Here's the code for it:

    #define LED_PIN_1 2
    #define LED_PIN_2 4
    #define LED_PIN_3 7
    #define LED_NUMBER 3
    byte LEDPinArray[LED_NUMBER] = { LED_PIN_1,
                                     LED_PIN_2,
                                     LED_PIN_3 };
    int LEDIndex = 0;
    void initAllLEDs()
    {
      for (int i = 0; i < LED_NUMBER; i++) {
        pinMode(LEDPinArray[i], OUTPUT);
      }
    }
    void powerOnSelectedLEDOnly(int index)
    {
      for (int i = 0; i < LED_NUMBER; i++) {
        if (i == index) {
          digitalWrite(LEDPinArray[i], HIGH);
        }
        else {
          digitalWrite(LEDPinArray[i], LOW);
        }
      }
    }
    void toggleNextLED()
    {
      LEDIndex++;
      if (LEDIndex >= LED_NUMBER) {
        LEDIndex = 0;
      }
      powerOnSelectedLEDOnly(LEDIndex);
    }
    void setup()
    {
      initAllLEDs();
      digitalWrite(LEDPinArray[LEDIndex], HIGH);
    }
    void loop()
    {
      delay(1000);
      toggleNextLED();
    }

  [1]: https://i.stack.imgur.com/uGExq.jpg
  [2]: https://i.stack.imgur.com/CDXRa.jpg

title: LED brightness variations

Answers: 0


body:
So I asked this question a couple days ago but did some more work with some of the coding, but I'm really stuck and need some help. I'm trying to display the temperature for each separate thermistor from input pins A0-A8 on the 2560 board. My current issue that it only reads the A8 input pin. Do I need to make more declarations such as "double readThermistor1, double readThermistor2..." etc. After I make those declarations, how would I go about displaying each separate thermistor?  I'll post what I have so far:

```lang-cpp

//  Constants

const int    SAMPLE_NUMBER      = 10;
const double BALANCE_RESISTOR   = 10000.0;
const double MAX_ADC            = 1023.0;
const double BETA               = 3977.0;
const double ROOM_TEMP          = 298.15;   // room temperature in Kelvin
const double RESISTOR_ROOM_TEMP = 10060.0;

// Here is where we will save the current temperature
double currentTemperature = 0;

//  Pin Declarations

//Inputs:

int thermistorPin[] = {A0,A1,A2,A3,A4,A5,A6,A7,A8};  // Where the ADC samples the resistor divider's output

//Outputs:

void setup()
{
  // Set the port speed for serial window messages
  Serial.begin(9600);
}

double readThermistor()
{
  // variables that live in this function
  double rThermistor = 0;            // Holds thermistor resistance value
  double tKelvin     = 0;            // Holds calculated temperature
  double tCelsius    = 0;            // Hold temperature in celsius
  double adcAverage  = 0;            // Holds the average voltage measurement
  int    adcSamples[SAMPLE_NUMBER];  // Array to hold each voltage measurement

  /* Calculate thermistor's average resistance:
     As mentioned in the top of the code, we will sample the ADC pin a few times
     to get a bunch of samples. A slight delay is added to properly have the
     analogRead function sample properly */

  for (int i = 0; i < SAMPLE_NUMBER; i++)
  {
    adcSamples[i] = analogRead(thermistorPin[0]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[1]);
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[2]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[3]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[4]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[5]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[6]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[7]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
    adcSamples[i] = analogRead(thermistorPin[8]);  // read from pin and store
    delay(10);        // wait 10 milliseconds
  }

  /* Then, we will simply average all of those samples up for a "stiffer"
     measurement. */
  for (int i = 0; i < SAMPLE_NUMBER; i++)
  {
    adcAverage += adcSamples[i];      // add all samples up . . .
  }
  adcAverage /= SAMPLE_NUMBER;        // . . . average it w/ divide

  rThermistor = BALANCE_RESISTOR * ( (MAX_ADC / adcAverage) - 1);

  tKelvin = (BETA * ROOM_TEMP) /
            (BETA + (ROOM_TEMP * log(rThermistor / RESISTOR_ROOM_TEMP)));

  tCelsius = tKelvin - 273.15;  // convert kelvin to celsius

  return tCelsius;    // Return the temperature in Celsius
}

void loop()

{
  currentTemperature = readThermistor();
  delay(3000);

  /* Here is how you can act upon a temperature that is too hot,
  too cold or just right. */
  if (currentTemperature > 0.0 && currentTemperature < 60.0)
  {
    Serial.print("It is ");
    Serial.print(currentTemperature);
    Serial.println("C. Ahhh, very nice temperature.");

  }
  else if (currentTemperature >= 60.0)
  {
    Serial.print("It is ");
    Serial.print(currentTemperature);
    Serial.println("C. I feel like a hot tamale!");
  }
}

```

Any help is appreciated, thank you.

title: Displaying multiple temperature outputs w/Thermistors

Answers: 1

body:
Here is my proposal:

Sum the readings (samples) of each sensor(thermistor) and store the sum in an array. Then divide each sum by the number of samples that were taken. Instead of computing one tCelsius, compute one tCelsius for each average values and store it in an array too. Then print each of them. Feel free to print it as you like.

BTW I did not compile and test the code. There might be errors in it. Use it as a hint/example.

    const int    SAMPLE_NUMBER      =    10;
    const double BALANCE_RESISTOR   = 10000.0;
    const double MAX_ADC            =  1023.0;
    const double BETA               =  3977.0;
    const double ROOM_TEMP          =   298.15;
    const double RESISTOR_ROOM_TEMP = 10060.0;

    // PIN_COUNT is the length of the thermistorPin list.
    const double PIN_COUNT = 9;
    int thermistorPin[] = {A0,A1,A2,A3,A4,A5,A6,A7,A8};

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

    double readThermistor()
    {
      double rThermistor = 0.0;
      double tKelvin     = 0.0;

      // The count of the zeros below should be equal
      // to the PIN_COUNT
      double tCelsius[]
               = {0.0, 0.0, 0.0, 0.0, 0.0,
                  0.0, 0.0, 0.0, 0.0};
      double adcSampleSumPerPin[]
               = {0.0, 0.0, 0.0, 0.0, 0.0,
                  0.0, 0.0, 0.0, 0.0};

      for (int i = 0; i < SAMPLE_NUMBER; i++)
      {
        for (int j = 0; j < PIN_COUNT; i++)
        {
          adcSampleSumPerPin[j] +=
                       (double) analogRead(thermistorPin[j]);
          delay(10);
        }
      }

      for (int i = 0; i < PIN_COUNT; i++)
      {
        adcSampleSumPerPin[i] /= SAMPLE_NUMBER;
        rThermistor = BALANCE_RESISTOR *
                      ((MAX_ADC / adcSampleSumPerPin[i]) - 1);
        tKelvin = (BETA * ROOM_TEMP) /
                  (BETA + (ROOM_TEMP * log(rThermistor /
                  RESISTOR_ROOM_TEMP)));
        tCelsius[i] = tKelvin - 273.15;
      }

      return tCelsius;
    }

    void loop()
    {
      delay(3000);
      currentTemps = readThermistor();

      for (i = 0; i < PIN_COUNT; i++)
      {
        double currentTemperature = currentTemp[i];
        if (currentTemperature > 0.0 && currentTemperature < 60.0)
        {
          Serial.print("Sensor A");
          Serial.print(i);
          Serial.println(":");

          Serial.print("It is ");
          Serial.print(currentTemperature);
          Serial.println("C. Ahhh, very nice temperature.");
        }
        else if (currentTemperature >= 60.0)
        {
          Serial.print("Sensor A");
          Serial.print(i);
          Serial.println(":");

          Serial.print("It is ");
          Serial.print(currentTemperature);
          Serial.println("C. I feel like a hot tamale!");
        }
      }
    }


body:
The code's purpose is to change from one led to another if the LDR detects a certain level of light for a given time. Currently, since I cannot wait 5 minutes to complete one circuit, each LED should be on for 1000 ms. At one stage in the code, there are no LEDs on. The LEDs should not turn on until the LDR has sensed no light and then light levels necessary for the code to restart.

Here is the code;

```c++
const int buzzer=3;
const int ldr = A4;

void setup () {
    Serial.begin(9600);
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(buzzer, OUTPUT);
    pinMode(ldr, INPUT);
}

void loop() {
    int ldrStatus = analogRead(ldr);

    if (ldrStatus >= 300) {
        digitalWrite(13, HIGH);
        delay(1000);
    } else {
        noTone(buzzer);
        digitalWrite(13, LOW);
        digitalWrite(12, LOW);
    }

    if (ldrStatus >= 300) {
        digitalWrite(13, LOW);
        digitalWrite(12, HIGH);
        tone(buzzer, 100, 30);
        delay(1000);
        tone(buzzer, 100);
        digitalWrite(12, LOW);
        digitalWrite(13, LOW);
    } else {
        noTone(buzzer);
        digitalWrite(13, LOW);
        digitalWrite(12, LOW);
    }
}
```

I have realised that the purpose of my code is unclear. What happens is one LED turns on when the LDR senses light. If the light continues, then the buzzer will sound once and the LED will change to a different colour LED. If the LDR continues to detect light, then all LEDs will turn off and the buzzer will sound continuously. The only problem is that the code doesn't stop until the LDR has sensed a high enough decrease in light levels.

title: How do I keep one function continued until a variable is completed?

Answers: 1

body:
You have a couple of issues in your code.

Analog inputs are versatile and (most) can be used as digital inputs (ie. on/off). For this application you are after the analog value of the LDR, however this is not how you have implemented it. You are declaring the LDR pin as a digital pin by `pinmode(ldr, INPUT)`. Delete this line altogether. For reference, see [the analog read documentation][1].

Secondly you have two `if` statements that are the same.

    if (ldrStatus>=300) {
      digitalWrite(13, HIGH);

and

    if (ldrStatus>=300) {
      digitalWrite(13, LOW);

I suspect that one of them is supposed to be a less than `<` sign.

Both LEDS are off beause it is executing this section of code:

    }else{
      noTone (buzzer);
      digitalWrite (13, LOW);
      digitalWrite (12, LOW);
  }

I suggest you add `Serial.println()` lines ([documentation here][2]) to your code for debugging. Particularly helpful would be to add it in the `if` and `else` statements as well as adding `Serial.println(ldrStatus)` as follows:

    int ldrStatus=analogRead(ldr);
    Serial.println(ldrStatus);
    if (ldrStatus>=300) {

Refer to [this document][3] on how to open your Serial Monitor in the Arduino Software (IDE).

Bonus Hint:
You can auto-format your code by using `ctrl + T`. See [this article][4] for more info.

  [1]: https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/
  [2]: https://www.arduino.cc/reference/en/language/functions/communication/serial/println/
  [3]: https://docs.arduino.cc/software/ide-v2/tutorials/ide-v2-serial-monitor
  [4]: https://www.tutorialspoint.com/auto-format-code-in-arduino-ide


body: Having a bit of a problem with the Arduino Nano RP2040. I'm trying to use the onboard microphone to read the frequency of a sound and then use that variable for calculations. However, while I can get the mic to respond to audio stimulus, I'm not sure what the values being recorded actually are. I want to be able to play for example a note at 80 Hz. I need to be able to identify a note.

title: Help in Frequency Conversion in ArduinoRP2040

Answers: 0