title: SPI with DMA in a Arduino Due

text:
# Question
Title: SPI with DMA in a Arduino Due
I have a project where I need to store data (~16 Mo) on a memory and be able to fetch the data fast (\<36000 bits/s) with DMA because I have other signals to take care of.

Currently I use an SD card with the SD library, but it doesn't seems to use DMA because of the delay between sending.

Many people told me it shouldn't be that hard and I suppose so. My guess is that I can't configure the DMA and/or the SPI correctly.

I tried this a long time ago.

Can someone show me an example of SPI with DMA, or tips on how to configure both?

# Answer
> 0 votes
```
#include <dmac.h>
#include <SPI.h>
#include <Arduino.h>
#include <sam.h>

uint8_t sourceBuffer[256];

void setup() {
  SPI.begin();
  SPI.setClockDivider(21);  // 4MHz clock (assuming 84MHz system clock)
  setupDMA();
}

void loop() {

  for(int i = 0; i < sizeof(sourceBuffer); i++) {
    sourceBuffer[i] = i;
  }
  startDMATransfer();
  delay(1000);
}

void setupDMA() {
  // Enable the DMA controller
  PMC->PMC_PCER1 |= PMC_PCER1_PID34;  // DMA ID for the Due is 34

  // Disable SPI DMA TX and RX
  SPI0->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS;

  // Setup a DMA channel for the transfer (channel 1 for this example)
  DmacChannel* channel = &(DMAC->DMAC_CH_NUM[1]);

  // Disable the DMA channel
  channel->DMAC_CHDR = DMAC_CHDR_DIS;

  // Clear any flags and reset the status
  channel->DMAC_CHDR = DMAC_CHDR_RES;

  // Set up source and destination pointers
  channel->DMAC_SADDR = (uint32_t) sourceBuffer;
  channel->DMAC_DADDR = (uint32_t) &(SPI0->SPI_TDR);

  // Configure source and destination pointers: source increments, destination does not
  channel->DMAC_CTRLA = DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE;

  // Set source and destination handshake (related to the SPI0 Tx)
  channel->DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE | DMAC_CTRLB_DST_DSCR_FETCH_DISABLE |
                        DMAC_CTRLB_FC_MEM2PER_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING |
                        DMAC_CTRLB_DST_INCR_FIXED;

  channel->DMAC_CFG = DMAC_CFG_SRC_PER(1) | DMAC_CFG_DST_PER(1) | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG;
}

void startDMATransfer() {
  // Assuming channel 1 is used
  DmacChannel* channel = &(DMAC->DMAC_CH_NUM[1]);

  // Set up the buffer size
  channel->DMAC_CUBC = sizeof(sourceBuffer);

  // Enable SPI DMA for TX
  SPI0->SPI_PTCR = SPI_PTCR_TXTEN;

  // Enable the DMA channel to start the transfer
  channel->DMAC_CHER = DMAC_CHER_ENA;
}

```

When you want to send data via SPI using DMA, you can fill the `sourceBuffer` and call `startDMATransfer()`.

Remember to always refer to the Atmel SAM3X8E datasheet and the Arduino Due's schematic when you are working at this level, as it provides in-depth details on how the hardware functions. I am unable to run the code or test it. But I believe that the code logic is proper. Error handling is up to you.

---
Tags: programming, spi, arduino-due, c
---


# Question
Title: reading device or board specific properties from the Arduino MKR WiFi 1010 device
How to read programmatically the device specific properties from the Arduino MKR WiFi 1010 chip or board?

For example, following properties of the device:

* any identification number, that can uniquely identify the physical device, integer or GUID or string or any other, how to read that from the code?
* SerialNumber of the MRK WiFi 1010 device
* ModelNumber of the MRK WiFi 1010 device

I have tried to check the documentation and examples, however I couldn't find anything at all.

# Answer
MAC address could be of use to you, but remember that it can be spoofed. Aside from that Serial and Model numbers **are not** accessible from software layer.

Here is a simple implementation for fetching the MAC address

```
    #include <WiFiNINA.h>

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

      if (WiFi.status() == WL_NO_MODULE) {
        Serial.println("Communication with WiFi module failed!");
        while (true);
      }

      byte mac[6];
      WiFi.macAddress(mac);
      Serial.print("MAC: ");
      for (int i = 5; i >= 0; i--) {
        if (mac[i] < 16) {
          Serial.print("0");
        }
        Serial.print(mac[i], HEX);
        if (i > 0) {
          Serial.print(":");
        }
      }
      Serial.println();
    }

    void loop() {}

```

Another solution that I can think of is writing your own unique identifier such as UUID to EEPROM memory for each board.

If you're generating a UUID in the context of a server or a device with more resources, there are libraries and tools that can create these for you based on various factors to ensure uniqueness (like timestamp, MAC address, etc.). However, with a microcontroller like the one on the Arduino MKR WiFi 1010, you have a more constrained environment, and the process can be more manual.

You can use an online UUID generator or can generate it using Python:

```
    import uuid
    print(uuid.uuid4())

```

After generating your UUID's, you can write them on EEPROM but make sure to not over-write EEPROM since it has very limited call boundaries.

## Writing to EEPROM

```
#include <EEPROM.h>

const char* MY_UUID = "550e8400-e29b-41d4-a716-446655440000";
const int EEPROM_UUID_ADDRESS = 0;  // starting address in EEPROM

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

  // Write UUID to EEPROM
  for (int i = 0; i < strlen(MY_UUID); i++) {
    EEPROM.write(EEPROM_UUID_ADDRESS + i, MY_UUID[i]);
  }
  Serial.println("UUID written to EEPROM");
}

void loop() {}

```

"starting address in EEPROM" is the address of the first box (or byte) where the program begins storing our UUID. By specifying `const int EEPROM_UUID_ADDRESS = 0;`, we are saying we'll start storing the UUID from the very first byte (box) of the EEPROM. **If you were storing other data in EEPROM, you would need to ensure that the addresses don't overlap**. For example, if you had other data stored in the first 10 bytes, you might set `EEPROM_UUID_ADDRESS` to 10 to start storing the UUID from the 11th byte.

## Reading from the EEPROM:

```
#include <EEPROM.h>

const int UUID_LENGTH = 36;  // Length of the UUID string
char readUUID[UUID_LENGTH + 1];  // +1 for the null terminator
const int EEPROM_UUID_ADDRESS = 0;  // starting address in EEPROM

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

  // Read UUID from EEPROM
  for (int i = 0; i < UUID_LENGTH; i++) {
    readUUID[i] = EEPROM.read(EEPROM_UUID_ADDRESS + i);
  }
  readUUID[UUID_LENGTH] = '\0';  // Null terminate the string

  Serial.print("UUID read from EEPROM: ");
  Serial.println(readUUID);
}

void loop() {}

```

**+1 for the null terminator**:

In the C and C++ programming languages, strings are represented as an array of characters. The end of the string is marked by a special character known as the "null terminator" or "null character", which is represented by the value `'\0'` (a byte with all bits set to 0).

When we read or write strings to/from memory (like EEPROM), we often need to account for this null terminator to ensure the string is properly terminated and can be safely used with string functions.

In the code, the UUID is 36 characters long. When we declare an array to hold this UUID with the line:

```
char readUUID[UUID_LENGTH + 1];

```

We're allocating space for the 36 characters of the UUID plus an additional character for the null terminator, hence `UUID_LENGTH + 1`.

Later, after reading the UUID from EEPROM, we ensure this array is a properly terminated string by adding the null terminator:

```
readUUID[UUID_LENGTH] = '\0';

```

This ensures that when we use `readUUID` in functions that expect a string, they'll recognize where the string ends. Without the null terminator, these functions wouldn't know where the string finishes, leading to unpredictable behavior or errors.

I hope that this is helpful.
> 1 votes

# Answer
The IDE shows the serial number so I looked into the SAMD core and found the function which reads the serial number from registers. It is in the CDC.cpp file

```
uint8_t Serial_::getShortName(char* name) {
    // from section 9.3.3 of the datasheet
    #define SERIAL_NUMBER_WORD_0    *(volatile uint32_t*)(0x0080A00C)
    #define SERIAL_NUMBER_WORD_1    *(volatile uint32_t*)(0x0080A040)
    #define SERIAL_NUMBER_WORD_2    *(volatile uint32_t*)(0x0080A044)
    #define SERIAL_NUMBER_WORD_3    *(volatile uint32_t*)(0x0080A048)

    utox8(SERIAL_NUMBER_WORD_0, &name[0]);
    utox8(SERIAL_NUMBER_WORD_1, &name[8]);
    utox8(SERIAL_NUMBER_WORD_2, &name[16]);
    utox8(SERIAL_NUMBER_WORD_3, &name[24]);
    return 32;
}

```

from the datasheet of SAMD21:

> Each device has a unique 128-bit serial number which is a concatenation of four 32-bit words contained at the following addresses:

> The uniqueness of the serial number is guaranteed only when using all 128 bits
> 6 votes

---
Tags: arduino-ide, softwareserial, mkr1010wifi
---


title: Limit of EthernetClient connections

text:
# Question
Title: Limit of EthernetClient connections
I'm working on a project on which I need to have multiple EthernetClient connections to different servers. All of these connections must be kept alive simultaneously and by this I mean I cannot stop or close one of these clients before starting the other.

Currently I can keep 2 simultaneous successful EthernetClient connections. After this, any subsequent client fails to connect to any server. The following code is running on an ESP32-S3 with a W5500 Ethernet module.

```
#include <Arduino.h>
#include <EthernetLarge.h>
#include <SPI.h>

#define     SPI_MOSI    35
#define     SPI_MISO    37
#define     SPI_SCK     36
#define     ETHERNET_CS 38

SPIClass SPI_Ethernet;
EthernetClient ethCli1;
EthernetClient ethCli2;
EthernetClient ethCli3;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

void setup()
{
  Serial0.begin(115200);
  SPI_Ethernet.begin(SPI_SCK, SPI_MISO, SPI_MOSI, ETHERNET_CS);

  pinMode(39, OUTPUT);
  pinMode(47, OUTPUT);
  digitalWrite(47, HIGH);
  digitalWrite(39, LOW);
  delay(500);
  digitalWrite(39, HIGH);

  Ethernet.init(ETHERNET_CS);
  Ethernet.begin(mac);
  Serial0.println(Ethernet.localIP());

  if( !(ethCli1.connect("httpbin.org", 80)) )
      Serial0.println("connection > 1 < failed");
  else
    Serial0.println("connection > 1 < succeeded");

  if( !(ethCli2.connect("httpbin.org", 80)) )
    Serial0.println("connection > 2 < failed");
  else
    Serial0.println("connection > 2 < succeeded");

  if( !(ethCli3.connect("httpbin.org", 80)) )
    Serial0.println("connection > 3 < failed");
  else
    Serial0.println("connection > 3 < succeeded");
}

void loop()
{
}

```

Which outputs:

```
connection > 1 < succeeded
connection > 2 < succeeded
connection > 3 < failed

```

