# Question
Title: Rc switch library display received values only one times using serial monitor
I use Rc switch library to transmit and receive data. It works fine.

The part that sends the data is as follows :

```
#include <Arduino.h>
#include <RCSwitch.h>

RCSwitch transmitter = RCSwitch();

void setup()
{
    Serial.begin(9600);
    transmitter.enableTransmit(10);
}

void loop()
{
    /* Send data in binary */

    // Go right
    transmitter.send("010101010101010100000011");
    delay(1000);

    // Go left
    transmitter.send("010101010101010100001100");
    delay(1000);
}

```

And the receiving part is like this:

```
#include <RCSwitch.h>

RCSwitch receiver = RCSwitch();
int rightLED = 4;
int leftLED = 7;
unsigned long receivedValue;
unsigned long goRight = 5592323;
unsigned long goLeft = 5592332;

void setup()
{
    Serial.begin(9600);
    receiver.enableReceive(0); // Receiver on interrupt 0
    pinMode(rightLED, OUTPUT);
    pinMode(leftLED, OUTPUT);
}

void moveRight()
{
    Serial.println("I'm going right");
}

void moveLeft()
{
    Serial.println("I'm going left");
}

void loop()
{
    if (receiver.available())
    {
        receivedValue = receiver.getReceivedValue();
        if (receivedValue == goRight)
        {
            moveRight();
        }
        if (receivedValue == goLeft)
        {
            moveLeft();
        }
        receiver.resetAvailable();
    }
}

```

The problem is, when I open a serial monitor and look the output of the received values `moveRight` and `moveLeft` functions are called multiple times.

```
I'm going right
I'm going right
I'm going right
I'm going right
I'm going left
I'm going left
I'm going left
I'm going left
I'm going right
I'm going right
I'm going right
I'm going right

```

What kind of change should I do in the receiver part so that `moveRight` and `moveLeft` functions are called only once.

```
I'm going right
I'm going left
I'm going right

```

# Answer
> 2 votes
You can save the previous received value, and only print if it is different from what you just received.

Something like this:

```
// near the top
const int rightLED = 4;
const int leftLED = 7;
const unsigned long goRight = 5592323;
const unsigned long goLeft = 5592332;

// to hold the state
unsigned long previousValue = 0;

// ...

// loop code
void loop()
{
  if (receiver.available())
  {
    unsigned long receivedValue = receiver.getReceivedValue();
    if (receivedValue != previousValue) {
      // something changed
      if (receivedValue == goRight)
      {
        moveRight();
      }
      if (receivedValue == goLeft)
      {
        moveLeft();
      }
      // remember the current value
      previousValue = receivedValue;
    }
    receiver.resetAvailable();
  }
}

```

# Answer
> 2 votes
Old post, I know but I have to add to it. The statement "transmitter.enableTransmit(10);" causes the RCSwitch library to send the message 10 times. You are receiving 4 messages; you should be receiving 10. I have found that when using "receiver.available()" I also get about half of what is expected. Just a hunch, but I think the "receiver.available()" is getting every other message. The RCSwitch library may have a dwell period after a message is received that holds the receiver in suspense causing every other message to be lost. "Serial.begin(9600)" also is a bit slow, but I think the buffer can handel it.

The attached image shows my transmitter power consumption. You can see that 10 messages are sent in about 200 mS. Your delay(1000) leaves plenty of time for completion of all messages received.

---
Tags: arduino-uno, arduino-pro-mini, rf
---


title: Digital Pot with Arduino

text:
# Question
Title: Digital Pot with Arduino
I am a newbie in electronics. Please correct me if I am wrong. I am replacing a pot with a digital pot (DS3502) in a circuit. The Vcc of the circuit is 12V. But the digital pot can have a maximum of 5.5V as Vcc. I am controlling the digital pot with an Arduino UNO. Can I use 5V from the Arduino as the Vcc of the digital pot and 12V as the Vcc of the circuit? I kept the ground common for both.

The connection is as below:

DS3502 Arduino Uno

VCC --- 5V

GND --- GND

SDA --- A4

SCL --- A5

DS3502 Circuit

RL --- GND

RW --- Circuit

This is a constant current circuit of 21mA, to drive a laser. But I want to slightly tune the intensity of laser using the digital pot. So I am replacing it with digital pot. But I am getting an open connection in the place of resistor. I have only use RL and RW to circuit. RH is kept opened. Do I need to connect RH and V bias to 12V(Vcc of my constant current circuit)? I don't have much knowledge in circuits. Please spare me if I am wrong

# Answer
> 2 votes
If you look at the datasheet it mentions that Vcc can be from 2.5V to 5.5V, and clearly the I2C connection is referenced to Gnd. Therefore you would connect the Uno to the DS3502 in the usual way (Gnd, Vcc, SDA and SCL).

The "digital pot" side has a separate input (V+) which can be from 4.5V to 15.5V.

> Can I use 5V from the Arduino as the Vcc of the digital pot and 12V as the Vcc of the circuit?

Your terminology is a bit loose here. You can use 5V from the Arduino to the Vcc pin of the pot (pin 3) and 12V to V+ and RH (pins 6 and 9). The output will be on RW (the wiper, pin 7).

It also looks like you would connect Gnd and RL (pins 2 and 8) to Gnd on the Arduino.

Although, conceivably I think, you could connect Gnd (pin 2) to Gnd on the Arduino, and RL (pin 8) to the Gnd of the "other circuit" - the one you are controlling. It looks like they are separate.

I think you might keep RL and Gnd not connected, to reduce digital noise.

The A0 and A1 pins are for modifying the I2C address.

---
Tags: arduino-uno, digital, potentiometer
---


# Question
Title: How to implement Arduino NANO as a RS-232 to USB adapter (Or do I need a Arduino Mega?) For 3D printer comms
I have a PC upstairs running my 3D printing slicer program (Simplify 3D). In the basement, I have several USB-enable 3D printers. My PC upstairs has a USB-to-RS-232 serial adapter. The serial side of that USB-to-Serial adapter connects to the Serial port of a Moxa Nport 6150 RS232-to-Ethernet protocol adapter. I get those Moxa devices for free when they break at work and then fix them for a couple of dollars.

The other side of the Moxa connects to my home computer network router. In the basement I can plug another Moxa into an ethernet cable on my home network and the serial RS232 output I need to connect to the Micro-USB jack of the 3D printer. How can I use an Arduino Nano (or Uno or Mega if required) to convert the RS232 data to the USB input of my 3D printer?

So I have PC-\>(RS-232)-\>\[MOXA(RS-232)-\>Moxa(Ethernet)\]-\>Router-\>\[Moxa(Ethernet)-\>Moxa(RS-232)\]-\>\[Arduino(RS-232)-\>Arduino(USB)\]-\>3D Printer(USB)... How can I get the Arduino to do that function? Items within \[ and \] brackets are single devices performing a protocol conversion.

I know people use Raspberry Pi's and a program called OctoPrint to remotely control their 3D printers but I get the Moxas for free and Uno's or Nanos are dirt cheap. RPi's are more expensive and for several 3D printers it can start adding up. Any ideas?

# Answer
Its not as easy as you think. An Arduino will not be enough for connecting the USB of the 3D printer. The USB protocol is strictly divided into slaves and masters. A USB(us) has exactly one master, which totally controls, what the slave can do. The slave itself cannot do much of its own.

Your 3D printer is a USB slave device. That enables a USB master (like a computer) to control it. The Arduino is also a USB slave device. If you connect both, you have a USB connection without a master. Nothing will happen. So you need to implement a USB master on the Arduino, which can handle the UART communication; all in software. That is generally possible, but I wouldn't recommend it. Also you definitely need extra hardware, because D+ and D- on USB are also electrically totally different from the TTL lines RX and TX (and also from the RS232 lines). They work differentially. So you need extra hardware to do that.

The easiest way with an Arduino would be to buy a USB host shield. With that you may be able to build, what you want.

But I would dispute, if this really makes sense. The cheapest USB host shield for Arduino, that I could find at amazon is around 10€, plus the price for an Arduino and the hassle of getting it all to work. A RaspberryPi Zero W only costs 10€. If you don't want to use wifi, you can add a USB to Ethernet adapter. And depending on the used software and its installation you might even be able to handle multiple printers with only one Pi (I use the Repertier Server, which has the ability to control multiple printers, I think). (Though depending on the number of printers and the resulting load you might wanna step up the game to a full Pi4)

---

There might be an additional way, depending on your printers. The printers microcontroller board might break the TX and RX pins out for you. Then you could connect the Arduino to them, no need for USB in that case. But that might not be an option. If the used microcontroller has a direct USB interface, there are no RX and TX pins to break out.
> 6 votes