In this code I'm using the OPEnSLab-OSU/EthernetLarge Ethernet library. But I also tried to run it with the Ethernet.h with the same output. In the W5500 documentation I was able to find the information that it can keep up to 8 connections open, but I wasn't able to find if the ESP32 has any restrictions like a max of simultaneous connections. Is it possible to keep more than 2 connections alive simultaneously?

In short:

* I'm using an ESP32-S3 with a W5500 Ethernet Module.
* I can keep 2 simultaneous connections and closing previous connections before opening a new one works, but in my project I need to keep at least 3 simultaneous connections.
* Changing from OPEnSLab-OSU/EthernetLarge Ethernet library to Ethernet.h produced the same output.
* Adding a delay between the connections didn't work.
* In the example code all the connections are being established to the same server, but in my official project these connections are established to different servers. Either way the output is the same.
* The W5500 documentation says that it can keep up to 8 simultaneous connections. I wasn't able to find if ESP32 has any restrictions on the limit of simultaneous connections.

# Answer
> 2 votes
The `OPEnSLab-OSU/EthernetLarge` library by default defines `MAX_SOCK_NUM` to `2`. Increasing this value allowed me to keep more simultaneous connections.

Regarding the `Ethernet.h` library, I also checked it and it was already setting `MAX_SOCK_NUM` to `8`. Testing the code again with it also allowed me to keep more simultaneous connections. Why I wasn't able to keep them before when using `Ethernet.h` it is still a mystery to me.

---
Tags: esp32, ethernet, esp32-s3
---


# Question
Title: How to control camera lens by Arduino's PWM? What FOCUS A+, FOCUS A- wires means?
I have a camera lens which I want to control by arduino (like this https://vi.aliexpress.com/item/1005004141070063.html)

I have an info about wires description but I can't understand what focus A+, A-, B+, B- means? I guess I need to send PWM pulses to A and B wires to move focus in straigt and opposite direction but I can't understand what + and - means. Is it just signal and ground?

# Answer
> 1 votes
It looks like you will be dealing with bipolar stepper motors. Most likely, A+ and A− are connected to one coil, whereas B+ and B− are connected to the other coil.

See the Arduino documentation: Arduino and Stepper Motor Configurations for instructions on driving this kind of motor.

---
Tags: pwm
---


# Question
Title: How can I compensate for a joysticks offset value in neutral position?
I have a joystick that outputs the values 0 - 4095. I want to map these values in this fashion (Yes, the reversed mapping is intended):

```
outputValue = map(inputValue, 4095, 0, -2048, 2047);

```

However, the neutral central position of the joystick is offset, outputting 145 instead of 0.

Is there a way to map these values - taking the offset value in account - and still have the output values ranging from -2048 to 2047? I fail to do this with the map() function alone, and could need some help with the specific math involved.

# Answer
> 6 votes
You can only approximate it, you have to sacrifice something.

The basic problem is that your input range is asymmetric in respect to the mid point. Let's visualize it this way (with a bit of visual exaggeration):

```
min                     mid      max
0----------------------2193-----4095

```

Another problem is that the whole range 0..4095 may not be physically reachable by the joystick, so your usable range may actually look like this:

```
min                mid        max
433---------------2193-------3722

```

So, to calibrate your joystick, you need to measure the min, mid and max points that you can physically reach with exactly that joystick on the input scale (joysticks are analog devices, so their actual ranges can differ from joystick to joystick and even from axis to axis in the same physical joystick).

Now, if you have these numbers (I call those calibration values `joy_min`, `joy_mid` and `joy_max`), you need to `map` both parts of your range separately:

```
if( joy_input < joy_mid ) {
  output = map(joy_input, joy_min, joy_mid, -2048, 0);
} else {
  output = map(joy_input, joy_mid, joy_max, 0, 2047);
}

```

The downside is that any step in the output may represent a slightly different distance in the movement, depending on whether you are currently lower or higher than the measured midpoint. But I expect that to be negligible.

Also, keep in mind that this is only for one axis of the joystick. You may need completely different calibration values for the other axis. In addition, you may want to implement a "dead zone" around the midpoint, i.e. always returning `output = 0` for `joy_mid-10 < joy_input < joy_mid+10` or something like that.

And as the joystick range may drift (with temperature, age, etc...) and `map` does not constrain the output range, it might be a good idea to apply a `output = constrain(output, -2048, 2047)` afterwards.

(In my code, I assume that you want to map 0..4095 to -2048..2047 as you say in the text; but in your code, you map 4095..0 to -2048..2047, basically flipping the direction. If that part of your code is correct and the text is not, just swap -2048 with 2047 in my code.)

---
Tags: joystick, map
---


# Question
Title: Confusing stepper reaction to increase in delayMicroseconds()
I have been following this tutorial using the same hardware, TB6600 driver, 42HS48-1704A (yes I think its supposed to be 42hs40 but thats not what it says the sticker) stepper but am controlling via a Nano.

The code,

```
const int stepPin = 5;
const int dirPin = 2;
const int enPin = 8;

int num_steps = 200;
int dt = 1000;

void setup() {

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enPin, OUTPUT);
  digitalWrite(enPin, LOW);

}

void loop() {

  digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction

  for(int x = 0; x < num_steps; x++) {

    digitalWrite(stepPin, HIGH);
    delayMicroseconds(dt);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(dt);

  }

  delay(1000); // One second delay
  digitalWrite(dirPin, LOW); //Changes the direction of rotation

  for(int x = 0; x < num_steps; x++) {

    digitalWrite(stepPin, HIGH);
    delayMicroseconds(dt);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(dt);

  }

  delay(1000);
}

```

I added `dt` so I could control the step speed but its not behaving as I thought it would.

The original code has `dt = 500` which needed 15V to run & runs not quite chunky movement but bordering on it & just over 1 revolution when `num_steps = 2000`

I changed to `dt = 1000` & now its got really smooth faster motion & doing quite a few revolutions (too fast for me to count with my eyes) but if reduce `num_steps = 200` that results in 1 revolution & now only needs 9V to run.

So, how come when I increase the delay it runs faster? Is this some kind of clocking/synching issue?

# Answer
> 2 votes
With `dt = 500` you get one step per millisecond. This is probably too fast for the motor/driver combination. When the driver tries to execute another step, while the previous is not fully executed by the motor shaft (which needs some time due to the shafts inertia), the magnets will misalign and the coil current of the current step will not result in a proper rotation of the shaft. Some of the pulses are aligned enough to the motor shaft position just by chance and can result in a correct step. So the motor skips some of the pulses due to its inertia. Increasing the voltage will increase the force of the motor coils, which drive the shaft. Thus it can overcome the described problems easier (the shaft moving faster by the force of one pulse than before)

Increasing to `dt = 1000` gives the motor enough time to follow each step. You aren't loosing steps because the magnets and coils in the motor always align correctly.

---
Tags: arduino-nano, stepper, stepper-motor
---


# Question
Title: How can I host a WiFi network from an Arduino getting a connection from a SIM card?
My friend and I are doing a project and we're stuck on a problem. We tried looking stuff up but it looks like no one documented something similar before.

Basically, what we want to do is have one Arduino (we thought a MKR NB 1500) in a remote location without any available WiFi (or Ethernet) connection be able to host its own Wifi Network. We thought that giving it a SIM card would allow it to communicate to our webserver (API) and to our surprise, it does (yay)! However, we also want **people near the Arduino to be able to access the internet**. However, that's where we're stuck...

I know that hosting an access point on an Arduino with WiFi is possible. But **is it possible for that access point to link the user to the real internet, itself provided by the SIM card**?

*P.S. : We are open to having two different Arduinos linked together (or more) in order to make this work. We just need to be able to transfer the SIM network to an access point (hotspot basically).*

*P.P.S : We are also open to using different technologies like ESP controllers... We're just not using a cellular hotspot because of the cost of these things and we want to make it with Arduino or different controllers.*

# Answer
> 0 votes
Bridging of two networks at TCP/IP level is done in the TCP/IP stack. It translates addresses from one *network interface* to other *network interface*, but both interfaces are handled by the same *TCP/IP stack*.

An example on an MCU would be translating between esp8266 SoftAP and STA network interface. They are two network interfaces handled by the same TCP/IP stack. And now esp8266 Arduino can handle some Ethernet modules as additional network interfaces of that TCP/IP stack too.

With MKR NB 1500 or any other (mobile) network module attached to Arduino you can't do bridging because the TCP/IP stack is in the firmware of the module and the WiFi or Ethernet shield you would attach to the MKR would have its own TCP/IP stack in the firmware too.

If you are on esp8266, esp32 or other MCU where the TCP/IP stack runs in the MCU, you still can't make it work together with the TCP/IP stack in the external module. Those Ethernet modules esp8266 can use as netwok interaces with its TCP/IP stack are interfaced on the software layer closer to hardware, but the mobile network modules use AT commands without exposing access to lower layers.

What you can do is to proxy some network services as I write in this answer.

---
Tags: wifi, web-server, wireless
---


title: Does ESP32 can support WIFIDirect

text:
# Question
Title: Does ESP32 can support WIFIDirect
I would like to establish a simple P2P connection between an ESP32 and an Android device without the use of an access point. I should be able to send and receive data from the ESP32 through the established connection. Is this possible, and if not, are there any alternative solutions?

# Answer
From my research i for to know that we can't use wifi direct for esp32 i found an alternative for my problem!!!!
> 0 votes

# Answer
I do know that you can host a web page on an esp8266, sending and receiving data on that. You can from there connect the Android to that web page. I am not sure what you mean by access point, and I hope that this method is not using an access point.
> 2 votes

---
Tags: arduino-ide, esp32, wifi, wireless, esp32-cam
---


# Question
Title: Is it possible to use UART0 freely when connecting ESP32 s3 via USB (D+, D-)?
I've designed a test PCB that utilizes an ESP32 S3 and testing pins. During program uploads, I use the USB interface over GPIO20 and GPIO19 as D+ and D-. Everything works fine in this configuration. However, I've encountered an issue where UART0 becomes inactive after using the USB interface. Now, I want to connect the TX pin of a GPS module (NEO 6m) to UART0's RX pin, but I'm unable to do so. It's impractical to run the code as is because when data is received on RX0, it floods the continuous serial screen. I'm looking for a solution to completely disconnect UART0 from the USB interface so that I can use it independently.

**In Short How I can receive date from UART0 and than Serial.print to Serial monitor over the USB interface?**

```
#define RXD2 6
#define TXD2 7

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial)
    delay(200);
  Serial.println("start GPS...");

  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
}

void loop() {
  while (Serial.available()) {
    Serial.print(char(Serial.read()));
  }
}

```

# Answer
> 2 votes
`Serial` is 'com' port over USB on esp32 with native USB (and "USB CDC On Boot" option selected in Tools menu). **For UART0 the core then creates `Serial0`.**

From documentation:

> To use the UART as serial output, you can use Serial0.print("Hello World!"); instead of Serial.print("Hello World!"); which will be printed using USB CDC.

---
Tags: esp32, gps, uart, esp32-s3
---


# Question
Title: Expected signature for ATmega328P is 1E 95 0F; I can not burn bootloader on my arduino Uno
well... the problem starts from the time that I accidentally touched the crystal on my arduino and all of a sudden everything messed up; the leds on arduino turned on and off while being touched, and after that I was unable to program it... after a lot of searches, I decided t burn bootloader again... so I got a USBasp and wired it to arduino and tried to program it using programmer or burning bootloader... but... It is not posible because of the following ERROR:

```
**Arduino: 1.8.15 (Windows 10), Board: "Arduino Uno"

avrdude: warning: cannot set sck period. please check for usbasp firmware update.

avrdude: Expected signature for ATmega328P is 1E 95 0F

         Double check chip, or use -F to override this check.

Error while burning bootloader.**

```

I tried changing that 0xF in config file to 0x14, because of the difference between ATmega328 and ATmega328p... but still no progress... I will be very glad if someone can help me run this UNO...

by the way, is it possible that the crystal which I touched with hand is ruined or interrupted and all of these stuff is because of that?

# Answer
> 1 votes
Well a couple of options:

* Plug the Arduino with USB, do you see a Serial PORT? If you do there is a good chance the USB CHIP is ok.
* Try programming the Arduino with a 12v High Voltage Programmer and burn a 8Mhz Internal oscillator bootloader and see if it works, if it does, the the crystal is damaged.
* Another alternative, e to use a 16mhz crystal and put it in parallel with that one, see if you can flash it like that, or just desolder that one and replace with a new one, doesn't matter if it's the same freq, you still be able to burn a bootloader, hopefully choose a osc that is supported by the bootloaders (8, 12, 16, 20) for example

---
Tags: arduino-uno, programming, usbasp
---


# Question
Title: Low-byte fuse programming of ATmega328 on Arduino Uno
I want to use the ATmega328 on my Arduino Uno board to clock a TDC1000 using the clkout bit of the ATmega328, but this requires fuse programming of the low byte. Can anyone tell me how to do this?

# Answer
> 1 votes
Do you have another Arduino? If so, check this video and you can set the fuses with AVRDUDESS.

Be careful: if you set the fuses the wrong way you kind of "brick" the chip, and depending on the mess, you can only recover with a high voltage programmer.

One advantage is that you can never ruin the chip with the fuses, just make it hard to reset to some defaults.

---
Tags: arduino-uno, atmega328, oscillator-clock
---


title: Help with program upload problem

text:
# Question
Title: Help with program upload problem
I'm going to upload some code to my LeArm using an Arduino board. I connected the RX and TX pins of the LeArm to the Arduino, but I got an error message when I tried to upload the code.

I'm not sure if I made the connections correctly. Does anyone have any tips on how to upload the programs successfully?

# Answer
> 0 votes
Is the Arduino Mega you have a "Chinese" version? If it is, try installing these drivers and try again.

---
Tags: arduino-uno, programming, uploading
---


# Question
Title: Serial does not read buffer with integer characters greater than 43
I'm trying to write a script to move an object coupled to a linear axis through a `stepper motor`. The user must send information such as the `length` to be moved, the `speed` of movement, the `direction` of movement, or even if he wants to make millimetric adjustments via the `serial`. However, `I can't read lengths from 43 mm` where I `send` the `integer 43 over serial`. I tested several methods that I found on the internet. Below is the current code and some alternatives of the serial read section that failed.

```
void(* resetFunc) (void) = 0;

//Serial read
const int bufferSize = 30; // Tamanho máximo para o buffer de leitura
char buffer[bufferSize];   // Buffer para armazenar os dados lidos via serial

//Step motor
const int stepPin = 3;
const int senPin = 2;
const int enPin = 8;
int sen, sp, len, ad; //sen = forward or backward, sp = speed, len = length, ad = enable steps to adjustment
int REV;//motor revolutions
int time_motor; // interval of pulse (on/off)

void setup()

{

  pinMode(stepPin,OUTPUT);
  pinMode(senPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);

  Serial.begin(9600);

  while (!Serial.available()) {
    delay(10);
  }

  int bytesRead = Serial.readBytesUntil('\n', buffer, bufferSize);

  buffer[bytesRead] = '\0';

  sscanf(buffer, "%d,%d,%d,%d", &ad, &sen, &len, &sp);

  Serial.print("ad: ");
  Serial.println(ad);
  Serial.print("sen: ");
  Serial.println(sen);
  Serial.print("len: ");
  Serial.println(len);
  Serial.print("sp: ");
  Serial.println(sp);

  time_motor = 100;

  REV = int(768 * len);

  if(ad == 0){
    if (sen == 1){
      backward(REV, time_motor);
      }

    else {
      forward(REV, time_motor);
      }

      resetFunc();
  }
  else{
    if(sen == 1){backward(768, time_motor);resetFunc();}
    else{forward(768, time_motor);resetFunc();}
  }
}

void forward(int len_fact, int time_c) {
  digitalWrite(enPin, LOW);
  digitalWrite(senPin, HIGH);
  for (int x = 0; x < len_fact; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(time_c);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(time_c);
  }
}

void backward(int len_fact, int time_c) {
  digitalWrite(enPin, LOW);
  digitalWrite(senPin, LOW);
  for (int x = 0; x < len_fact; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(time_c);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(time_c);
  }
}

void loop()
{

}

```

An alternative below:

```
  while (!Serial.available()) {
    // Aguarda até que haja dados disponíveis na porta serial
  }

  delay(100); // Pequeno atraso para garantir que todos os dados tenham chegado

  int bytesRead = 0;
  while (Serial.available() && bytesRead < bufferSize - 1) {
    char c = Serial.read();
    if (c == '\n') {
      break; // Termina a leitura ao encontrar uma quebra de linha
    }
    buffer[bytesRead] = c;
    bytesRead++;
  }

  // Adiciona o caractere nulo para indicar o final da string
  buffer[bytesRead] = '\0';

  // Usa a função sscanf para extrair os números do buffer
  sscanf(buffer, "%d,%d,%d,%d", &ad, &dir, &len, &sp);

  // Imprime os valores lidos para verificá-los
  Serial.print("ad: ");
  Serial.println(ad);
  Serial.print("dir: ");
  Serial.println(dir);
  Serial.print("len: ");
  Serial.println(len);
  Serial.print("sp: ");
  Serial.println(sp);

```

And the other:

```
  while (!Serial.available()) {
    // Aguarda até que haja dados disponíveis na porta serial
  }

  // Lê os dados da porta serial e armazena no buffer até atingir o tamanho máximo
  int bytesRead = 0;
  while (bytesRead < bufferSize - 1) {
    if (Serial.available()) {
      char c = Serial.read();
      if (c == '\n') {
        break; // Termina a leitura ao encontrar uma quebra de linha
      }
      buffer[bytesRead] = c;
      bytesRead++;
    }
  }

  // Adiciona o caractere nulo para indicar o final da string
  buffer[bytesRead] = '\0';

  // Usa a função sscanf para extrair os números do buffer
  sscanf(buffer, "%d,%d,%d,%d", &ad, &dir, &len, &sp);

  // Imprime os valores lidos para verificá-los
  Serial.print("ad: ");
  Serial.println(ad);
  Serial.print("dir: ");
  Serial.println(dir);
  Serial.print("len: ");
  Serial.println(len);
  Serial.print("sp: ");
  Serial.println(sp);

```

Serial returns nothing or "?". How should I proceed to solve this problem? I'm using an original Arduino uno and writing in the arduino IDE. The version is 1.8.19.

# Answer
> 0 votes
Well, you didn't provided that much info, but i picked up on some of your code (below) and in the serial monitor i can read all the numbers :

```
    const int bufferSize = 30; // Tamanho máximo para o buffer de leitura
char buffer[bufferSize];   // Buffer para armazenar os dados lidos via serial

//Step motor
const int stepPin = 3;
const int senPin = 2;
const int enPin = 8;
int dir, sp, len, ad; //sen = forward or backward, sp = speed, len = length, ad = enable steps to adjustment
int REV;//motor revolutions
int time_motor; // interval of pulse (on/off)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
while (!Serial.available()) {
    // Aguarda até que haja dados disponíveis na porta serial
  }

  delay(100); // Pequeno atraso para garantir que todos os dados tenham chegado

  int bytesRead = 0;
  while (Serial.available() && bytesRead < bufferSize - 1) {
    char c = Serial.read();
    if (c == '\n') {
      break; // Termina a leitura ao encontrar uma quebra de linha
    }
    buffer[bytesRead] = c;
    bytesRead++;
  }

  Serial.println(buffer);

  // Adiciona o caractere nulo para indicar o final da string
  buffer[bytesRead] = '\0';

  // Usa a função sscanf para extrair os números do buffer
  sscanf(buffer, "%d,%d,%d,%d", &ad, &dir, &len, &sp);

  // Imprime os valores lidos para verificá-los
  Serial.print("ad: ");
  Serial.println(ad);
  Serial.print("dir: ");
  Serial.println(dir);
  Serial.print("len: ");
  Serial.println(len);
  Serial.print("sp: ");
  Serial.println(sp);
}