# Answer
The Nano, like the Uno, has an onboard serial ↔ USB converter. If you can get a logic level serial from the Moxa, then you can use the Nano to convert that to USB:

1. Load a do-nothing sketch in the Nano
2. Connect the Moxa TX to the Nano's Tx through a 1 kΩ resistor, and the Moxa RX to the Nano's RX.

Yes, the second step looks backwards. The reason is that the labels RX and TX refer to the ATmega328P that runs your sketches on the Nano. Internally, the pin labeled RX is connected (through a resistor) to the TX pin of the serial ↔ USB converter, and this is thus the pin you want to connect the Moxa's RX. And similarly for the pin label TX (it's the RX of the onboard converter).

Step 1 is important because you do *not* want the 328P to open its serial port. The resistor is needed for the short time when the 328P is running the bootloader, and has its serial port open.
> 2 votes

# Answer
There's not enough information to provide a general solution at this time. As chrisl rightly says, the 3D printers are expecting a connection from a host. That host connection depends on whether the USB-serial interface inside the printer is supported. These are typically FTDI or WCH (QinHeng) chips, and would need the appropriate system driver for each type. This would be hard to implement on a USB host shield for Arduino.

Most 3d printers are, in essence, an Arduino inside. The typical 8-bit controller on the vast majority of 3d printers uses a very similar ATMega microcontroller. Some newer machines use 32-bit ARM microcontrollers, which are typically 3.3 V logic compared to the Arduino's (typical) 5 V. To add a standard RS-232 port you'd need to find the RX, TX, GND and Vcc points on each printer controller board and connect the right pins of your RS-232 to TTL converter boards to those points. This would bypass the USB ports on the printers entirely.

You might experience issues with flow control and buffering with multiple ports sending from one PC and Serial-Network-Serial latency. Marlin-style Gcode printers (= most filament printers that aren't Makerbot or Flashforge, approximately) don't use flow control: the printer sends back `ok` when it's ready for the next command. If your serial ports send data too slowly, the printer will pause and print quality may suffer. 3d printers don't need a really fast serial connections (under 20 kbit/s per printer, if using Gcode) but they need the data when they're ready to print.

OctoPrint can be quite an expensive option. The minimum supported platform is a Raspberry Pi 3b+ (+ power supply, SD card, USB cable, case, ...) dedicated to each printer. While you can run a very cut-down OctoPrint on a Raspberry Pi Zero, the author does not recommend it, and you have to click through an *Unsupported Configuration: Use at your own risk* dialogue.
> 2 votes

# Answer
If we take the following configuration PC(only pseudo serial like by old laptops without USB) -\> Arduino -\> USB printer, than all what is important is Arduino 'xxx.ino' pseudo ;) code:

```
//do all necessary setups
  initialize
(((( loop
//pc-->arduino
    oh, some bytes on serial     //Nano detect some activity on serial port
    I'm dividing that in commands,status and cargo. //Nano parse this stream and determine what to do with what.
    huh, now repack that in USB protocol and send out // most probably this are data an commands to sent to printer over USB with appropriate protocol
//Arduino-->printer
    hey printer, here is some feed for you //Nano announce upcoming data event
//printer --> Arduino
    thanks, want more input    // printer certainly react with acknowledge, (success or error) and request or not next data
//Arduino --> PC
    let's send some more, he like it //Nano request next data package from sender PC
))) //end loop         and repeat until all done

```

But somehow more detailed.

I hope you understand that this id ;) "humor/joke/nonsense" pseudo code that show only organization of data flow how to make some functions/procedures. The concrete usable code is up to you. Once more, it shows only that is possible to do it with Arduino. It is certainly needed more than 5 minutes to write the comment.

I'm not sure if CR/LF come through correctly but anyone that can write code in C would be able to properly format this text and may be start filling the sections with real code
> -1 votes

---
Tags: arduino-uno, arduino-mega, arduino-nano
---


title: Parse char* mac-string to uint8_t array

text:
# Question
Title: Parse char* mac-string to uint8_t array
I have to handle a String coming in over UART containing a bunch of information, part of it is a MAC-address that I get by using String.substring(a, b) returning a 12-char String representing a mac-address `"B8C9A45BA770"` \<- (just an example).

**I need the format of the mac-address to be a uint8\_t array like so `{ 0xB8, 0xC9, 0xA4, 0x5B, 0xA7, 0x70 }`.**

So I need a function to convert a String to a uint8\_t\*. Sadly I have no clue how to convert this. There has so be an easy way right? its "C8" to 0xC8 and so forth...

Any ideas on this?

# Answer
> 2 votes
Personally I'd go with a basic implementation such as this one.

```
const uint8_t MAC_length = 6;
uint8_t* MAC_buffer[6];

uint8_t fromHexChar(char c)
{
    uint8_t result = 0
    if ((c >= '0') && (c <= '9'))
        result = c - '0';
    else if ((c >= 'A') && (c <= 'F'))
        result = 10 + c - 'A';
    else if ((c >= 'a') && (c <= 'f'))
        result = 10 + c - 'a';
    return result
}

uint8_t* toMAC(String s)
{
    for (uint8_t i = 0; i < MAC_length; i++)
    {
        MAC_buffer[i] = (fromHexChar(s.charAt(2*i)) << 4) | fromHexChar(s.charAt(2*i + 1));
    }
    return MAC_buffer;
}

```

Probably it can be optimized, but this is such a simple job and to be used so rarely that I think this is enough.

Important: I did not test this code, so there may be bugs inside.

If you need to start from an arbitrary point in the String instead of at the beginning, you simply have to modify it this way:

```
uint8_t* toMAC(String s, uint8_t startIdx)
...
        MAC_buffer[i] = fromHexChar(s.charAt(2*i + startIdx)) << 4 | fromHexChar(s.charAt(2*i + startIdx + 1));

```

Note for future me: I checked both on a simulator and in the code, and `charAt` is safe to use even when the index is outside the string boundaries (it simply returns 0).

---
Tags: string, convert, c-string, bytes
---


# Question
Title: Is there a schematic for the ESP32S Dev Kit C V4 NodeMCU WLAN Development Board?
Recently I bought a ESP32S Dev Kit C V4 NodeMCU WLAN Development Board. I got it from azdelivery.de in Germany. Now I am interested in the schematic for this board to learn more about it. Not Google, nor the support team at azdelivery.de could help me, but since the board is a Chinese mass product, I hope to find an answer here, where I could get the schematic. Thank you!

# Answer
> 2 votes
Espressif has schematics and more on their website. EZ-Delivery sells two different versions: One has a CP2101 USB-Interface, the other one uses a CH340 instead. If you have the CP2101 variant, this should match the one at Espressif's Website:

https://dl.espressif.com/dl/schematics/esp32\_devkitc\_v4-sch.pdf

More related docs are linked on their Website (scroll down to "Related Documents" here:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-devkitc.html#get-started-esp32-devkitc-board-front

# Answer
> 1 votes
Here is a webpage that provides ESP32 Devkit C schematic and pin definition.

ESP32 Devkit C schematic

---
Tags: esp32
---


title: How to calibrate MMC5603 magnetometer

text:
# Question
Title: How to calibrate MMC5603 magnetometer
I just got a MMC5603 magnetometer from Adafruit however the measurements are unreliable. For example when I convert it to a heading it goes from 200° to 180° and then back to 200° if I move it radially.

# Answer
> 1 votes
To calibrate a magnetometer you should perform hard-iron and soft-iron calibration. There's some guides online about how to do this but I found this digikey guide to be the most informative. Adafruit also has a guide here

I had some issues getting this to work however so here's some tricks

## Using an M1 macbook

Both guides recommend to use MotionCal but it hasn't been updated in several years. If you downloaded the macOS version it might not show any available ports. To fix this you need to compile it from source – you can find details in this Github Issue but the TL;DR is:

1. `git clone git@github.com:PaulStoffregen/MotionCal.git`
2. `brew install wxwidgets`
3. Open the `Makefile`
4. Comment the line `OS = LINUX`
5. Uncomment the line`OS = MACOSX_CLANG`
6. Under `else ifeq ($(OS), MACOSX)` add `-arch arm64` to the `CFLAGS`
7. Run `make` and it should build

I had some issues with it not building after this which was resolved by deleting the directory and then redoing these steps

## Using an Arduino UNO

Both guides say to use **Adafruit Sensor Lab** which is too large to fit onto an Arduino UNO's flash. Instead you can you use this code:

```
#include <Arduino.h>

#include <Adafruit_MMC56x3.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_MMC5603 mmc = Adafruit_MMC5603(12345);

int loopcount = 0;

// Hard-iron calibration settings
const float hard_iron[3] = {
    0, 0, 0
};

// Soft-iron calibration settings
const float soft_iron[3][3] = {
    { 1, 0, 0 },
    { 0, 1, 0 },
    { 0, 0, 1 }
};

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

    Serial.println("Adafruit_MMC5603 Magnetometer Test");
    Serial.println("");

    /* Initialise the sensor */
    if (!mmc.begin(MMC56X3_DEFAULT_ADDRESS, &Wire)) { // I2C mode
        /* There was a problem detecting the MMC5603 ... check your connections */
        Serial.println("Ooops, no MMC5603 detected ... Check your wiring!");
        while (1)
            delay(10);
    }

    /* Display some basic information on this sensor */
    mmc.printSensorDetails();
}

void loop(void)
{
    static float hi_cal[3];
    // Get a new sensor event
    sensors_event_t event;
    mmc.getEvent(&event);

    // Put raw magnetometer readings into an array
    float mag_data[] = { event.magnetic.x,
        event.magnetic.y,
        event.magnetic.z };

    // Apply hard-iron offsets
    for (uint8_t i = 0; i < 3; i++) {
        hi_cal[i] = mag_data[i] - hard_iron[i];
    }

    // Apply soft-iron scaling
    for (uint8_t i = 0; i < 3; i++) {
        mag_data[i] = (soft_iron[i][0] * hi_cal[0]) + (soft_iron[i][1] * hi_cal[1]) + (soft_iron[i][2] * hi_cal[2]);
    }

    // 'Raw' values to match expectation of MOtionCal
    Serial.print("Raw:");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(int(mag_data[0] * 10));
    Serial.print(",");
    Serial.print(int(mag_data[1] * 10));
    Serial.print(",");
    Serial.print(int(mag_data[2] * 10));
    Serial.println("");

    // unified data
    Serial.print("Uni:");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(mag_data[0]);
    Serial.print(",");
    Serial.print(mag_data[1]);
    Serial.print(",");
    Serial.print(mag_data[2]);
    Serial.println("");

    delay(10);
}

```

which will output the magnetometer data correctly formatted at the correct baud rate. Then you just open up MotionCal, select the right port

---
Tags: magnetometer, calibration
---


title: Using file.seek() with arduino ide

text:
# Question
Title: Using file.seek() with arduino ide
I have in my code in c, this function:

```
    fseek(file, 0, SEEK_SET);

```

I need to use the same function with Arduino ide. Is this correct?

```
    file.seek(file.size());

```

Or what is the alternative function in Arduino ide?

# Answer
> 1 votes
According to https://www.arduino.cc/reference/en/libraries/sd/seek/ :

### SD - seek()

Seek to a new position in the file, which must be between 0 and the size of the file (inclusive).

### Syntax

```
file.seek(pos)

```

### Parameters

* file: an instance of the File class (returned by SD.open()).
* pos: the position to which to seek (unsigned long).

---

If you want to seek to the start of the file, therefore you should seek to zero, not `file.size()`. Using `file.size()` would seek to the end of the file.

---
Tags: arduino-uno, arduino-ide
---


# Question
Title: A peristaltic pump with pH sensor and web based output project
Good day to you all, I am asking here to confirm that my project is feasible. I have low knowledge of Arduino and other components. Please help me in achieving this project.

I already have the peristaltic pump and pH sensor working with Arduino uno. Now I want the output of the pH sensor to be displayed in a webpage or web app, In the webpage I will also make a formula on how much volume is released from the peristaltic pump.

So there are two things on my webpage output: the acidity of the liquid and the volume released. I want a wireless setup, so I guess I would use ESP32 (notsure)? Now I kind of getting hard on how to put it on a webpage and the important part is, how to pass the data from the arduino to the ESP32?. Any ideas? or things that I would do?

OR

I would use the ESP32 alone since I have not so many components and I think the ESP32 can cater for the pHsensor (analog signal) and pwm (motor Peristaltic pump). Correct me if I'm wrong. By this, I won't be having problems about the communication to the arduino and esp32 (UART).

Additional Info:
Current Set up-
Arduino - controls the pump and pHsensor
ESP32 - Webpage or webserver

Is there any way that I could do this with ESP32 alone? so that I won't be having problems with UART.

I want to thank you in advance for giving me insights.

Update:

by this I decided to use ESP32 alone for the whole project. I just need to rewire all. I'm hoping the ESP32 has PWM pins to control the pwm peristaltic pump and pHsensor(analog signal) pins. Please confirm if you know that ESP32 has these pins(for pwm and analog). By the way I'm using the ESP32S where the TXD0 is in pin 35 which is the GPIO1 and the RXD0 is in pin 34 which is the GPIO3. – Johannes Remotigue 2 days ago Delete

# Answer
> 1 votes
Yes. You will need to add a solid state switch or similar to power the motor. The ESP32 has the radio needed to connect to your wifi so that part is already there. The ESP can be configured as a client or server so take your pick. There is a lot published on the web about doing this with code even posted. The device also has a lot of computing power so it could become a stand alone device which reports the results to the web server or works in conjunction with it.

All you will need to add is mainly code. This should get you started. Just be cautious as the Arduino is generally 5V and the ESP is 3.3 volt so some voltage translation may be needed and if using 5V modules and/or MOSFETS. If MOSFETs are involved be very careful of the Vgs ratings to be sure it is on with 3V.

---
Tags: arduino-uno, web-server, uart, esp8266webserver, arduino-iot-cloud
---


# Question
Title: How do I set the DHCP pool for an ESP-WIFI-MESH?
I'm building a mesh with ESP32 dev kits (ESP32-DevKitC V4) using the ESP-IDF VS Code extension and the ip\_internal\_network example project. The code for the example, common project components, and the API is linked. When the mesh nodes power on and build the network, they use the 10.0.0.0 network. How do I change the internal mesh network?

My operating assumptions:

* The root node receives an external IP address from an external DHCP server.
* The root node acts as an internal DHCP server to the mesh nodes.
* The root node performs network address translation.
* Its DHCPv4 server runs on the lwIP TCP/IP stack.
* Internal IP addresses are leased from a pool governed by the root node (but it's possible that nodes request a particular address from this network and the server provides the next available; I'm unsure).
* The network address is 10.0.0.0/8 (I inferred the subnet mask; it could be anything).

Obviously, the first thing I tried was searching for this network address in files. There was nothing in the project workspace and too many hits in the repo to be useful. I tried decimal and hex with no luck.

I also tried tracing the function that prints the IP address to the serial terminal to find the IP var, and working backwards to locate the statement that initializes this variable. I'm still reading event handler API documentation so I haven't made quick progress here either.

The programming interface is split among ESP-IDF component header files, build systems (CMake and Ninja?), KConfig options and host tools (idf.py?). C, FreeRTOS and build systems are all new to me so I would appreciate if someone with more experience could weigh in. Thank you.

# Answer
> 2 votes
I figured it out; it's in mesh\_netif.c:43. I'm not sure why I passed over this file initially but it caused a lot of unnecessary headache. The relevant struct is this:

```
const esp_netif_ip_info_t g_mesh_netif_subnet_ip = {
    .ip = { .addr = ESP_IP4TOADDR( 192, 168, 0, 1) },
    .gw = { .addr = ESP_IP4TOADDR( 192, 168, 0, 1) },
    .netmask = { .addr = ESP_IP4TOADDR( 255, 255, 255, 0) },
};

```

I changed the 10.0.0.0/16 network to 192.168.0.0/24. The root node assumes the address in `.ip`. I assume child nodes check the ARP table and increment until an address is available, then send the DHCPREQUEST for that address to root. I say "assume" because although root runs lwIP, I am not sure child nodes run lwIP (they may just communicate in layer 2 ESP-WIFI-MESH frames).

Make sure your DHCP server publishes an IPv4 DNS address or `ESP_ERROR_CHECK(esp_netif_set_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns))` (mesh\_netif.c:70) will fail and cause the board to power cycle. A way around this is to enable `Use global DNS IP` in menuconfig. The global DNS field is in hex format, so 10.32.64.128 is written 0x0A204080.

Mesh-internal IP messages are published with MQTT so the name/address `.broker.address.uri` in mqtt\_app.c:74 must be accessible from the router.

---
Tags: programming, esp32, wireless, networking, espressif
---


title: DS18B20 doesn't work reliably

text:
# Question
Title: DS18B20 doesn't work reliably
like discribed in the title my temperature sensor goes to -127 after a few minutes of run time, it works again after a restart, I have already replaced the sensor and I'm using the same code for the temperature which I had used before which has been running flawlessly for almost 6 months now, I really have no clue what I did wrong hopefully someone got an idea.

Thank you!

# Answer
There's a problem with using OneWire and Wire/I2C in one Sketch at once.

I believe this is because OneWire takes too long not sure, but this is probably why the temperature reading went to -127 after a while to fix thi.

I used an NTC 10K at 20°C. Below you can see code to make the NTC work and how to wire it!

Hope this helps!

Code:

```
#include <math.h>
const int thermistor_output = A1;

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

void loop() {
  int thermistor_adc_val;
  float output_voltage, thermistor_resistance, therm_res_ln, temperature;
  thermistor_adc_val = analogRead(thermistor_output);
  output_voltage = ( (thermistor_adc_val * 5.0) / 1023.0 );
  thermistor_resistance = ((5 * (10.0 / output_voltage)) - 10);
  thermistor_resistance = thermistor_resistance * 1000 ;
  therm_res_ln = log(thermistor_resistance);
  temperature = (1 / (0.001129148 + (0.000234125 * therm_res_ln) + (0.0000000876741 * therm_res_ln * therm_res_ln * therm_res_ln)));
  temperature = temperature - 273.15;
  Serial.print("Temperature in degree Celsius = ");
  Serial.print(temperature);
  Serial.print("\n");
  delay(1000);
}

```

Wiring:
> -1 votes

---
Tags: arduino-nano, temperature-sensor, ds18b20, temperature
---


title: 16 bit PWM on Nano Every

text:
# Question
Title: 16 bit PWM on Nano Every
I need to drive a LED strip via MOSFET module. The module needs a high resolution PWM for very dim conditions. How can I set my pin to a 16 bit PWM resolution on an Arduino Nano Every?

# Answer
> 4 votes
It's possible for D5 (TCA0-WO2) + D9 (TCA0-WO0) + D10 (TCA0-WO1) all three of them will be 16bit if you change TCA0 top value, but you can't use analogWrite.

```
void setup() {
  // change period of TCA0 (already configured and started by arduino core)
  TCA0.SINGLE.PER = 0xFFFF; // change top value from 255 to 65535

  // set PWM value of D9 (channel 0)
  TCA0.SINGLE.CMP0 = 0; // initial value
  // enable PWM output (needed only once in setup)
  pinMode(9, OUTPUT); // setup pin as an output
  TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP0EN_bm; // enable pwm->pin

  // D5
  TCA0.SINGLE.CMP2 = 1; // initial value
  pinMode(5, OUTPUT);
  TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP2EN_bm;

  // D10
  TCA0.SINGLE.CMP1 = 65530; // initial value
  pinMode(10, OUTPUT);
  TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP1EN_bm;
}

```

and in the code you'll use only `TCA0.SINGLE.CMPn = val;` where n is 0..2

(untested, but should be working)

EDIT: I forgot the period will be 3.8Hz, so you'll need to change also TCA0 prescaller or use smaller precision like 10b or so. Changing prescaller will mess up the all the TCB counters periods along with the one used for millis counter so you'd need also change that

EDIT2: for classic UNO/nano it'll look like this:

```
TCCR1B = 0; // stop timer

ICR1  = 0xFFFF; // f = 16MHz / (2*N*ICR1) = 16MHz / (2*65536) => ~122Hz
OCR1A = 1;             // PB2 -> D9  (PWM value)
TCCR1A = _BV(COM1A1);  // enable PWM output on PB2
TCCR1B = _BV(WGM13) | _BV(CS10);  // mode=8 (phase and freq correct, ICR1 as top) and start timer with prescaller /1

```

# Answer
> 0 votes
Thanks again for your help KIIV. I can confirm it works. This an example of a low light PWM for an LED on Pin 10. Maybe it helps others.

```
int brightness = 0;  // how bright the LED is
int fadeAmount = 1;  // how many points to fade the LED by

void setup() {
  TCA0.SINGLE.PER = 0x4000;
  TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV16_gc | 1 << TCA_SINGLE_ENABLE_bp
  TCA0.SINGLE.CMP1 = 65530; // initial value
  pinMode(10, OUTPUT);
  TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP1EN_bm;
}

void loop() {
  // set the brightness of LED pin:
  TCA0.SINGLE.CMP1 = brightness;

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 64) {
    fadeAmount = -fadeAmount;
  }
  // wait to see the dimming effect
  delay(50);
}

```

---
Tags: pwm, arduino-nano-every
---


title: Having trouble uploading sketch to Nano

text:
# Question
Title: Having trouble uploading sketch to Nano
I have a few cheap Nano clones that I bought online that have worked for the past couple of months. They were working fine today until suddenly the Arduino IDE had trouble uploading sketches to them.

Here is the full error message:

```
Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

Sketch uses 2080 bytes (6%) of program storage space. Maximum is 30720 bytes.

Global variables use 212 bytes (10%) of dynamic memory, leaving 1836 bytes for local variables. Maximum is 2048 bytes.

An error occurred while uploading the sketch

avrdude: ser_open(): can't set com-state for "\\.\COM5"

```

I have tried troubleshooting multiple ways, but none of the following worked:

* unplugged/replugged in nano
* restarted computer
* swapped to another nano clone
* changed USB cables
* changed USB ports
* tried uploading other code
* downloaded the CH340 drivers

I tried uploading to an Arduino Mega and that DID work, however, I would like to be able to use the Nano.

I am using version 1.8.19

Thanks for the help.

# Answer
See Have I bricked my Arduino Uno? Problems with uploading to board.

I know you mentioned Nano, but it is the same concept.

If a sketch you previously uploaded sets up the watchdog timer to fire too quickly the new sketch may not upload.

Try holding down reset while you start the upload process and then release reset when the upload starts. See the part of the linked answer headed "Watchdog timer problems".
> 0 votes

# Answer
The cheap Nano requires you to use the old bootloader. I use them without problems most of the time. When it fails to upload I first check tools and validate the bootloader it is running. If it is correct I then close the IDE, power down the Nano and then reopen and repower it, between the two it usually solves the problem.
> 0 votes

---
Tags: arduino-nano, uploading, clones, ch340
---


# Question
Title: How to properly read ADC on an ATtiny85?
**What I want to do**: attach six buttons to a single input. Each button triggers a different action.

**How I want to do it**: Use an AD conversion and add a resistor with different values to each button so that you can distinguish between the different input signals
I use these values: 1k, 4.7k, 18k, 22k, 55k, 300k

Vcc is stable 3.3v but I also tried it on 5v. I use Vcc as reference value for the ADC.

**The problem I have**: no matter what I do I always read the same value on the ADC. Connected to GND it reads 0 and on Vcc it reads a value that’s always the same regardless what resistor I actually use.

I tried a lot of things I’ve found on the internet but nothing really worked for me. I’m clearly doing something wrong

This is the method I call in `setup()` to initialize the converter on ADC2(pb4)

```
void initADC()
{
  // 8-bit resolution
  // set ADLAR to 1 to enable the Left-shift result (only bits ADC9..ADC2 are available)
  // then, only reading ADCH is sufficient for 8-bit results (256 values)

  ADMUX =
            (1 << ADLAR) |     // left shift result
            (0 << REFS1) |     // Sets ref. voltage to VCC, bit 1
            (0 << REFS0) |     // Sets ref. voltage to VCC, bit 0
            (0 << MUX3)  |     // use ADC2 for input (PB4), MUX bit 3
            (0 << MUX2)  |     // use ADC2 for input (PB4), MUX bit 2
            (1 << MUX1)  |     // use ADC2 for input (PB4), MUX bit 1
            (0 << MUX0);       // use ADC2 for input (PB4), MUX bit 0

  ADCSRA =
            (1 << ADEN)  |     // Enable ADC
            (1 << ADPS2) |     // set prescaler to 64, bit 2
            (1 << ADPS1) |     // set prescaler to 64, bit 1
            (0 << ADPS0);      // set prescaler to 64, bit 0
}

```

The code is taken from here https://www.marcelpost.com/wiki/index.php/ATtiny85\_ADC

The page seems to be down at the moment so here is an archived version of it https://web.archive.org/web/20230128091128/https://www.marcelpost.com/wiki/index.php/ATtiny85\_ADC

In the `loop()` method I do basically this: Read ADC and then blink an LED *n* times, based on the read value.

```
ADCSRA |= (1 << ADSC);         // start ADC measurement
while (ADCSRA & (1 << ADSC) ); // wait till conversion complete

uint8_t adcValue = ADCH;

if (adcValue >= 0 && adcValue < 32) {
  blink(1);
} else if (adcValue >= 32 && adcValue < 126) {
  blink(2);
} else if (adcValue >= 126 && adcValue < 193) {
  blink(3);
} else if (adcValue >= 193 && adcValue < 227) {
  blink(4);
} else if (adcValue >= 227 && adcValue < 245) {
  blink(5);
} else if (adcValue >= 245 && adcValue <= 255) {
  blink(6);
}
delay(60000);

```

My breadboard has the resistors going from Vcc to an empty row and I connect a jumperwire from PB4 to one of these resistors and do an external reset of the microcontroller to test my setup. They share GND/Vcc

What am I doing wrong? What can I do to *debug* this?

Thanks

# Answer
Unfortunately @jsotola only posted their solution as a comment. But it was the correct answer. So I'll just post my solution here

I now use a voltage divider setup with these values:

Voltage divider formula `Vs * R2 / (R1 + R2)`

Vs: 3.3v
R2: 100k Ohm
R1: 10k (3.0v), 27k (2.8v), 38k (2.6v), 50k (2.2v), 65k (2.0v)

Using an 8-bit ADC, I came up with these *if* statements to distinguish between the inputs. I gave it some room for deviation

```
if (adcValue >= 227 && adcValue <= 237)
{
  // 10k ohm (3.0V -> adc 232)
}
else if (adcValue >= 212 && adcValue <= 223)
{
  // 18k ohm (2.8V -> adc 217)
}
else if (adcValue >= 196 && adcValue <= 206)
{
  // 27k ohm (2.6V -> adc 201)
}
else if (adcValue >= 181 && adcValue <= 191)
{
  // 38k ohm (2.4V -> adc 186)
}
else if (adcValue >= 165 && adcValue <= 175)
{
  // 50k ohm (2.2V -> adc 170)
}
else if (adcValue >= 150 && adcValue <= 160)
{
  // 65k ohm (2.0V -> adc 155)
}

```

Here is a picture of my breadboard. I know it's not a real schematic but I couldn't figure that out right now. But I hope it's good enough
> 1 votes

---
Tags: adc, attiny85, digital-analog-conversion
---


# Question
Title: How to fix UnicodeDecodeError when using Serial.println
I am using an Arduino Uno R3 to send instructions to a serial monitor in a Python program with Serial.println. But when I send a specific line, I get a a `UnicodeDecodeError`.

The line in the Arduino code that causes this error is:

```
Serial.println("Press '1,2,3,4,5' to run motor at 10%, 20%, 30%, 40%, 50% for 2 seconds");

```

My Python code to read the serial data is:

```
def get_serial_data(self):
        while 1:
            try:
                serial_data = self.serial_connection.readline().decode('Ascii')
                filtered_serial_data = serial_data.strip('\r\n')
                self.serial_monitor.insert(END, filtered_serial_data)
            except TypeError:
                pass

```

and is called from a thread:

```
thread1 = threading.Thread(target=self.get_serial_data)
        thread1.daemon = True
        thread1.start()

```

But I get the following error:

```
UnicodeDecodeError: 'ascii' codec can't decode byte 0x85 in position 36: ordinal not in range(128)

```

Can anyone help why this is happening or how to fix, I saw a stackoverflow post to use a try, except block to get it to ignore this line, but I want to print it out, and I want to understand why I get this error.

# Answer
I solved the issue. It was a memory issue not a decoding issue. Because the dynamic memory was mostly used up, it affected the encoding of the data. Reducing the amount of memory my code was using resolved the issue.

I also discovered, that `Serial.println("some text")` uses a lot of dynamic memory. So by reducing the amount of text I was encoding helped, but also by wrapping the the text in `F()`, like this:

```
Serial.println(F("some text"))

```

Which stores the string in flash memory not sram. Heres a helpful link on the F function:

https://arduinogetstarted.com/faq/what-is-serial.println-f
> -1 votes

---
Tags: arduino-uno, serial, python
---


# Question
Title: Is it possible to synchronize two SPI busses to send data out in parallel on the same clock signal?
We're working with these very odd driver chips which are sort of like shift registers except rather than latch the data at the end, the latch needs to happen over the last 'n' clock cycles in parallel with the data being shifted out. Depending on the value of 'n', the data is 'latched' into different registers. Like I said, it's an odd protocol.

Here's an example sending six bytes of data (top row) synced to the latch (bottom row). The latch is HIGH for the last two bits of the data as it's being shifted out.

```
Time-->
11001100 01010101 10011010 11001011 01001010 10010101
00000000 00000000 00000000 00000000 00000000 00000011

```

In this example, the latch is synced to the fifth and sixth bit of that last frame (as opposed to the 7th and 8th in the first example) which tells the chip to load this data into a different register.

```
Time-->
11001100 01010101 10011010 11001011 01001010 10010101
00000000 00000000 00000000 00000000 00000000 00001100

```

Like I said, it's an odd design, but it basically lets you shoot out data non-stop without having to pause to latch.

Because of having to 'sync' the latch with certain clock cycles in the data, we can't use the standard SPI bus and have to use normal GPIO pins, which of course are substantially slower.

BUT... if I could set up the data for a second SPI bus, then use a buffer to define where the latch is high/low accordingly, that would work.

The issue is I don't know how to, or if it's even possible to sync SPI busses together.

Only thing I can think of is to use one SPI bus as the master and another SPI bus (on the same processor) as a slave, then try to leverage the bi-directional nature of it. But this is just a guess.

I was considering looking into DMA too, but I'm starting with SPI since I know my chip has four SPI busses on it. (Update: I'm starting to think DMA is the way to go here since I now know it is possible to sync two DMA controllers to the same clock.)