```

---
Tags: arduino-uno, serial, serial-data, integer
---


title: Arduino pin erratic behavior?

text:
# Question
Title: Arduino pin erratic behavior?
I've built a switch key matrix (thus the diode, contextually useful schematics below) and me being me, I realised after that I misunderstood a few things about how button really works, to say the least... So anyway, I want to save it so I plan on a solution which, to my surprise, is half-working: When I remake the entier circuit on a breadboard (mistake & solution), it's working but when I do it with my PCB, it doesn't...

The 5V+ is from a digital pin set to HIGH and I've mesured w/ an oscilloscope the tension between the ground and a digital pin ("Arduino INPUT") on the breadboard and on the PCB, with the input pin connected and not connected:

|  | Connected | Not Connected |
| --- | --- | --- |
| BreadBoard | 2.5V+ | 5V+ |
| PCB | 0V+ | 5V+ |

So it's seems like the pin is becoming one with the ground but I can't find anything that could explain this. I've been testing and trying to understand what the hell was going on for multiple hours now and I runned out of ideas... Does anyone here have an idea of whats might happening ?

# Answer
Are you supplying the breadboard from a 5v power source, other than the one that is supplying the Arduino?

Is there any reason why you are using a diode between the button and the arduino pin?

Arduino can sink and source current and with the 10k resistor that diode is just "dropping" some voltage, i would remove it if you really don't have any other use for it.

If you are supplying the PCB with a different power source than the arduino, you have to "join" the 2 grounds, connect the groud from the power source of the PCB to any ground pin of the arduino. if you could take a photo that could help.

Something like this :
> 0 votes

---
Tags: arduino-leonardo, switch, breadboard
---


title: Ubuntu - TinyISP is not recognized

text:
# Question
Title: Ubuntu - TinyISP is not recognized
I got a Pocket AVR Programmer.

https://learn.sparkfun.com/tutorials/pocket-avr-programmer-hookup-guide

I hooked it up on Ubuntu Linux, opened up a sketch in the Arduino IDE, selected `Programmer: USBTinyISP` and then `Upload Using Programmer`.

However, I am getting this error:

```
An error occured while uploading the sketch
avrdude: Warning: cannot open USB device: Permission denied
avrdude: Error: Could not find USBtiny device (0x1781/0xc9f)

```

I even followed this blog post: https://www.krekr.nl/content/using-usbtinyisp-with-ubuntu/ and issued these commands:

In a terminal, type:

```
sudo nano /etc/udev/rules.d/99-USBtiny

```

Then paste

```
SUBSYSTEM=="usb", ATTR{idVendor}=="1781", ATTR{idProduct}=="0c9f", GROUP="adm", MODE="0666"

```

into the new file. Write it out by pressing Ctrl-O.

```
sudo usermod -a -G plugdev YOURUSERNAME
sudo service udev restart
sudo udevadm control --reload-rules

```

However, the problem still remains.

# Answer
> 1 votes
Have you installed the libusb?

> sudo apt-get install libusb-1.0-0-dev

---
Tags: arduino-ide, linux, isp, programmer, ubuntu
---


# Question
Title: With TIMER1 in CTC mode can't get above ~200khz in arduino UNO runnning @ 16MHZ with no prescaller?
I got the following code, and based on the datasheet the Freq should be `clk / 2 * Prescaller * (1 + OCR1A)` making it that if I set the OCR1A to 0, I should get something close to **8Mhz**, but the maximum I can get is **~200kHZ**. Can anyone help me understand why?

In FAST PWM MODE I can reach those speeds, just wanted to know why i can't in CTC MODE.

```
    void setup() {

        DDRB |= (1 << PINB1) ;
        TCCR1A = 0;
        TCCR1B = 0;
        OCR1A = 0;
        TCCR1B |= (1<<CS10) | (1<<WGM12);

        TIMSK1 |= (1<<OCIE1A);
        sei();
    }

    void loop() {

    }

    ISR (TIMER1_COMPA_vect){
        PORTB ^= 1 << PINB1;
    }

```

# Answer
> 2 votes
I disassembled your program. Below is the code for the ISR. Next to each instruction, I wrote the number of CPU cycles it takes, as a comment:

```
; Prologue: save some registers to the stack.
push r1         ; 2
push r0         ; 2
in   r0, 0x3f   ; 1
push r0         ; 2
clr  r1         ; 1
push r24        ; 2
push r25        ; 2

; ISR body: PORTB ^= 0x02;
in   r24, 0x05  ; 1
ldi  r25, 0x02  ; 1
eor  r24, r25   ; 1
out  0x05, r24  ; 1

; Epilogue: restore registers and return.
pop  r25        ; 2
pop  r24        ; 2
pop  r0         ; 2
out  0x3f, r0   ; 1
pop  r0         ; 2
pop  r1         ; 2
reti            ; 4

```

I count a total of 31 CPU cycles, most of them spent in the prologue and epilogue. Then, there is some overhead:

* The CPU always executes at least one instruction of the main program between two interrupts. Given that the main program is in a tight loop containing only two double-cycle instructions, that will take two CPU cycles.
* The CPU takes four cycles to enter interrupt mode: prevent nested interrupts, save the program counter and load the address of the interrupt vector.
* The interrupt vector is a `jmp` instruction that jumps to the ISR. This takes three cycles.

The minimal interrupt period is then given by this sum:

```
 2  one loop instruction
 4  enter interrupt mode
 3  jump to ISR
31  execute ISR
────────────────────────
40  total cycles

```

This takes 2.5 µs, giving an interrupt frequency of 400 kHz. Given that you need two interrupts for a full cycle of the output signal, the maximum you can see on the output is then 200 kHz.

You can save 10 CPU cycles by toggling the pin with:

```
    PINB |= 1 << PINB1;

```

This line compiles to a single double-cycle `sbi` machine instruction. As this instruction doesn't access any CPU registers, you don't need to save and restore `r24` and `r25`. Actually, you don't need to save and restore any register, so you could just remove the prologue, and replace the epilogue by a single `reti` instruction:

```
ISR (TIMER1_COMPA_vect, ISR_NAKED) {
    PINB |= 1 << PINB1;
    asm("reti");  // return from interrupt
}

```

This gives an ISR that executes in six cycles, and the total interrupt period can then be as small as 15 cycles. Beware though, that you should not write a naked ISR unless you are absolutely sure that the code within it will not clobber any CPU register, nor the status register.

---

**Clarification**: On the face of it, the instruction

```
PINB |= 1 << PINB1;

```

seems to mean: “Load `PINB`, do a bitwise OR with `0x02`, then write the result back to `PINB`”. This is, however, not how the compiler interprets it. Instead, it takes it to mean “set bit 1 of register `PINB` to one”. This happens to be a single machine instruction, as `PINB` is a bit-addressable I/O registers.

Yes, the avr-gcc compiler may be a bit peculiar in this respect.

---
Tags: arduino-uno
---


# Question
Title: Why am I getting wrong compass heading using magnetometer readings?
I have been trying to calculate the compass heading using the magnetometer in an MPU9250 sensor. But the result is not making sense to me. I am completely new in this and do not have much understanding in how magnetometers work and just trying to find resources in the internet to make it work. I am calculating the `atan2` of the y and x axis readings of the sensor to find out the angle:

```
float mx = imu.mag_x_ut();
float my = imu.mag_y_ut();
float mz = imu.mag_z_ut();

float heading = atan2(my, mx) * 180 / PI;

Serial.print(mx);
Serial.print(",");
Serial.print(my);
Serial.print(",");
Serial.print(mz);
Serial.print(",");
Serial.println(heading);

```

My understanding is that when the `x` axis of my magnetometer faces the north direction the value of `heading` should be 0, for east 90, south 180 and then for west 270. But my calculations are nowhere near the expected results. I am not even getting a zero reading in any directon. I am attaching the screenshots of the direction reading :

This is when x axis points to north.

Rotated x axis towards east.

x towards south.

x towards west.

I have also added the raw readings from the magnetometer represnted by `mx`, `my` and `mz`. Is something wrong with my sensor or there is some misunderstanding from my part.

EDIT: Readings after hard iron offset compensation.

# Answer
Consider calibrating your magnetometer. Off the shelf, almost all magnetometers require calibration before making use of their data. The offset (commonly referred to as Hard Iron) and the magnitude (commonly referred to as Soft Iron) need to be found for each of the 3 sensors (X, Y & Z) for individual magnetometers.

As there is no accelerometer in this design let us simplify the problem and assume the magnetometer will always be used on a flat surface with its Z axis normal to the surface of the Earth. Let us also assume the X and Y sensors in the magnetometer are perfectly orthogonal to one another.

To calibrate the magnetometer remove metal objects from the local vicinity and avoid large metal object such as cars by 10s of meters. Sample the X and Y sensors many times as these sensors point toward and away from north. Find the maximum and minimum X and Y values.

Find the offset calibration value by adding the minimum and maximum values then divining by 2. Find the magnitude calibration value by arbitrarily picking one axis and adjusting the magnitude of the other to match. Picking X, we subtract the X minimum from the X maximum to find the X range. We do the same for Y to find the Y range. Then we assume the X magnitude calibration value to be 1 and the Y magnitude calibration value to be x-range divided by y-range.

Once calibration is done, to get calibrated X and Y values we subtract the X and Y offset respectively. Then we multiply the offset adjusted Y value by the Y magnitude calibration value.

Note, this type of calibrated compass is difficult to carry around by hand because it may not be held level with the surface of the earth. Also, because the inclination of the magnetic field points deeper into the earth the more one travels away from the equator, it will require re-calibration when traveling to a different latitude.

Calibration calculations based on data in question:

```
X max to min is 42 to -22 so offset is 10 and range is 64
Y max to min is 120 to 48 so offset is 84 and range is 72
So Y magnitude calibration is 64/72 or 0.889

```

Data when sensors are pointed East:

```
Y ~48 & X ~11
bearing = atan2(((48 - Y_offset) * Y_magnitude), ((11 - X_offset) * X_magnitude))
bearing = atan2(((48 - 84) * 0.889), ((11 - 10) * 1))
bearing = atan2(((-36) * 0.889), (1 * 1))
bearing = atan2(-32.004, 1)
bearing = -1.540 rad = -88.236 degrees

```

If instead of -88.236 degrees the value of approximately 90 degrees is desired, change the sign of the Y sensor as part of the calibration process.

The C programming function atan2 is an enhanced form of the math arc tan operation. The C programming function atan2 will calculate to a full 2-Pi circle. To verify how this works use this online atan2 calculator.
> 3 votes

---
Tags: arduino-uno, imu, magnetometer
---


# Question
Title: Read byte and time into EEPROM, then display with a comma between the time and the value?
I have bytes of natural numbers 1-60 coming in at random times:

Example of send data

```
// Uno send

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

  int integersToSend[] = {1, 22, 30, 4, 50};
  for (int i = 0; i < 5; i++)
  {
    Serial.print(integersToSend[i]);  // send as characters
    delay(1000);
  }
}

void loop() {}

```

I want to log the time (any time format) and what value was received into EEPROM:

```
#include <EEPROM.h>

const int timeRefreshDisplay = 30000;
const int EEPROM_SIZE = 100; // Define size of EEPROM available
int addr = 0; // EEPROM address pointer

unsigned long programStartTime;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600); // Initialize Serial1 for data input
  programStartTime = millis(); // Record program start time
}

void loop()
{
  if (Serial1.available())
  {
    int receivedData = Serial1.read();

    if (receivedData != 0 && receivedData <= 60)
    {
      byte receivedValue = receivedData; // Convert?

      // Calculate the timestamp based on program start time
      unsigned long currentTime = programStartTime + millis();

      // Store the received timestamp and value in EEPROM
      EEPROM.put(addr, currentTime);
      addr += sizeof(unsigned long);
      EEPROM.put(addr, receivedValue);
      addr += sizeof(int);
    }
  }

  if (millis() - programStartTime >= timeRefreshDisplay)
  {
    programStartTime = millis();
    displayEEPROMData();
  }
}

void displayEEPROMData() {
  // Display all positions stored in EEPROM
  Serial.println("EEPROM:");

  for (int i = 0; i < EEPROM_SIZE; i += sizeof(unsigned long) + sizeof(int)) {
    if (i >= EEPROM_SIZE) {
      i = 0; // Start reading from the beginning when reaching the end of EEPROM
    }

    unsigned long timestamp;
    int value;
    EEPROM.get(i, timestamp);
    EEPROM.get(i + sizeof(unsigned long), value);

    // Display position data with timestamp in HH:MM:SS format
    Serial.print(String(i / (sizeof(unsigned long) + sizeof(int)) + 1) + ": ");
    Serial.println(String(timestamp) + ", " + String(value));
  }
}

```

Serial monitor

```
EEPROM:
1: 17330, 22272
2: 101, 27943
3: 4143972352, 116
4: 0, 0
5: 0, 0
6: 0, 0
7: 0, 0
8: 0, 0
9: 0, 0
10: 0, 0
11: 0, 0
12: 0, 0
13: 0, 0
14: 0, 0
15: 0, 0
16: 0, 0
17: 0, 0