# Answer
> 1 votes
As the Wikipedia page on SPI shows (as introductory material), the SPI **main** device generates the clock. The SPI **sub** device waits for the leading edge on its `CS` (chip select) to start transmitting its data on the following clock edges.

So you can set up one of the senders as main device, and the other sender as sub device. Use MOSI of main as the first data output, and MISO of sub as the second data output, like this:

simulate this circuit – Schematic created using CircuitLab

You can add more SPI sub devices, if you need more synchronized outputs.

---
Tags: spi
---


# Question
Title: Microcontroller freezes when triggering the gate of an N-channel MOSFET
**Disclaimer**: I have asked questions about this project before but this is yet another issue I'm facing.

**What I really want to do**: Build a battery powered device with 6 colored buttons. When you press one of the buttons the gadget should play a sound saying the name of the color.

It should not need an ON/OFF toggle to save battery capacity but rather have a very low idle current draw so that the battery will lasts for weeks (or even months) when it's not used.

Something like this

**Hardware**: ATtiny85 (low draw in general, very low draw in sleep), DfPlayer, 3.7v Battery (probably 18650)

The 6 buttons are attached to a single input pin. The microcontroller can distinguish them by reading the ADC value. The buttons have different resistors attached to them

**How I wanted to do it**: My initial plan was to press a button that wakes the microcontroller up. The mcu then wakes the dfplayer, plays a sound and goes back to sleep. If that would not be responsive enough add a delay to the sleep like: if no button was pressed within the last 30s go to sleep. That worked after some initial problems but it turned out that the DfPlayer "sleep mode" doesn't mean it goes to sleep as in it draws less current but much rather that it's just idling, not playing any sound.