```

I'm not quite sure how it is reading data into EEPROM. That has to be where the issue is. I just don't know how to fix it. I tried clearing out the memory:

```
    #include <EEPROM.h>

    void setup() {
       // initialize the LED pin as an output.
       pinMode(13, OUTPUT);

       for (int i = 0 ; i < 22; i++) /*EEPROM.length()*/
          EEPROM.write(i, 0);

       // turn the LED on when we're done
       digitalWrite(13, HIGH);
    }

    void loop() {}

```

Serial monitor again

```
EEPROM:
1: 0, 0
2: 0, 0
3: 0, 0
4: 0, 4
5: 70, 1
6: 22, 3
7: 230, 2
8: 182, 4
9: 134, 50
10: 234, 49
11: 209, 50
12: 213, 50
13: 185, 51
14: 189, 48
15: 161, 52
16: 137, 53
17: 140, 48

```

I'm using a Leonardo to receive.

# Answer
> 0 votes
This works.

```
#include <EEPROM.h>

const int EEPROM_SIZE = 100; // Define size of EEPROM available
int addr = 0; // EEPROM address pointer

unsigned long programStartTime;

void setup()
{
  Serial.begin(9600);
  while (!Serial);
    Serial1.begin(9600);

  programStartTime = millis(); // Record program start time

  // Initialize EEPROM data
  //  for (int i = 0; i < EEPROM_SIZE; i++) {
  //    EEPROM.write(i, 0);
  //  }
  displayEEPROMData();
}

void loop()
{
  if (Serial1.available())
  {
    int receivedData = Serial1.read();

    if (receivedData >= 1 && receivedData <= 60)
    {
      byte receivedValue = static_cast<byte>(receivedData); // Convert to byte

      // Calculate the timestamp based on program start time
      unsigned long currentTime = millis() - programStartTime;

      // Store the received timestamp and value in EEPROM
      EEPROM.put(addr, currentTime);
      addr += sizeof(currentTime);
      EEPROM.put(addr, receivedValue);
      addr += sizeof(receivedValue);

      displayEEPROMData();
    }
  }

  if (addr >= EEPROM_SIZE) {
    addr = 0; // Wrap around if the EEPROM is full
  }

}

void displayEEPROMData() {
  // Display all positions stored in EEPROM
  Serial.println("EEPROM:");

  for (int i = 0; i < EEPROM_SIZE; i += sizeof(unsigned long) + sizeof(byte)) {
    unsigned long timestamp;
    byte value;
    EEPROM.get(i, timestamp);
    EEPROM.get(i + sizeof(timestamp), value);

    // Display position data with timestamp in HH:MM:SS format
    Serial.print(String(i / (sizeof(unsigned long) + sizeof(byte)) + 1) + ": ");
    Serial.println(String(timestamp) + ", " + String(value));
  }
}

```

---
Tags: serial
---


# Question
Title: How to create minimal web server example with a dropdown menu?
I want to create a three-item menu: Verizon, T-Mobile, AT&T. Since the example uses LEDs, I'll do the same--except with a dropdown menu to select among the three.

I'm trying to combine these two examples:

1. https://randomnerdtutorials.com/esp8266-web-server
2. https://www.w3schools.com/html/tryit.asp?filename=tryhtml\_elem\_select

Except with phone carriers instead of cars:

I'm struggling on the polyglot part of the programming, combining the HTML and Arduino program in the middle:

```
        // Web Page Heading
        client.println("<form action='/action_page.php'>");
        client.println("  <select id='providor' name='providor'>");
        client.println("    <option value='verizon'>Verizon</option>");
        client.println("    <option value='tmobile'>T-Mobile</option>");
        client.println("    <option value='atnt'>AT&T</option>");
        client.println("  </select>");
        client.println("  <input type='submit'>");
        client.println("</form>");

        if (providor==verizon)
          client.println("<p>Provider Selected: Verizon</p>");
        else if (providor==tmobile)
          client.println("<p>Provider Selected: T-Mobile</p>");
        else if (providor==atnt)
          client.println("<p>Provider Selected: AT&T</p>");

```

Here is the rest of the program:

```
/*

Based from
https://randomnerdtutorials.com/esp8266-web-server

HTML tool
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_elem_select
*/

#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
//String output5State = "off";
//String output4State = "off";