**How I want to do it now**: Pretty much the same as above but instead of sending the DfPlayer to sleep just turn it on and off:
Press a button that wakes the microcontroller up. The mcu then turns the DfPlayer on by setting the gate of an n-channel mosfet (IRF3708) HIGH, waits a short period of time, plays a sound, turns the dfplayer off and goes back to sleep. If that's not responsive enough add a sleep delay like explained above.

**What I'm already able to do**:

* make the DfPlayer play a specific sound over serial communication
* distinguish between the 6 input buttons
* wake the microcontroller up with any of these buttons
* turn the DfPlayer on/off by using an n-channel mosfet

**The problem that I have**: The microcontroller *freezes* when I set the output pin attached to the mosfet gate to HIGH. Freeze means it just won't execute any code after the `digitalWrite(PIN_MOS, HIGH);` call. I tested it by turning an LED on a different pin on and off like so

```
digitalWrite(PIN_LED, HIGH);
digitalWrite(PIN_MOS, HIGH);
digitalWrite(PIN_LED, LOW);

```

The LED turns on but won't ever turn off. When I use the external reset of the attiny the mosfet will turn off and code will execute again just fine. Until I try to set the mosfet pin to HIGH again.
The DfPlayer will turn on though, I can play sounds on it by shorting 2 pins on it. It doesn't seem to be unstable either. It's just that the attiny hangs up.
I use a cheap lab psu but it should be good enough to be not the problem. I've also tried a fully charged 18650 battery and a CR2032 battery. The 18650 worked the same as the psu and the CR2032 just couldn't handle the draw and the DfPlayer wouldn't properly turn on.
I tried it different voltages between 3.3v and 5v. In theory everything should work and in reality it didn't change anything either.

Here is the breadboard layout I use.
I also added an electrolytic and ceramic cap between Vcc/GND on the DfPlayer but that didn't help either

Here is the code I use