// Assign output variables to GPIO pins
const int output5 = 14;    // D5 verizon
const int output6 = 12;    // D6 tmobile
const int output7 = 13;    // D7 atnt

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output6, OUTPUT);
  pinMode(output7, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output6, LOW);
  digitalWrite(output7, LOW);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop()
{
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    currentTime = millis();
    previousTime = currentTime;
    while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") >= 0)
            {
              Serial.println("D5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            }
            else if (header.indexOf("GET /5/off") >= 0)
            {
              Serial.println("D5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            }
            else if (header.indexOf("GET /6/on") >= 0)
            {
              Serial.println("D6 on");
              output4State = "on";
              digitalWrite(output6, HIGH);
            }
            else if (header.indexOf("GET /6/off") >= 0)
            {
              Serial.println("D6 off");
              output4State = "off";
              digitalWrite(output6, LOW);
            }
            else if (header.indexOf("GET /7/on") >= 0)
            {
              Serial.println("D7 on");
              output4State = "on";
              digitalWrite(output7, HIGH);
            }
            else if (header.indexOf("GET /7/off") >= 0)
            {
              Serial.println("D7 off");
              output4State = "off";
              digitalWrite(output7, LOW);
            }
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #77878A;}</style></head>");

            // HERE
            // ↓
            // ↓
            // ↓
            // ↓

            // Web Page Heading
            client.println("<form action='/action_page.php'>");
            client.println("  <select id='provider' name='providor'>");
            client.println("    <option value='verizon'>Verizon</option>");
            client.println("    <option value='tmobile'>T-Mobile</option>");
            client.println("    <option value='atnt'>AT&T</option>");
            client.println("  </select>");
            client.println("  <input type='submit'>");
            client.println("</form>");

            if (providor==verizon)
              client.println("<p>Provider Selected: Verizon</p>");
            else if (providor==tmobile)
              client.println("<p>Provider Selected: T-Mobile</p>");
            else if (providor==atnt)
              client.println("<p>Provider Selected: AT&T</p>");

            // ↑
            // ↑
            // ↑
            // ↑

            client.println("</body></html>");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

```

Any suggestions or solutions on how to change or the correct code?

# Answer
> 0 votes
First thing: be careful with matching your quotes. Every string literal should be written as `"bla, bla, bla"`, with no unescaped double-quotes in between. Do use the syntax highlighting: it is here precisely for helping you spot this kind of trivial programming mistakes. Also, for writing very long constant strings, use the C++ “raw string literal” feature: it just makes this easier.

Second thing, you should understand how a form submission works at the HTTP level. You should be able to find the info on the Web but, to make it short, when the user clicks on your form, the browser will send a request looking like

```
GET /action_page.php?providor=verizon HTTP/1.1
Some-Header-Name: some header value
Other-Header-Name: other header value
...

```

You should parse this to find the actual provider between the `'='` character and the following space. Also, get rid of `action_page.php`, it is useless here.

Then a few random remarks:

* Do not write “providor”: the correct spelling is “provider” (although you may prefer “carrier” in this context).
* Within an HTML document, the ampersand should be written `&`.
* The HTML page needs a `<title>` element to be valid.
* Remove the whole section of the code titled “turns the GPIOs on and off”: it does not make sense in your context.

Now, to illustrate these points, here is how I would code parsing the request:

```
// Find the provider in the URL.
String provider;
const String provider_before = "GET /?provider=";
int request_begin = header.indexOf(provider_before);
if (request_begin < 0) {
    provider = "unknown";
} else {
    int provider_begin = request_begin + provider_before.length();
    int provider_end = header.indexOf(' ', provider_begin);
    provider = header.substring(provider_begin, provider_end);
}

```

And here is how I would send the page to the client:

```
// At the beginning of the sketch (in global context).
const char page_before_provider[] = R"rawstr(<!DOCTYPE html>
<html>
<head>
<title>Phone carrier selection</title>
[...]
<p>Provider Selected: )rawstr";
const char page_after_provider[] = "</p>\n</body>\n</html>\n";

// At the place where the page has to be sent.
client.print(page_before_provider);
if (provider == "verizon")
    client.print("Verizon");
else if (provider == "tmobile")
    client.print("T-Mobile");
else if (provider == "atnt")
    client.print("AT&T");
else
    client.print(provider);
client.print(page_after_provider);

```

# Answer
> 0 votes
Apart from the syntax errors (you aren't matching double quotes in multiple places) web pages don't work like that.

To do something like your form you:

1. Send the form, more-or-less like you have.
2. > ```
>    if (providor==verizon)
>        client.println("<p>Providor Selected: Verizon</p>");
>
> ```

You can't test the providor (provider?) right there. Do you mean `if (providor=="verizon")`?
3. The form has to be sent to the client, the user has to fill it in, and send it back. Thus you can't test for what they filled in a line or so under sending the form.

So, testing for what they entered is a subsequent step. It's a little hard to explain without taking dozens of paragraphs. I suggest reading up on how web forms work.

---

Here's an analogy:

Say you want to write to a company and apply for a job. You fill in a form and send it off. You do not, a moment later, check to see if you got the job. The form has to go to the company. Someone has to process it. Then they make a reply. The reply might say "in reference to your job application of 11 September 2023 you were/were not successful."

It's like that with HTML. The form, which the user fills in, is the initial step. Then the user fills it in. That might be an hour later. Then they press Send and the reply comes back to you. *That's* when you process the reply.

---
Tags: esp8266
---


# Question
Title: Why is my LED strip value always equal to 255 on my potentiometer?
I'm pretty new to Arduino and this is my first project I'm working on and I'm really struggling with why my code isn't working properly.

The LED strip should be able to adjust the colour with one potentiometer that I can take out to so I don't use 3 potentiometers and just use that can adjust all colours. Then once it's on mode 4 it should keep the colour and blink repeatedly.

I'm using an Arduino Uno but once my project if finished I'll use the Arduino Nano. I don't know if I'll need to change the code but if I do I think I could do that on my own.

I just don't know why my LED strip is always stuck on off (255).

```
// set pin numbers:
int ledPinR = 11; // the number of the LED R pin
int ledPinG = 10; // the number of the LED G pin
int ledPinB = 9; // the number of the LED B pin
int buttonPin = 7; // the number of the push button pin
int mode = 0; //to change the mode
int bluelev = 0; //save the blue led value
int greenlev = 0; //save thegreen led value
int redlev = 0; // save the red led value

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPinR, OUTPUT);
  pinMode(ledPinG, OUTPUT);
  pinMode(ledPinB, OUTPUT);

  //make the led strip white at boot
  digitalWrite(ledPinR, 0);
  digitalWrite(ledPinG, 0);
  digitalWrite(ledPinB, 0);
}

void loop() {
  // when the button is pressed changes the mode value by one
  if (digitalRead(buttonPin) == LOW) {
    ++mode;
    delay(500);
  }

  if (mode == 1) { //red config
    int adcValue; // Define a variable to save the ADC value
    // Convert analog of A0 port into digital, and work as PWM duty cycle of ledPinR port
    adcValue = analogRead(A0);
    analogWrite(ledPinR, map(adcValue, 0, 1023, 0, 255));
    (redlev = ledPinR); // saves the red led level
  }

  if (mode == 2) { //green config
    int adcValue; // Define a variable to save the ADC value
    // Convert analog of A1 port into digital, and work as PWM duty cycle of ledPinG port
    adcValue = analogRead(A1);
    analogWrite(ledPinG, map(adcValue, 0, 1023, 0, 255));
    (greenlev = ledPinG); // saves the green led level
  }

  if (mode == 3) { //Blue config
    int adcValue; // Define a variable to save the ADC value
    // Convert analog of A2 port into digital, and work as PWM duty cycle of ledPinB port
    adcValue = analogRead(A2);
    analogWrite(ledPinB, map(adcValue, 0, 1023, 0, 255));
    (bluelev = ledPinB); // saves the blue led level
  }

  if (mode == 4) {
    digitalWrite(ledPinR, 255); // switch off LED
    digitalWrite(ledPinG, 255); // switch off LED
    digitalWrite(ledPinB, 255); // switch off LED
    digitalWrite(8, 0); // switch on LED
    delay(1000); //wait 1 second
    digitalWrite(ledPinR, redlev); // switch on LED
    digitalWrite(ledPinG, greenlev); // switch on LED
    digitalWrite(ledPinB, bluelev); // switch on LED
    digitalWrite(8, 225); // switch on LED
    delay(1000); //wait 1 second
  }

  if (mode == 5) {
    mode -= 5; //sets the mode value back to 0
  }
}

```

Here is the setup.

Pretend the RGB LED is a LED strip and the potentiometers are just slots for one to be put in to change the colour when I want to. So when I'm not changing the colours I can use the potentiometer for other projects and not waste 3.

# Answer
> 1 votes
There are at least these errors in your code:

**1. You cannot read back the analog value set to a pin.**

You try this:

```
    analogWrite(ledPinR, map(adcValue, 0, 1023, 0, 255));
    (redlev = ledPinR); // saves the red led level

```

You correctly set the analog value at the pin for the red LED. But then you try to read it back. Look at the definition of `ledPinR`: It is an `int` with the fixed value of 11. So `redlev` is always 11.

*Note 1: The output is not really analog, but pulse width modulated.*

*Note 2: You don't need the parentheses in the second statement.*

Instead, store the mapped value in `redlev`:

```
    redlev = map(adcValue, 0, 1023, 0, 255);
    analogWrite(ledPinR, redlev);

```

*Note 3: Use good variable names, like `redLevel`. Some time or later you will confuse things because of abbreviated names.*

**2. You are not repeating the analog write in mode4.**

You wrote this, which is apparently wrong:

```
  if (mode == 4) {
    digitalWrite(ledPinR, 255); // switch off LED
    // other statements...
    delay(1000); //wait 1 second
    digitalWrite(ledPinR, redlev); // switch on LED
    // other statements...
    delay(1000); //wait 1 second
  }

```

Instead you want this (if 255 is really "off"):

```
  if (mode == 4) {
    analogWrite(ledPinR, 255); // switch off LED
    // other statements...
    delay(1000); //wait 1 second
    analogWrite(ledPinR, redlev); // switch on LED
    // other statements...
    delay(1000); //wait 1 second
  }

```

There are more issues, but this will take you a step forward. Most important, keep an indentation style, I cleaned up your source in the question to make it readable.

# Answer
> -1 votes
My first project was also the same, to set the strip color with one potentiometer. I used the function getColorValue, that returns you a Struct. This struct contains the value for red, green, and blue. Here is the example code:

```
#define PIN_POTENTIOMETER A0

struct RGB
{
    uint8_t red;
    uint8_t green;
    uint8_t blue;
} color;

RGB getColorValue(uint16_t inputValue);

void setup()
{
    Serial.begin(9600);
    pinMode(PIN_POTENTIOMETER, INPUT);
}

void loop()
{
    uint16_t inputValue = analogRead(PIN_POTENTIOMETER);
    color = getColorValue(inputValue);

    Serial.print("R: ");
    Serial.print(color.red);
    Serial.print(" G: ");
    Serial.print(color.green);
    Serial.print(" B: ");
    Serial.println(color.blue);
    delay(100);
}

RGB getColorValue(uint16_t inputValue)
{
    RGB color;
    color.red = 0;
    color.green = 0;
    color.blue = 0;

    map(inputValue, 0, 1023, 0, 255);

    if (inputValue <= 42.5)
    {
        color.red = 255;
        color.green = inputValue * 6;
        color.blue = 0;
    }
    else if (inputValue <= 85)
    {
        color.red = 255 - (inputValue - 43) * 6;
        color.green = 255;
        color.blue = 0;
    }
    else if (inputValue <= 127.5)
    {
        color.red = 0;
        color.green = 255;
        color.blue = (inputValue - 85) * 6;
    }
    else if (inputValue <= 170)
    {
        color.red = 0;
        color.green = 255 - (inputValue - 127.5) * 6;
        color.blue = 255;
    }
    else if (inputValue <= 212.5)
    {
        color.red = (inputValue - 170) * 6;
        color.green = 0;
        color.blue = 255;
    }
    else if (inputValue <= 255)
    {
        color.red = 255;
        color.green = 0;
        color.blue = 255 - (inputValue - 212.5) * 6;
    }

    return color;
}

```

If you need any further help, you can comment here or contact me directly with my mail in the bio.

Regards Dario

---
Tags: arduino-uno, potentiometer, led-strip
---


title: ATTINY 85 - use host laptop's internet

text:
# Question
Title: ATTINY 85 - use host laptop's internet
Suppose I enable USB tethering (internet) on my laptop. Will it be possible to use that internet on an ATTINY 85 connected to USB.

# Answer
> 1 votes
No, the attiny85 is simply too slow and not powerful enough to process your laptop's internet connection and begin something with it. If you only have to make API Request, you can hard code them into the firmware, and send the api-request-string to your computer, make your computer execute the API-request and then send the API response from the computer to the attiny to process the response there.

Regards

Dario

---
Tags: attiny, attiny85
---


# Question
Title: Arduino Pro Micro not recognizing INPUT or INPUT_PULLUP
I tried to make a controller box with multiple `buttons`. Sadly, when I tried to connect the buttons, the `Arduino Pro Micro` didn't recognize them being pressed. I even tried to connect a wire directly (and a directly a resistor from GND to the ports) from GND to the ports but it doesn't seem to matter.

`OUTPUT works` on the same ports, but `INPUT/INPUT_PULLUP` does not. Is there something wrong with the code?

My `Arduino Pro Micro` is a Chinese knockoff. Keyboard and Mouse are working, OUTPUT is working. It doesn't seem to work with the input.

PS: I have worked with Arduino UNO before (and also the ESP family (ESP8266, ESP32)).

PS2: Sometimes, if I touch the microcontroller's back side some values register (like I pushed all the buttons at once)

```
#define LED_PIN 4
#define BUTTON_1 10
#define BUTTON_2 16
#define BUTTON_3 14
#define BUTTON_4 9

byte ledState = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_1, INPUT_PULLUP);
  pinMode(BUTTON_2, INPUT_PULLUP);
  pinMode(BUTTON_3, INPUT_PULLUP);
  pinMode(BUTTON_4, INPUT_PULLUP);
}

void loop() {

  byte one = digitalRead(BUTTON_1);
  byte two = digitalRead(BUTTON_2);
  byte three = digitalRead(BUTTON_3);
  byte four = digitalRead(BUTTON_4);

  if (one == HIGH) {
    Serial.println("BUTTON_1");
  }
  if (two == HIGH) {
    Serial.println("BUTTON_2");
  }
  if (three == HIGH) {
    Serial.println("BUTTON_3");
  }
  if (four == HIGH) {
    Serial.println("BUTTON_4");
  }

  digitalWrite(LED_PIN, ledState);
  ledState = !ledState;
  delay(1000);
}

```

Edit: corrected the code

Mention: I wired the buttons the following way (I have to mention it, because the Arduino Pro Micro doesn't have a sepparate 3V/5V pin, it only has RAW output that by my undertanding can fry the board)

Tutorial from where I inspired the button wiring: https://arduinogetstarted.com/tutorials/arduino-button

# Answer
The way you have it wired, INPUT\_PULLUP will make the buttons look HIGH, so in your code you need to test if they are going LOW, which is what grounding the button would do.
> 1 votes

# Answer
After looking at many tutorials and trying many approaches with different Arduinos (Uno, because it's easyer to prototype) (and taking a short brake so I can try again from 0 with a new mindset) I made it work.

Before, I could do it because I was using Microcontrollers that had a 3/5V output also (ex. Uno, Mega, Nano, STM32, ESP8266, ESP32), so I could do a pull-up/down circuit, but because the Arduino Micro doesn't have such pins (it has only RAW as output, which can fry the board if it's externally powered) I had to use this method where I only use a GND pin and a Digital Input without any ressistors wired to the button.

Thanks for the answers and suggestions!

The new code (without the LED functionality):

```
#include "Keyboard.h"

// defining button pin numbers
// TODO: rename variables according to functionality
#define BUTTON_10 10
#define BUTTON_16 16
#define BUTTON_14 14
#define BUTTON_9 9

// giving them a first-state of HIGH
int previousButtonState10 = HIGH;
int previousButtonState16 = HIGH;
int previousButtonState14 = HIGH;
int previousButtonState9 = HIGH;

void setup() {
  // initializing the buttons as INPUTS with PULLUP (internal pull-up resistor from Arduino)
  pinMode(BUTTON_10, INPUT_PULLUP);
  pinMode(BUTTON_16, INPUT_PULLUP);
  pinMode(BUTTON_14, INPUT_PULLUP);
  pinMode(BUTTON_9, INPUT_PULLUP);

  // only for test
  // TODO: Move this only to the function needed when more functionality is added
  Keyboard.begin();

}

void loop() {
  // checking if any of the buttons were pressed and saving the state in a variable
  previousButtonState10 = checkButton(BUTTON_10, previousButtonState10);
  previousButtonState16 = checkButton(BUTTON_16, previousButtonState16);
  previousButtonState14 = checkButton(BUTTON_14, previousButtonState14);
  previousButtonState9 = checkButton(BUTTON_9, previousButtonState9);
}

// function: reads the button state and compares it with the previous state to find out if it was pressed or not
// params: buttonPin => the pin number of the button; previousButtonState => the state corresponding for each button
// return: it returns the red state, so it can be saved as previousState in the coresponding parameter
int checkButton(int buttonPin, int previousButtonState) {
  int buttonState = digitalRead(buttonPin);

  if (buttonState == LOW && previousButtonState == HIGH) {
    Keyboard.println(buttonPin);
    // some minimal debouncing
    // TODO: WIll be a problem when using millis() in the future
    delay(50);
  }

  if (buttonState == HIGH && previousButtonState == LOW) {
    // not needed, but some functionality could be added in the future
    // Keyboard.println("release");
    delay(50);
  }

  return buttonState;
}