```
    #include <Arduino.h>
    #include <avr/sleep.h>
    #include <DFMiniMp3.h>
    #include <avr/interrupt.h>
    #include <avr/power.h>
    #include "LemonSerial.h"
    #include "mp3notify.h"

    #define PIN_TX PB0
    #define PIN_RX PB1
    #define PIN_MOS PB2
    #define PIN_LED PB3
    #define PIN_A PB4

    LemonSerial secondarySerial(PIN_RX, PIN_TX);
    DfMp3 dfmp3(secondarySerial);

    void sleep();

    void initADC()
    {
      ADMUX =
          (1 << ADLAR) | // left shift result
          (0 << REFS1) | // Sets ref. voltage to VCC, bit 1
          (0 << REFS0) | // Sets ref. voltage to VCC, bit 0
          (0 << MUX3) |  // use ADC2 for input (PB4), MUX bit 3
          (0 << MUX2) |  // use ADC2 for input (PB4), MUX bit 2
          (1 << MUX1) |  // use ADC2 for input (PB4), MUX bit 1
          (0 << MUX0);   // use ADC2 for input (PB4), MUX bit 0

      ADCSRA =
          (1 << ADEN) |  // Enable ADC
          (1 << ADPS2) | // set prescaler to 128, bit 2
          (1 << ADPS1) | // set prescaler to 128, bit 1
          (1 << ADPS0);  // set prescaler to 128, bit 0
    }

    void setup()
    {
      initADC();

      pinMode(PB5, INPUT_PULLUP);
      pinMode(PIN_A, INPUT);
      pinMode(PIN_LED, OUTPUT);
      digitalWrite(PIN_LED, LOW);
      pinMode(PIN_MOS, OUTPUT);
      digitalWrite(PIN_MOS, LOW);
    }

    void play(uint16_t track)
    {
      if (digitalRead(PIN_MOS) == LOW)
      {
        digitalWrite(PIN_LED, HIGH);
        delay(500);
        digitalWrite(PIN_MOS, HIGH);
        digitalWrite(PIN_LED, LOW);

        delay(500); // wait for DfPlayer to turn on

        dfmp3.begin();
        dfmp3.reset();
        dfmp3.disableDac();
        dfmp3.setVolume(30);
        dfmp3.setPlaybackSource(DfMp3_PlaySource_Sd);
      }

      dfmp3.playGlobalTrack(track);
    }

    void loop()
    {
      ADCSRA |= (1 << ADSC); // start ADC measurement
      while (ADCSRA & (1 << ADSC))
      {
          // wait till conversion complete
      }

      uint8_t adcValue = ADCH;
      // actually calculate the parameter based off adcValue here. omitted for readability
      play(1);
    }

    // Interrupt Serviceroutine (Pin-Change-Interrupt)
    ISR(PCINT0_vect)
    {
      LemonSerial::handle_interrupt();
    }

    // ADC interrupt service routine
    ISR(ADC_vect)
    {
      ; // noop
    }

```

# Answer
> 1 votes
@6v6gt was the one who figured out what was missing.

I had to increase the 1Ω resistor between the output pin and gate to 1kΩ and add a 100nF ceramic capacitor between GND and gate. Eventually it worked just as expected.

This is the full code I ended up using. I tried to add enough comments to make it clear what happens.

```
#include <Arduino.h>
#include <avr/sleep.h>
#include <DFMiniMp3.h>
#include <avr/interrupt.h>
#include <avr/power.h>
// this is just "SoftwareSerial" without blocking interrupts
// thus you have to call handle_interrupt() from here
#include "LemonSerial.h"
#include "mp3notify.h"

#define PIN_TX PB0
#define PIN_RX PB1
#define PIN_MOS PB2
#define PIN_LED PB3
#define PIN_A PB4
// turning the player on and initializing it takes quite a while
// thus do not go back to sleep immediately after each button press
uint32_t timeoutMs = 30000;
uint64_t started = 0;

// dfplayer api
LemonSerial secondarySerial(PIN_RX, PIN_TX);
DfMp3 dfmp3(secondarySerial);

void sleep();

uint8_t readADC()
{
  ADCSRA |= (1 << ADSC); // start ADC measurement
  while (ADCSRA & (1 << ADSC))
    ; // wait till conversion complete

  uint8_t adcValue = ADCH;
}

void initADC()
{
  ADMUX =
      (1 << ADLAR) | // left shift result
      (0 << REFS1) | // Sets ref. voltage to VCC, bit 1
      (0 << REFS0) | // Sets ref. voltage to VCC, bit 0
      (0 << MUX3) |  // use ADC2 for input (PB4), MUX bit 3
      (0 << MUX2) |  // use ADC2 for input (PB4), MUX bit 2
      (1 << MUX1) |  // use ADC2 for input (PB4), MUX bit 1
      (0 << MUX0);   // use ADC2 for input (PB4), MUX bit 0

  ADCSRA =
      (1 << ADEN) |  // Enable ADC
      (1 << ADPS2) | // set prescaler to 128, bit 2
      (1 << ADPS1) | // set prescaler to 128, bit 1
      (1 << ADPS0);  // set prescaler to 128, bit 0
}

void setup()
{
  initADC();

  // set INPUT_PULLUP to reduce current draw
  pinMode(PB5, INPUT_PULLUP); // PB5 is not assigned to any constant
  pinMode(PIN_LED, INPUT_PULLUP);

  pinMode(PIN_A, INPUT); // ADC pin is physically pulled low
  pinMode(PIN_MOS, OUTPUT);
  digitalWrite(PIN_MOS, LOW);

  started = millis();
}

/// @brief plays a track on the dfplayer. turns the player on if neccessary
/// @param track track number to play
void playTrack(uint16_t track)
{
  started = millis();

  if (digitalRead(PIN_MOS) == LOW)
  {
    digitalWrite(PIN_MOS, HIGH);
    delay(50); // wait 50ms for DfPlayer to turn on

    // baud 4800 because the attiny runs at 16mhz (8mhz -> 9600)
    dfmp3.begin(4800);
    dfmp3.setVolume(30);
  }

  dfmp3.playGlobalTrack(track);
}

void loop()
{
  uint8_t adcValue = readADC();

  if (adcValue >= 227 && adcValue <= 237)
  {
    // 10k ohm (3.0V -> adc 232)
    playTrack(1);
  }
  else if (adcValue >= 212 && adcValue <= 223)
  {
    // 18k ohm (2.8V -> adc 217)
    playTrack(2);
  }
  else if (adcValue >= 196 && adcValue <= 206)
  {
    // 27k ohm (2.6V -> adc 201)
    playTrack(3);
  }
  else if (adcValue >= 181 && adcValue <= 191)
  {
    // 38k ohm (2.4V -> adc 186)
    playTrack(4);
  }
  else if (adcValue >= 165 && adcValue <= 175)
  {
    // 50k ohm (2.2V -> adc 170)
    playTrack(5);
  }
  else if (adcValue >= 150 && adcValue <= 160)
  {
    // 65k ohm (2.0V -> adc 155)
    playTrack(6);
  }
  // ending up here every loop where no button was pressed. so basically 99.99% of the time
  else
  {
    // started gets set to millis() everytime a track is played
    if (millis() - started > timeoutMs)
    {
      // sleep if some time has passed without input (see timeoutMs)
      sleep();
    }
  }
}

// sets the device into POWER DOWN mode.you can probably tune it to be more efficient
void sleep()
{
  digitalWrite(PIN_MOS, LOW);

  // pin change interrupt
  PCMSK |= bit(PIN_A);
  GIFR |= bit(PCIF);  // clear any outstanding interrupts
  GIMSK |= bit(PCIE); // enable pin change interrupts

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  power_all_disable(); // power off ADC, Timer 0 and 1, serial interface
  sleep_enable();
  sleep_cpu();
  sleep_disable();
  power_all_enable(); // power everything back on
}

// Interrupt Serviceroutine (Pin-Change-Interrupt)
ISR(PCINT0_vect)
{
  // the SoftwareSerial does not block any interrupt pins anymore and thats why we have to call it from here
  LemonSerial::handle_interrupt();
}

// ADC interrupt service routine
ISR(ADC_vect)
{
  ; // noop
}

```

This is a schematic from how everything is set up now. This is the first time I drew a *real* schematic so I hope it's clear whats going on

---
Tags: attiny, current, adc, attiny85, mosfet
---


# Question
Title: How to make 2 lidar lite v3 work with 1 Arduino?
I'm using the code below, but I had no success.

I'm using this connection wire: The photo of the Arduino doesn't show the SCL and SDA pins, but please consider that it has 2 SCL pins and 2 SDA pins in the places where I marked them in the image.

Both sensors are working, however they are mirroring each other's measurements.

That link is from the datasheet: https://static.garmin.com/pumac/LIDAR\_Lite\_v3\_Operation\_Manual\_and\_Technical\_Specifications.pdf

```
#include <Wire.h>
#include <LIDARLite.h>

#define LIDAR1_ADDRESS 0x62 // Endereço I2C do LIDAR Lite 1
#define LIDAR2_ADDRESS 0x63 // Endereço I2C do LIDAR Lite 2

LIDARLite lidar1; // Objeto para o LIDAR Lite 1
LIDARLite lidar2; // Objeto para o LIDAR Lite 2

void setup() {
  Wire.begin();        // Inicializa a biblioteca Wire (I2C)
  Serial.begin(115200);  // Inicializa a comunicação serial

  // Inicializa os objetos dos LIDARs
  lidar1.begin(LIDAR1_ADDRESS); // Inicialização do LIDAR Lite 1
  lidar2.begin(LIDAR2_ADDRESS); // Inicialização do LIDAR Lite 2
}

void loop() {
  int distance1 = lidar1.distance();
  int distance2 = lidar2.distance();

  // Exibe as medições dos LIDARs no Monitor Serial
  Serial.print("LIDAR 1: ");
  Serial.print(distance1);
  Serial.print(" cm | LIDAR 2: ");
  Serial.print(distance2);
  Serial.println(" cm");

  delay(500); // Intervalo entre as leituras
}

```

# Answer
If these are the Garmin Lidar Lite V3, here is a link to their data sheet. On page 5 of the datasheet you'll find instructions for configuring their I2C addresses. If you haven't already done that, it's quite likely that both devices are replying at once to the same query.

If you have done that already, please update your question with that and any other relevant data - such as the manufacturer, if I got that wrong, add any configuration changes you've made.
> 2 votes

---
Tags: arduino-uno, sensors, i2c, 1-wire
---


# Question
Title: SD Card Mount Failed with Waveshare ESP32 using Arduino IDE
I'm currently working on a project using an ESP32 (the Waveshare ESP32 Driver Board), and I am trying to read data from an SD card, but consistently getting a "SD Card Mount Failed" error. I am using the Adafruit SD card reader breakout board and the Arduino IDE.

Here's how I've wired the SD card reader to the ESP32

```
SD card     ESP32
-------     -----
3.3V        3.3V
GND         GND
CLK         pin 18 (SCK)
DO          pin 19 (MISO)
DI          pin 23 (MOSI)
CS          pin 5 (SS)

```

And here's the relevant code I'm using to setup and test the SD card:

```
#define SCK  18
#define MISO  19
#define MOSI  23
#define CS  5

int setup_sd_card() {

  SPIClass spi = SPIClass(VSPI);
  spi.begin(SCK, MISO, MOSI, CS);

  if (!SD.begin(CS,spi,80000000)) {
    Serial.println("ERROR: SD Card Mount Failed");
    return -1;
  }
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    Serial.println("ERROR: No SD card attached");
    return -1;
  }

  // Code to print out SD card details...

  return 1;
}

```

I've triple-checked my wiring but the code always fails at `if (!SD.begin(CS,spi,80000000))`. I've tried 3 different SD cards of different sizes, all formatted to FAT32 (64GB, 256GB, 1024GB)

Could the issue be related to the ESP32 not being a stock one because it has some hardware for driving an e-paper screen? Here is the schematic: https://www.waveshare.com/w/upload/8/80/E-Paper\_ESP32\_Driver\_Board\_Schematic.pdf

Can anyone suggest what might be the issue or what else I could try to debug this problem? Any help would be greatly appreciated.

# Answer
> 1 votes
There are at least two problems with your code.

First I think you have a typo in the frequency. Default frequency is 4 MHz, but your parameter in `begin` is 80 MHz, which I doubt will work.

You initialize the `spi` object on the stack in the function and then supply it to the SD instance. The `spi` object on stack will be removed when the function ends and the SD object will crash. It has to be an allocation on heap as `SPIClass* spi = new SPIClass(VSPI);` or a global variable `SPIClass spi(VSPI);`.

And since you use the default pins of VSPI you can use just `spi.begin()` without the pin numbers.

# Answer
> 0 votes
The issue turned out to be a faulty SD card.

I had tried other SD cards but must have used incorrect wiring for them.

EDIT: Here is the updated code:

```
#define CS        5
#define SCK       18
#define MOSI      23
#define MISO      19

SPIClass spi(VSPI);

int setup_sd_card() {
  spi.begin(SCK, MISO, MOSI, CS);

  if (!SD.begin(CS,spi,4000000)) {
    Serial.println("ERROR: SD Card Mount Failed");
    delay(1000);
    return -1;
  }
  Serial.println("Finished initializing SD card. Getting card type...");

  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    Serial.println("ERROR: No SD card attached");
    delay(1000);
    return -1;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC){
    Serial.println("MMC");
  } else if(cardType == CARD_SD){
    Serial.println("SDSC");
  } else if(cardType == CARD_SDHC){
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));

  Serial.println("SUCCESS! (SD CARD)");

  return 1;
}

```

---
Tags: esp32, spi, sd-card
---


# Question
Title: When I use AnalogueWrite the voltage doesn't vary properly
I have a project where I want to control a pump, I use an Arduino, connected to a driver L298N and I will connect the pin 5, 6, 7 of the arduino to the pin IN2, IN1, ENA of the driver respectively and the motor will be connected to the output

My materiel :

* Arduino Uno R3
* Multimeter
* Arduino IDE 2.1.1

The issue : When I use the function analogWrite the voltage vary only between two value (0v or 5.5v). The pin used was the Digital pin n°7, noted in the code 7.

The code :

```
#define PUMP_DIR_1 5
#define PUMP_DIR_2 6
#define PUMP_PWM 7
#define INVERTED 0

void setup() {
  Serial.begin(9600);
  pinMode(PUMP_PWM, OUTPUT);
}

void set_pump_speed(int speed){
  Serial.print("Set speed ");
  Serial.print(speed);
  Serial.print("\r\n");
  analogWrite(PUMP_PWM, speed);
}

void loop() {
  set_pump_speed(255);
  delay(3000);
  set_pump_speed(0);
  delay(3000);
  set_pump_speed(125);
  delay(3000);
}

```

As output I obtained :

> 00:32:17.184 -\> Set speed 0
> 00:32:20.175 -\> Set speed 125
> 00:32:23.178 -\> Set speed 255
> 00:32:26.182 -\> Set speed 0
> 00:32:29.197 -\> Set speed 125
> 00:32:32.201 -\> Set speed 255

From the mutlimeter I obtained :

> 0v when speed = 0
> 0v when speed = 125
> 5.5v when speed = 255

The arduino is not wired to anything

# Answer
> 1 votes
Pin 7 isn't a PWM pin. Use, say, pin 6 and you will get correct results. The PWM pins are marked with a "~" on the board.

---
Tags: voltage, analogwrite
---


title: NodeMCU V3 GOT OVERHEATED AND DIED

text:
# Question
Title: NodeMCU V3 GOT OVERHEATED AND DIED
My NodeMCU V3 got overheated and died. Please help me figure out what i did wrong.

Brief Desrip: Project is an RC Car on ESPNOW Protocol. Transmitter setup have an Arduino Nano to take values from Two analogue joysticks and sends to a NodeMCU through Tx & Rx Pins, which then Transmits the values to the NodeMCU V3 in my Receiver (An RC CAR) over ESPNOW Protocol. Transmitter side is working perfect.

But, the NodeMCU V3 in my Receiver setup has got overheated and Died during a full throttled action. Here I am attaching the wiring diagram of the receiver setup. Please help me figure out whether there is any issues with the wiring.

# Answer
Based on https://lastminuteengineers.com/l298n-dc-stepper-driver-arduino-tutorial/, you have wired your servo incorrectly. The third pin on the bottom blue connector (VSS) is the second input, not the output.

I can only speculate what happened, but I suspect that the servo tried to draw power from the D4 pin which overloaded and fried some internal circuitry of the ESP8266.
> 1 votes

---
Tags: esp8266, power, nodemcu, servo, l298n
---


title: Read binary file on SD card

text:
# Question
Title: Read binary file on SD card
Why I can't read the last byte in the file when I use the Arduino ide code? The code in cpp is work without any mistakes. This is my code on Arduino ide:

```
  vector<unsigned char> text;
  unsigned char textseg;
  in_file.read(&textseg,1);
  while (in_file.available()){
      text.push_back(textseg);
      in_file.read(&textseg,1);
  }

```

And this is cpp code:

```
vector<unsigned char> text;
unsigned char textseg;
in_file.read(reinterpret_cast<char*>(&textseg), 1);
while (!in_file.eof())
{   text.push_back(textseg);
    in_file.read(reinterpret_cast<char*>(&textseg), 1);
}

```

# Answer
> 1 votes
Your loop seems to be out-by-one. I would prefer:

```
  vector<unsigned char> text;
  unsigned char textseg;
  while (in_file.available()){
      in_file.read(&textseg,1);
      text.push_back(textseg);
  }

```