```

Now I can work further on improving and extending the code to make the "Macro Board" project with mouse movement (and I also have to solder the buttons and LEDs to the board :P )
> 0 votes

---
Tags: button, arduino-leonardo, arduino-pro-micro, pull-up
---


# Question
Title: Is there an Arduino library that uses ARP to get list of connected devices on network?
I have been looking for a library that can execute an ARP (Address Resolution Protocol) command to return a list of connected devices on the network. The idea is that it would send the request to the gateway and get a list of MAC addresses of currently connected devices as a sort of "who's home" request.

I have searched around Arduino's libraries and have not found any that specifically perform this type of functionality so I was hoping that maybe it was available in a function within a broader networking library.

The particular networking interface (wifi via ESP8266/ESP32 or Ethernet) does not matter as I have not chosen a specific board for the job yet. I'm interested in any library solution that would allow me to poll the gateway to see which devices are currently online without having to buy a special device like FingBox.

Any recommendations for a library that includes this functionality or an approach that would allow me to send ARP commands over the network?

# Answer
> 3 votes
ARP isn't generally used the way you described. Per the spec, to resolve an IP address into a MAC address, you broadcast an ARP request for the IP address, and receive a unicast response from the host whose address it is - not a router. It also only resolves a single IP address in one request; it doesn't return the contents of the entire ARP cache.

While you could potentially unicast ARP requests to a router, it's anybody's guess as to whether the router would respond - it's not required to. By spec only the computer who's IP address is being queried should respond - so a router should not unless you've sent it an ARP request for its IP address. You'd also have to send one request for each IP address in the range specified by the LAN's network mask.

You're better off using SNMP, if the router supports it. SNMP can read the router's entire ARP cache with very little overhead (and very few packet exchanges).

The are SNMP implementations for the ESP32 and ESP8266, but they're likely to be difficult to use. Googling will find them for you.

# Answer
> 1 votes
I was searching for the same function but I think you don't need to query the gateway.

My idea is to loop through all the valid ip addresses, send a ping to each one (it does not matter if they don't answer the ping), and we should have the MAC for this ip. Then check if this MAC is in a list saved in some non volatile space (may be an sd card) and if it's not in the "known peers" list, add it and send a message warning about a new device added to the network. Using the MAC address instead of the ip for identifying the devices should avoid problems with dynamic ips recognized as new.

---
Tags: esp8266, wifi, ethernet, esp32
---


# Question
Title: Is there a way to increase the number of output pins in Arduino Uno?
I am an amateur. I know about Arduino, but I am still learning.

And I was making this Bluetooth rover with a camera, ultrasonic sensor, mecanum wheels, air-soft shooter, and sand sample collector. I am using two L298 motor drivers, because L23D requires soldering and is a bit less compatible with me. So, when creating this amazing robot I realised that I ran out of pinmode spaces for the air-cannon and some other features.

So, is there a way to increase the number of output pins in an Arduino Uno or can I connect the Rx and Tx pins of the Bluetooth module and the trig and echo pin and use them both as one for two more spaces?

# Answer
> 4 votes
As an extension to Dario.Casciato’s response, there are not only I²C I/O expanders, but also the simple 74HC595 IC, which can be cascaded and used via Arduino's shiftOut function. It needs three signal pins for 8 / 16 / 24 ... outputs.

The link is not a purchase recommendation, but rather a technical hint.

# Answer
> 3 votes
It sounds like you are using some GPIOs ;) If you need more digital pins, you can use the analog pins as digital pins (if you didn't already).

If you already occupied these pins, then I would think about getting an I/O expander. It's a chip/IC that can be mostly controlled via I²C, offering you a way to scale your project's GPIO capabilities.

# Answer
> 3 votes
What you probably want is called an ‘I/O Expander’. They come in many different varieties based both on exact means you use to communicate with them, how many I/O pins they give you, and what you can do with those pins.

The usual recommendation for use with an Arduino is an I²C based I/O expander, such a Microchip MCP23017 (available readily online from many sources and available in a DIP format so that you can use it with solderless breadboards), because this provides a reasonably fast interface that is very well supported on the Arduino and uses relatively few pins (only 2 pins are required, not counting Vcc and ground).

I’ve also personally used a Analog Devices DS2408 for this purpose before. It uses a 1-Wire interface, cutting the required pins down to only 1 not counting Vcc and ground, and also not actually requiring the use of a specific I/O pin like a proper I²C device would, but it’s also slower and not as nice to work with (you need a separate library to work with 1-Wire on most Arduino chips), and also only comes in SOIC packages (so requires some precise, but not necessarily difficult, soldering).

In theory you could also use an SPI I/O expander, but they are often a bit more of a pain to work with, and eat at last three pins (possibly four) other than Vcc and ground.

---

In theory, there are two other options in specific circumstances.

The first is a multiplexer chip, which is essentially a fancy solid-state switch with multiple outputs. These are only really practical if you just need to trigger external devices individually, though that may be viable for your use case (it could easily drive a simple level trigger for the airsoft gun and a simple edge trigger for the sand sample collector).

The second is to use a shift register. These are only viable if you have some way to latch outputs (for example, putting a gated D-latch on each output) or only need the outputs to be valid at specific points in time, because updating the outputs cycles each pin through the output values of each other pin. They’re great if you are doing something like implementing a parallel bus, but not as good if you need fast outputs that retain state.

---
Tags: arduino-uno
---


# Question
Title: Arduino Servo with temperature sensor (TMP36)
The essence of the program is to measure the temperature, and if the temperature is higher than 26 degrees, the servo rotates by 45 degrees, and if it's lower, it rotates by 179 degrees. However, a short circuit is occurring. At the moment of the first servo rotation, the temperature jumps to 40 degrees (the temperature is calculated from voltage), and after that, the servo continuously rotates back and forth because the temperature is fluctuating between 40 and 20 degrees. What could be the cause of this issue?

My code:

```
#include <Servo.h>
Servo myServo;
const int sensorPin = A0;
const float baselineTemp = 20.0;
int angle;
void setup() {
  myServo.attach(9);
  Serial.begin(9600);
}

void loop() {
  int sensorVal = analogRead(sensorPin);
  Serial.println("Sensor Value: ");
  Serial.print(sensorVal);
  float voltage = (sensorVal/1024.0) * 5.0;
  Serial.println("Volts:");
  Serial.print(voltage);
  Serial.println("Celcius:");
  float temperature = (voltage - .5) * 100;
  Serial.print(temperature);
  if (temperature < baselineTemp) {
    myServo.write(179);
  } else {
    myServo.write(45);
  }
  delay(800);
}

```

Output in terminal:

```
sensorVal: 149
 Volts:0.73
 Celcius:22.75
 sensorVal: 192
 Volts:0.94
 Celcius:43.75
 sensorVal: 154
 Volts:0.75
 Celcius:25.20
 sensorVal: 188
 Volts:0.92
 Celcius:41.80
 sensorVal: 150
 Volts:0.73
 Celcius:23.24
 sensorVal: 184
 Volts:0.90
 Celcius:39.84
 sensorVal: 151

```

# Answer
You need to power the servo through a separate power supply. High power devices such as motors etc. should not be powered via the Arduino's regulator. That is surely affecting the analogRead() and therefore also the temperature reading as already noted by @jsotola.

Secondly, you need to add some hysteresis here to prevent continuous thrashing when the temperature is around the baseline:

```
if (temperature < baselineTemp) { myServo.write(179); }
else { myServo.write(45); }

```

Maybe try something like :

```
if (temperature < baselineTemp - 1.0 ) { myServo.write(179); }
elseif (temperature > baselineTemp + 1.0 ) { myServo.write(45); }

```

You could also try adding a capacitor across the power rails of the temperature sensor say 10uF very close to the sensor itself.
> 1 votes

---
Tags: arduino-uno, servo, temperature-sensor
---


# Question
Title: convert string representing a binary number to binary
I have a serial input "1111111" and I would like to convert this to a binary B1111111 that I can send to a led matrix.

I tried to search, but, all the results were misleading, led to full text to binary conversion. Please advise.

edit: This is my sample code where I am missing a step in the conversion part

```
LedControl mat = LedControl(DIN_PIN, CLK_PIN, CS_PIN, MAX_SEG); // MAX7219
void OneLine() {

//input
char text[] = "11111110";
//convert to binary number somehow

//show one line
      mat.setRow(0, 0, convertednr);
}

```

# Answer
As pointed out by @EdgarBonet, I can convert the string to binary number with `strtoul()` and pass this to my led control. Adding this as an answer for future readers:

```
 LedControl mat = LedControl(DIN_PIN, CLK_PIN, CS_PIN, MAX_SEG); // MAX7219
void OneLine() {

//input
char text[] = "11111110";
//convert to number
uint32_t convertednr = strtoul(text, NULL, 2);
//print out
mySerial.println(convertednr);

//show one line
      mat.setRow(0, 0, convertednr);

```
> 1 votes

---
Tags: serial, programming, c++
---


title: Upload to ESP32-C3 fails

text:
# Question
Title: Upload to ESP32-C3 fails
I have built a custom circuit board using the ESP32-C3-MINI-1-H4 module (datasheet).

Here is a schematic:

I have the GND, Tx, and Rx lines hooked up to an Arduino Uno without the ATmega. The 3.3 V comes from an external power supply.

I have successfully put the chip into download mode (as shown from the serial output below).

> ESP-ROM:esp32c3-api1-20210207
>
> Build:Feb 7 2021
>
> rst:0x1 (POWERON),boot:0x5 (DOWNLOAD(USB/UART0/1))
>
> waiting for download

I attempted to upload an example sketch using the following settings (Arduino IDE).

I held down the reset button (S4) until the Rx light on the Uno started flashing.

It works about 5% of the time, but 95% of the time it ends in this:

> A fatal error occurred: Failed to connect to ESP32-C3: No serial data received.

I'm not sure how that is possible, as the serial data appears on the oscilloscope, and it is clearly in download mode as shown by the serial output.

I have tried removing the voltage divider from the RX line, but that didn't help. Is there any way to make uploading more consistent?

# Answer
> 1 votes
You must be in flash mode DIO and watch the "USB CDC on boot" which must be on if you use native C3 usb and off if you use an external usb-serial converter.

You can upload OK in QIO mode but program wont start, that is EXACTLY what OP is asking.

---
Tags: arduino-ide, esp32, upload
---


title: blink a Grove - RGB LED Stick

text:
# Question
Title: blink a Grove - RGB LED Stick
I am trying to blink a Grove - RGB LED Stick (10 - WS2813 Mini 3535) with this code:

```
#include "FastLED.h"

int ledState = LOW;       // ledState used to set the LED
long previousMillis = 0;  // will store last time LED was updated
long interval = 1000;     // interval at which to blink (milliseconds)

#define NUM_LEDS 10
CRGB myLeds[NUM_LEDS];

void setup() {
  FastLED.addLeds<NEOPIXEL, 4>(myLeds, NUM_LEDS);
}

void loop() {
  unsigned long currentMillis = millis();
  FastLED.setBrightness(25);

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::White;
        FastLED.show();
      }
    } else {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::Black;
        FastLED.show();
      }
    }
  }
}

```

Any idea why it does not blink?

Thanks

# Answer
> 1 votes
In your code, you define the global variable `ledState` and initialize it to the value "LOW".

In the `loop()` function, the `ledState` variable is used to determine the (next) state of the LED once every 1000 milliseconds, like this:

```
...
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::White;
    FastLED.show();
  }
} else {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::Black;
    FastLED.show();
  }
}
...

```

However, since your code does not change value of `ledState` to reflect the new state of the LED array, the next time the above `if (...)` comparison is run, the outcome is the same and the color of the LEDs not be changed.

The simplest change to make your LEDs blink as you intended, would be to change the above piece of code to the following:

```
...
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::White;
    FastLED.show();
    ledState = HIGH;
  }
} else {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::Black;
    FastLED.show();
  }
  ledState = LOW;
}
...

```

An alternative (arguably more elegant) solution would be to declare `ledState` as a boolean (true/false) variable so that you can further simplify your code:

```
#include "FastLED.h"

bool ledState = false;    // ledState used to set the LED
long previousMillis = 0;  // will store last time LED was updated
long interval = 1000;     // interval at which to blink (milliseconds)

#define NUM_LEDS 10
CRGB myLeds[NUM_LEDS];

void setup() {
  FastLED.addLeds<NEOPIXEL, 4>(myLeds, NUM_LEDS);
}

void loop() {
  unsigned long currentMillis = millis();
  FastLED.setBrightness(25);

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (!ledState) {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::White;
        FastLED.show();
      }
    } else {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::Black;
        FastLED.show();
      }
    }
    ledState = !ledState;    // make ledState reflect the new LED state

  }
}

```

---
Tags: led
---


# Question
Title: Is the EEPROM the best alternative for store non-volatile values with Arduino?
SD-cards are capable of store values even if it is turned off.

I don't know what is the time that a EEPROM can keep a value in it's memory, but of course are better than the volatile memory.

There are some others ways of store non-volatile values for arduino?

Which of these need hardware built-in and which doesn't?

Are the EEPROM the best alternative (in terms of facility, durability, and cost) for store non-volatile values when we talk about Arduinos (or even microcontrollers in general)?

# Answer
EEPROM on the Atmega328P (such as on the Arduino Uno) holds 1KB (1024 bytes) and has a documented write/erase cycle of 100,000 writes.

So, if your application only needs to store 1024 bytes in a non-volatile way, and you do not plan to write more than 100,000 times then that is suitable.

The sort of things I would use EEPROM for are remembering settings (eg. fan speed, oven temperature, a password for accessing WiFi, that sort of thing).

I also personally use it for "remembering" RFID card codes for access to my house. In my experience, using it for that purpose, it has never "forgotten" a code. According to the datasheet it will retain data for 100 years at 25°C.

It is convenient because you don't need any extra hardware.

---

Other alternatives are SPI or I2C based external EEPROM, such as NVRAM (non-volatile RAM) which would have larger capacity, but you would need to connect it. That would likely be about 5 wires and somewhere to put the chip. An example of that is Adafruit I2C FRAM Breakout.

---

You could use a micro-SD card, which I have used on another project to record temperature readings every 15 minutes. This has a lot more capacity than EEPROM, and then you can just take the SD card out and read it in an ordinary PC. This needs extra hardware (eg. a holder for the SD card and possibly voltage-level shifters). However you can buy that for around $20, and it is easy enough to hook up.

---

I don't know how SQL got into the discussion under the question, but that is a language (Structured Query Language) and not a piece of hardware.

---

Another alternative, if you don't particularly want portability, is to send your data along a connection to your PC, and record the data there. Conceivably WiFi could be used for that.

---

## Speed

Speed-wise, I would say EEPROM is the fastest because it is natively inside the chip. Other alternatives required sending messages along wires (I2C, SPI, or maybe USB) to somewhere else and that takes time.

Writing is slower than reading, because writing involves using electricity to make a chemical change in the chip (turning a 1-bit into a 0-bit) but it is still quite fast.
> 2 votes

---
Tags: eeprom
---


title: Turn on by long press of a button?

text:
# Question
Title: Turn on by long press of a button?
In my project on Arduino, I want to implement turning on the whole circuit by long press of a button.

But at the same time, I want the Arduino to be turned off in standby or sleep mode, but I don't know how to wake it up then.

Can you please advise me how this can be realized?

# Answer
You can use a circuit like this to get close to what you want to achieve.

Found on: https://forum.arduino.cc/t/switch-microcontroller-on-and-off-with-a-button-and-mofset/1047044

It is a latching circuit with the special property that you can use the same button to power up the Arduino and later when the Arduino is running, test the button in code.

It works like this. If the Arduino is powered off, pressing the button powers up the Arduino. Your program will immediately (or after a specific chosen interval) switch on D6. This sustains the latch.

Now in your code, you can detect the button press and do what you like with it. Maybe power the device off by setting D6 to LOW if the button has been pressed for X ms.

If you want the device simply to enter sleep mode on a button press, then you can do that also. However, it gets a bit more complicated because the button then has to be used to wake the device. That means setting a pin change interrupt on pin A0 and then testing A0 on wake up to determine the length of the button press. If it is too short, then you can force the Arduino to resume sleep.
> 3 votes

---
Tags: arduino-mega, button
---


# Question
Title: How to get recover numeric data sent by an Arduino in binary
I am a C# dev and these C++ data conversions are killing me.

I have an Arduino sending binary data through LoRaWAN to AzureIOT. I am trying to decode my Temp/Humid/Bat payload that I am pulling out of AzureIOT Hub.

Here is a sample method I am using in C# to parse the byte array. Once I have parsed it, how do I convert those numbers back to their actual values?

Here is the input data on the sensor side:

> T=74.48
>
> RH=45.20
>
> BatteryVoltage:3332

Thanks. Here is how the data was input:

```
float temperature = readDHTTemperature(); //this method prints T to Serial
float humidity = readDHTHumidity(); //this method prints H to Serial
uint16_t batteryVoltage = readBattery(true);
delay(100);

unsigned char *puc;

puc = (unsigned char *)(&temperature);
appDataSize = 10;
appData[0] = puc[0];
appData[1] = puc[1];
appData[2] = puc[2];
appData[3] = puc[3];

puc = (unsigned char *)(&humidity);
appData[4] = puc[0];
appData[5] = puc[1];
appData[6] = puc[2];
appData[7] = puc[3];

appData[8] = (uint8_t)(batteryVoltage>>8);
appData[9] = (uint8_t)batteryVoltage;

```

Here is the output:

```
private static void BytesToString()
{
    var hexStringFromPayLoad = "MzOYQgAAHEINBA==";
    var bytes = Base64Decode(hexStringFromPayLoad);

    Console.WriteLine($"Temp: {bytes[0]}, {bytes[1]}, {bytes[2]}, {bytes[3]}");
    Console.WriteLine($"Humid: {bytes[4]}, {bytes[5]}, {bytes[6]}, {bytes[7]}");
    Console.WriteLine($"Bat: {bytes[8]}, {bytes[9]}");

    /*
    Temp: 51, 51, 152, 66
    Humid: 0, 0, 28, 66
    Bat: 13, 4
    */
}

```

# Answer
> 1 votes
Arduinos use very standard formats for their internal binary representations of data:

This is the same as your typical x86\_64. The implication is that, once the bytes are in your PC, you do not need to perform any conversion at all. All you need to do is either alias or copy the bytes to the memory locations of the variables that are meant to get the values.

Example in plain C:

```
uint8_t temperature_bytes[] = { 51, 51, 152, 66 };
float temperature;
memcpy(&temperature, temperature_bytes, sizeof temperature);
// now `temperature` holds the value 76.1.

```

How you would do this in C# is a question that is out of topic in this site.

---
Tags: sensors, c++, convert, bytes
---


# Question
Title: Can Arduino UNO/MEGA master assert SPI SS LOW on multiple slaves at once if Full Duplex is unnecessary?
I have a computer talking serially to an UNO SPI Master and, beyond it, multiple MEGA Slaves. The slaves never talk back to the master.

I understand it is normal and correct to assert **SS LOW** to select one slave at a time, such that the master clocks bits via **MOSI** to the selected slave on the same clock edges the slave sends bits to the master via **MISO**.

Multiple slaves clocking on MISO would garble the communication back to the master. But what if I don't care? Instead, on a system with a pulled-up MISO pin that does not even have MISO wires attached, what if the master selects all the slaves at once, then clocks a byte out on MOSI with a bit set calling for one specific slave (of 8 possible) to respond to subsequent bytes? That is way faster than the master sorting out with code which slave should get the message originating in the computer. ALL the slaves can check the bit they expect and ignore the subsequent bytes of the SPI message if the bit is CLEAR-- they are not doing anything else at the moment anyway, say.

What is wrong with this idea? Are there electronic issues in the UNO or MEGAs I am not thinking of? Is this done? Why not?

# Answer
> 1 votes
> What is wrong with this idea?

Nothing, this is perfectly possible. The main advantage is the avoidance of multiple SS lines, reducing pin count and/or decoding hardware.

The SPI main device does not know the number of SPI sub devices, and it will happily sample the level at the MISO pin, whatever you give it.

Each SPI sub device does not know that the other SPI sub devices receive the very same bytes. As you write, if the first byte (or any other protocol detail) tells it to ignore the rest of the transmission, it will.

> Are there electronic issues in the UNO or MEGAs I am not thinking of?

You need to read the data sheet to learn about the load of each input of the SPI sub devices, and the guaranteed provided drive capability of each output of the SPI main device, that means SS, SCLK, MOSI. Then make sure the driver can drive all receivers.

Commonly you can connect a two-digit number without any concern.You write that you have eight, so just go ahead.

You can leave the MISO outputs of the SPI sub devices simply unconnected. At the SPI main device make sure you have a pull-up or pull-down resistor on its MISO input.

> Is this done?

I have no personal experience or example, but I'm sure it is done.

> Why not?

When you actually need responses from the SPI sub devices, you need to do it differently. However, even then you can combine all the MISO outputs of the SPI sub devices with some clever digital logic.

---

Note: I prefer "main" and "sub", which still match the abbreviations, instead of the old terms of the former century.

# Answer
> 1 votes
The electronic circuit of an SPI work this way, when a slave device is not been selected (i.e. its CS pin is not asserted), its MISO line will be in tri-state output, i.e. it is in a high impedance floating state, electrically disconnect, this allows multiple devices sharing the same MISO bus. For this reason, you can't tie all the slave devices with a single CS pin as all the MISO outputs from the devices will be activated.

If you don't care about the MISO data clocking in from the slave devices, you simple don't connect the MISO pin to the bus.

---
Tags: spi
---