Why read a byte, as you did, before you know if it is available?

In the Standard C++ library, `eof()` is true if a read fails, however in the Arduino `available()` means a byte is available to be read. They are not directly swappable.

---
Tags: arduino-uno, arduino-ide, c++
---


# Question
Title: Problem compiling sketches for the arduino wavgat uno R33
I am configuring the arduino IDE to be able to compile and upload sketches for the arduino wavgat uno R3. I have installed the Arduino IDE, as well as the required drivers for the board. I also have downloaded the zip containing the "hardware" and "librairies" folder that i copied into the "Arduino" folder.

In the IDE, I can select the wavgat uno R3 as a board and the board is detected by the IDE.

However, when I try to compile any sketch, I get the following error message :

```
avr-gcc: error: C:\Users\henry\AppData\Local\Temp\arduino\sketches\F2EF7F804783EB75A0A6457CF6D8C244/core\core.a: No such file or directory

exit status 1

Compilation error: exit status 1

```

I seems to be a problem related to the compilation. Is there something related to the compilation for the wavgat uno R3 that I forgot ?

Thank you in advance

# Answer
> 2 votes
The problem was solved by using a specific version of the arduino IDE, the 1.8.15. You have to install the drivers and copy the correct driver files in the Arduino folder. The program then compile correctly and can be uploaded to the wavgat.

Also, when working on the wavgat nano, you have to select "WAVGAT UNO R3" as the board type, and not "WAVGAT NANO 3.0" as you might first think.

---
Tags: compilation-errors, installation
---


# Question
Title: How to listen to multiple server ports with ESP8266?
I'm using WeMos D1 R2. I'm trying to listen to both ports 1992 and 1993. This is my current code: #include

```
WiFiServer server_1992(1992);
WiFiServer server_1993(1993);

void setup() {
    Serial.begin(9600);
    WiFi.begin("MySSID", "MyPassword");
    while (WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print(".");
    }
    Serial.println(" connected");

    server_1992.begin();
    server_1992.setNoDelay(true);
    server_1993.begin();
    server_1993.setNoDelay(true);
}

void check_server(WiFiClient* client, WiFiServer* server, const char* text){
    if (client->connected()) {
        if (client->available()){
            unsigned char c[250];
            client->readBytes(c, 1);
            Serial.print(c[0]);
            Serial.print(" ");
        }
    } else {
        client->stop(); //Adding it here like Juraj said. Not tested.
        *client = server->available();
        if (*client) Serial.print(text);
    }
}

void loop() {
    WiFiClient client_1992, client_1993;
    while (1){
        check_server(&client_1992, &server_1992, "1992 connected \n");
        check_server(&client_1993, &server_1993, "1993 connected \n");
    }
}

```

The problem is when the client(s) disconnect from the hotspot, my code keeps waiting for data forever without trying to acquire new client (with `client = server->available();`).

**Solution:** for now I ask the client "Hey are we still connected?" every few seconds and manually kick the client out if it doesn't reply. More on this

Sorry if it's wrong to link other question here, I just hope people who have the same problem as mine can find the solution.

# Answer
Use the client.status() function to check if the client is connected Returns 4 if connected and 0 if not I don't have detailed information about its use and I found it by chance You can check other output modes of this function If you get any other information, please let me know.

```
void loop()
{

  WiFiClient client_8080;
  WiFiClient client_8081;

  delay(200);
  Serial.println(client_8080.status());
  Serial.println();
  Serial.println();

  while (1)
  {

    if(client_8080.connected())
    {

      delay(200);
      Serial.println(client_8080.status());
      Serial.println();
      Serial.println();

      while (client_8080.available())
      {

        delay(200);
        Serial.println(client_8080.status());
        Serial.println();
        Serial.println();

        Serial.print(client_8080.available());
        char Buffer_8080 = client_8080.read();
        Serial.println(Buffer_8080);
        client_8080.println(Buffer_8080);

      }

       while (Serial.available())
      {
        client_8080.print(Serial.available());
        client_8081.print(Serial.available());
        char Buffer_Serial = Serial.read();

        client_8080.println(Buffer_Serial);
        client_8081.println(Buffer_Serial);
      }

    }else if (!client_8080.connected())
    {

       Serial.println(client_8080.status());
       Serial.println();
       Serial.println();

      client_8080 = server1.available();

       Serial.println(client_8080.status());
       Serial.println();
       Serial.println();

      Serial.println("server lisening to port 8080 ");

    }

    //_______________________________________________

    if(client_8081.connected())
    {
      while (client_8081.available())
      {

        Serial.print(client_8081.available());
        char Buffer_8081 = client_8081.read();
        Serial.println(Buffer_8081);
        client_8081.println(Buffer_8081);

      }

      while (Serial.available())
      {
        client_8080.print(Serial.available());
        client_8081.print(Serial.available());
        char Buffer_Serial = Serial.read();

        client_8080.println(Buffer_Serial);
        client_8081.println(Buffer_Serial);
      }

    }else if (!client_8081.connected())
    {
      client_8081 = server2.available();

      Serial.println("server lisening to port 8081 ");

    }

  }
}

```
> -2 votes

---
Tags: esp8266, tcpip, iot
---


# Question
Title: How to upload already compiled code when no changes were made?
How do I use the Arduino IDE to upload the last compiled code? I don't want to have to wait 2 minutes to upload compiled code when there are no changes. It's a big codebase, where I frequently make one or two small changes and have some issue with my MCU or USB cables. Frequently the controller on my boards are damaged due to some overcurrent issue because of the high-heat nature of **3D printing**. Having to wait an extra 2-5 minutes every time I experiment with this is unacceptable.

Obviously, there is a keyboard shortcut to do this that I'm unaware of, because otherwise this would add hours to development.

Please tell me how I can get the Arduino IDE to just 'upload without compiling' my sketch.

# Answer
You can upload hex file to your board from command line without Arduino IDE.

To get the hex file, use in Arduino IDE in menu the command "Export compiled binary". It will save the hex file next to the ino file.

I assume your board in printer has AVR MCU. Then you can use avrdude from command line to upload the hex file again and again without any compilation.

The avrdude command on Windows is (if started from the sketch's folder):

```
%LOCALAPPDATA%\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -C%LOCALAPPDATA%\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -carduino -PCOM11 -b115200 -D -Uflash:w:Blink.ino.hex:i

```

The command line is for the Blink sketch and for AVC boards package 1.6.21
> 3 votes

# Answer
This is what I have done. In the arduino IDE settings panel, turn on the "Show verbose output during compile and upload". This way whenever you are doing verify and upload you can see all the command that Arduino has performed. Now after you hit Verify or Upload it, you can copy the last command before the upload, such as

"/Users/fang/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude" "-C/Users/fang/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" -v -V -patmega32u4 -cavr109 "-P/dev/cu.usbmodem21101" -b57600 -D "-Uflash:w:/private/var/folders/xb/4609zdjx4tn3bv\_6jh2nym\_r0000gn/T/arduino/sketches/7972D54945A751059BF3114D2057C2B6/sketch\_aug4c.ino.hex:i"

Now, when you need to upload without compiling again, just paste this line to the Terminal, it'll do the rest for you. Essentially you can see Arduino IDE is just a wrapper around these commands.

**Update:**

I also found another way which is kinda of different but more effective. If you happen to use Visual Studio Code, you can also try the PlatformIO plugin which can compile and upload code separately, I wrote an article about it here, https://windmaomao.medium.com/use-platformio-to-write-arduino-code-3c957c4e58b5
> 2 votes

---
Tags: arduino-ide, compile
---


# Question
Title: Updating the firmware of Arduino Mega2560
I wanted to connect my Arduino board to MATLAB although it recognized the Arduino board, I kept receiving the error that said:

"Internal error: The initialization of the server code is incorrect."

I got the recommendation of updating my Arduino board's firmware;
So I connected my board to my pc and opened Arduino IDE; It said that the Arduino Mega or Mega 2560 on com6 is connected.

I even uploaded the blink example to my board to make sure that it was connected and fully functioning. Which it was.

But in the above bar in Arduino IDE, "Tools" menu, when I select the "WIFI101/ Firmware Updater" It says that no supported board connected. What should I do now?

*P.S: I'm currently using Arduino IDE version 2.1.1 and MATLAB 2023a on Windows 11.*

I'm sorry, I'm really new to this and would appreciate your help.

# Answer
https://www.mathworks.com/help/supportpkg/arduinoio/ug/configure-setup-for-arduino-hardware.html

This link has the instructions for connecting the Arduino board. Look right at the first where it talks about the USB connection. Step 2 where you click program is the step where you are loading the server firmware onto the Mega. That's the bit it sounds like you're missing.
> 1 votes

---
Tags: firmware, matlab
---