# Question
Title: How execution time of code instructions influences signal between Arduino and DHT11?
I am exemining code for DHT11 from CircuitGeeks, variant without using lib. The problem is a mismatch between DHT11/DHT22 protocol and signals, which are read from sensor in scetch. Despite this, sketch is working and I would like to find out how.

```
#define DHT11_PIN   12

unsigned long TON_TIME = 0;
unsigned long TOFF_TIME = 0;

unsigned char data_byte[5];
unsigned int data_packet[40];
unsigned char bit_data = 0;
unsigned char checksum_byte = 0;
int bit_counter = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 Humidity & Temperature Sensor\n");
  delay(1000);//Wait before accessing Sensor
}

void loop() {
  pinMode(DHT11_PIN, OUTPUT);
  digitalWrite(DHT11_PIN, LOW);
  delay(18);
  digitalWrite(DHT11_PIN, HIGH);
  pinMode(DHT11_PIN, INPUT_PULLUP);

  TOFF_TIME = pulseIn(DHT11_PIN, LOW);
  if (TOFF_TIME <= 84 && TOFF_TIME >= 76) {
    while (1) {
      TON_TIME = pulseIn(DHT11_PIN, HIGH);
      if (TON_TIME <= 28 && TON_TIME >= 20) {
        bit_data = 0;
      }
      else if (TON_TIME <= 74 && TON_TIME >= 65) {
        bit_data = 1;
      }
      else if (bit_counter == 40) {
        break;
      }
      data_byte[bit_counter / 8] |= bit_data << (7 - (bit_counter % 8));
      data_packet[bit_counter] = bit_data;
      bit_counter++;
    }
  }
  checksum_byte = data_byte[0] + data_byte[1] + data_byte[2] + data_byte[3];

  if (checksum_byte == data_byte[4] && checksum_byte != 0) {
    Serial.println("Humidity: ");
    for (int c = 0; c <= 7; c++) {
      Serial.print(data_packet[c]);
    }
    Serial.print("\t");
    for (int c = 0; c <= 7; c++) {
      Serial.print(data_packet[c + 8]);
    }
    Serial.print("\t");
    Serial.print(data_byte[0]);
    Serial.print("%");
    Serial.println(" ");

    Serial.println("Temperature: ");
    for (int c = 0; c <= 7; c++) {
      Serial.print(data_packet[c + 16]);
    }
    Serial.print("\t");
    for (int c = 0; c <= 7; c++) {
      Serial.print(data_packet[c + 24]);
    }
    Serial.print("\t");
    Serial.print(data_byte[2]);
    Serial.print("C");
    Serial.println(" ");

    Serial.println("Checksum Byte: ");
    for (int c = 0; c <= 7; c++) {
      Serial.print(data_packet[c + 32]);
    }
    Serial.println(" ");
    Serial.print("CHECKSUM_OK");
    Serial.println("");
    Serial.println("");
  }

  bit_counter = 0;
  data_byte[0] = data_byte[1] = data_byte[2] = data_byte[3] = data_byte[4] = 0;
  delay(1000);
}

```

Looking into the code there is 18 ms of LOW level for initialization. Then about 40 us of HIGH level, it can be considered as time between `digitalWrite(DHT11_PIN, HIGH);` and `TOFF_TIME = pulseIn(DHT11_PIN, LOW);` instructions. But then after 80 us of LOW level `TOFF_TIME = pulseIn(DHT11_PIN, LOW);` it should be 80 us HIGH level. Instead of this, the code is being continued by conditions for checking pulses length, which are responsable for data bits. If pulse length is 26-28 us it's 0, if 70 us - it's 1. I understand that with `TON_TIME = pulseIn(DHT11_PIN, HIGH);` instruction we will find length of HIGH pulses of data bits only.

Why 80 us HIGH level is passed, however this doesn't impact on interaction with sensor? Does it pass in time of executing instructions from  `if (TOFF_TIME <= 84 && TOFF_TIME >= 76)` to `TON_TIME = pulseIn(DHT11_PIN, HIGH);` ?

# Answer
> 2 votes
At the end of the 80 µs LOW from the HDT11, `pulseIn(DHT11_PIN, LOW)` returns. At this point in time, the data line is HIGH, somewhere near the beginning of the positive 80 µs pulse. Now, the code executes the first `pulseIn(DHT11_PIN, HIGH)`.

You cannot measure the length of a positive pulse if you missed the rising edge. Thus, as `pulseIn()` finds the line HIGH, it will first wait until it transition to LOW, then wait until in transitions back to HIGH, and only then starting timing.

See for example the implementation of the counting loop in the AVR core, or rather the C code that served to generate the assembly implementation. It has three waiting loops:

* wait for any previous pulse to end
* wait for the pulse to start
* wait for the pulse to stop

---
Tags: pulsein, dht11
---


title: Confusion on bit shifting

text:
# Question
Title: Confusion on bit shifting
I am trying to read-in two separate, 3 byte messages over CAN, add them together, and send back out over CAN, on a CANBED V1 which uses a Leonardo.

My confusion is using bit shifting.

If I attempt to shift 1 by 1..14 bits I seem to understand,

uint32\_t hdbs = 1 \<\< (14) ; Serial.println(hdbs, BIN);

this codes gives me 100000000000000 in the display window if printing binary or 16384 decimal.

But if I try a bit shift of 15 or more uint32\_t hdbs = 1 \<\< (15) ; Serial.println(hdbs, BIN);

I am now confused as I get

11111111111111111000000000000000 or 4294934528 in decimal

What basic concept am I missing? I tried using unsigned long, long, etc.,

If I do some simple math and use hdbs = 8 * 4095 I get the correct answer of 32760, but when I try 8\*4096 I get 4294934528, which should be 32768 (which seems like would exceed a 16 bit unsigned, but I thought I was declaring hdbs as a 32 bit variable.

# Answer
This is really more of a C++ question, but I don't know whether or not you know that. Roughly speaking, in C, C++ (and so "Arduino" language) expressions are evaluated for types in parallel with their values from the inside out following operator precedence rules much like regular algebra.

You must ensure the type on the left-hand-side of the `<<` is already prepared to accept the resulting value. E.g.:

```
uint32_t hdbs = static_cast<uint32_t>(1) << 15;

uint32_t hdbs = (uint32_t)1 << 15;

uint32_t hdbs = uint32_t(1) << 15;

uint32_t hdbs = uint32_t{1} << 15;

uint32_t hdbs = 1UL << 15;

```

---

`1` is of type `int`, which for Leonardo is a 16-bit type. Usually when binary operators like `+` or `/` are evaluated for result type, the both sides are taken into account in something called usual arithmetic conversions. For `<<` it just looks at the type of the thing being shifted and takes that. So your result of `1 << 15` is being evaluated in an `int`, which cannot store that value on the AVR. The fact that you later use that in initializing `uint32_t hdbs` is beside the point when calculating `1 << 15` itself.

I would have tentatively guessed you'd get 0x8000 which when converted to 32-bit under sign extension would have resulted in `11111111 11111111 10000000 00000000`. But, an attempt to overflow a signed integer type like this is undefined. It cannot be reliability expected to produce any particular behaviour, let alone value.

Had you been using 32-bit chip like an ARM or ESP32/ESP8266, this would have just worked because the `int` type there is 32-bit.
> 0 votes

# Answer
This is how C type cast works.

C expressions are of signed type by default. If an expression type has too small bit length than it may get also negative due to overflow (into the high bit which is also a sign bit).

Whenever a signed expression needs to fit into more bits, it gets expanded into longer signed value first (which is effectively the same as duplicating the high bit as many times as needed). And only after that, it will be converted to unsigned (which is basically no-op).

So to overcome this thing you need to change cast order by making `1U` or `1UL` instead of just `1`. Then you will never run into signed values and, so, no sign bit expansion.
> 0 votes

---
Tags: bitshift
---


# Question
Title: How to send multiple and different bytes via SPI using custom function
I need to send multiple bytes via SPI to a controller. I would like to have a function which I can use for doing that as I need to do some other things with it (timing, setting pin states etc.).

The issue is, that I need to pass a variying size of bytes and also I need to change these bytes in the code.

My not compiling try to do it:

```
const int CS = 9;
const int A_0 = 7;
#define STOP 0xFFF

void setup() {
 pinMode(CS, OUTPUT);
 pinMode(A_0, OUTPUT);
 digitalWrite(CS, 0);
 digitalWrite(A_0, 0);
 SPI.begin();
 SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
 DispData(1, (int []){0xE3, 0xE4, 0x00, 0x122, STOP});
 SPI.endTransaction;
 //some code
 SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
 DispData(1, (int []){0xE6, 0xE7, 0x02, STOP});
 SPI.endTransaction;
}

void DispData(int chip, int data[] ){
  digitalWrite(CS, chip);
  digitalWrite(A_0, 0);
  int i=0;
  delayMicroseconds(12);
  digitalWrite(A_0, 1);
  delayMicroseconds(7);
  while(data[i] != STOP)
  {
    SPI.transfer(data[i]);
    i++;
  }
}

```

# Answer
After more searching I found one solution, using `const int` instead of `int`:

```
const int CS = 9;
const int A_0 = 7;
#define STOP 0xFFF

void setup() {
 pinMode(CS, OUTPUT);
 pinMode(A_0, OUTPUT);
 digitalWrite(CS, 0);
 digitalWrite(A_0, 0);
 SPI.begin();
 SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
 DispData(1, (const int []){0xE3, 0xE4, 0x00, 0x122, STOP});
 SPI.endTransaction;
 //some code
 SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
 DispData(1, (const int []){0xE6, 0xE7, 0x02, STOP});
 SPI.endTransaction;
}

void DispData(int chip, const int data[] ){
  digitalWrite(CS, chip);
  digitalWrite(A_0, 0);
  int i=0;
  delayMicroseconds(12);
  digitalWrite(A_0, 1);
  delayMicroseconds(7);
  while(data[i] != STOP)
  {
    SPI.transfer(data[i]);
    i++;
  }
}

```
> 0 votes

---
Tags: arduino-uno, spi, c, array
---


# Question
Title: How to make a stepper motor's speed follow a sine wave
I'm trying to have the rotational speed of a stepper follow that of a sine wave with a period of x seconds. So it starts at a speed of 0 at 0°, picks up and peaks at 90°, slows back down to 0 at 180°, back up to peak speed at 270°, and back to 0 at 360°, if that makes sense. I'm trying to have the period of the rotation adjustable as well.

Right now I'm having trouble even getting it to spin with what I have now. if I start at 0 speed it doesn't step and therefore doesn't continue with the sketch, or at least I think that's what's happening. Any advice on how to do this would be appreciated.

I'm using the equation (topSpeed) * sin((pi * time) / period) for the wave.

```
#include <Stepper.h>

const int stepsPerRevolution = 200.000;
const float pi = 3.14159265358979;
const int period = 5; // Seconds
const int topSpeed = 100; // RPM

Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

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

void loop() {
  for (int tStart = millis(); (millis()-tStart) < period;) {
    float speed = topSpeed * (sin((pi * (millis() / 1000.000)) / period));

    if (speed = 0) {
      myStepper.setSpeed(1);
      myStepper.step(1);
    } else {
      myStepper.setSpeed(speed);
      myStepper.step(1);
    }
  }
}

```

# Answer
> 0 votes
**Disclaimer**: This is not intended to be a complete answer, it is only meant to help you with the math.

I find a contradiction in the problem statement:

> it starts at a speed of 0 at 0°, picks up and peaks at 90°, slows back down to 0 at 180° \[...\]

If the speed is a sinusoidal function, then at this point you have completed the positive part of the period. The speed will now become negative (i.e. the stepper will move backwards), and remain negative for the second half of the period.

> back up to peak speed at 270°, and back to 0 at 360°

No. It will reach peak (negative) speed at 90°, and back to zero speed at 0°.

If you really want the stepper to turn always in the same direction, the speed cannot be sinusoidal. What you can do instead is use a sinusoidal function *with an offset*, such that the speed fluctuates between zero and some maximum, instead of fluctuating between ±maximum.

The graph below represents speed as a function of time. The first curve (“sine”) is a movement that rocks back and forth like: 0° → 90° → 180° → 90° → 0°. The “shifted sine” curve is a continuous rotation doing a full revolution with a speed that is always non-negative.

If you want to properly describe the movement, you should integrate the speed in order to find the (angular) position as a function of time. You will find a continuous ramp (because of the shift in the speed) superimposed with a sinusoidal movement, as in this graph:

If that may help, I did the integration for you and found this formula:

angle = 360° × (t/T − sin(4πt/T)/(4π))

where t is the current time and T the rotational period. This can then be differentiated to get the speed:

speed = 360°/T × (1 − cos(4πt/T))

---
Tags: arduino-uno, motor, sine-wave
---


title: beginner 7-segment code using 74hc595

text:
# Question
Title: beginner 7-segment code using 74hc595
Was trying this basic circuit using 74HC595 but 7-segment doesn't light at all in Anode Common. When switched to Cathode common, it just stays at 9 instead. Trying to achieve changing value from 0-9 after clicking the button. The code I used:

```
int data = 0;
int clock = 2;
int latch = 1;
int button = 3;

byte segment[10] = {B11111100, //0
                     B11000000, //1
                     B11011010, //2
                     B11110010, //3
                     B01100110, //4
                     B10110110, //5
                     B10111110, //6
                     B11100000, //7
                     B11111110, //8
                     B11100110, //9
                    };
void setup()
{
  pinMode(button, INPUT);
  pinMode(data, OUTPUT);
  pinMode(clock, OUTPUT);
  pinMode(latch, OUTPUT);
}

void loop()
{
  digitalWrite(latch, LOW);
  shiftOut(data, clock, LSBFIRST, segment[9]);
  digitalWrite(latch, HIGH);
}

```

# Answer
> 0 votes
If the display works when wired up for common cathode then likely it is a common cathode LED display.

Going on, it would appear that the only thing this code does is write out data to display the number "9" over and over again:

```
  shiftOut(data, clock, LSBFIRST, segment[9]);

```

To test the display, add lines with different indices into the array which contains the 7 segment display patterns. For example:

```
  shiftOut(data, clock, LSBFIRST, segment[0]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[1]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[2]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[3]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[4]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[5]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[6]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[7]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[8]);
  delay(1000);
  shiftOut(data, clock, LSBFIRST, segment[9]);
  delay(1000);

```

... should cycle through numbers 0 through 9 then repeat.

Adding a momentary push button is difficult because of mechanical switch bounce. Because the processor can sample the switch very fast, random switch bounces can make a project such as this one appear broken. Displaying what appears to be random numbers.

Read how to de-bounce a push button here in the arduino.cc document pages.

The best approach to writing a good program is to remove all calls to delay(). Instead, after reading how to de-bounce a switch, consider creating a state machine where each button push will advance to the next state. Create 10 states where each state display a different number 0 through 9.

---
Tags: arduino-uno
---


# Question
Title: NodeMCU 1.0 - Port D3, relay and pump does not boot
I'm trying to create a watering system using a NodeMCU 1.0, a relay and some pumps.

Currently I've port D0, D1, D2, D5, D6, D7, D8 already in use. I'm trying to use the port D3 (GPIO0) as follows, but when I plug or reboot the NodeMCU, sometimes (!) at boot the relay starts, the pump starts watering and the board does not finish the boot.

The only way to start the board are the following:

* Unplug the current from relay
* Unplug D4 until boot ends
* Disconnect the pump from relay

I tried to substitute the pump with a led and a resistor and I've no problem. I tried also to put a resistor before the pump and it starts (but the pump does not work).

At boot my first command (after defining variable and object is setting D3 as HIGH)

```
#define D0 16
#define D1 5
#define D2 4
#define D3 0
#define D4 2
#define D5 14
#define D6 12
#define D7 13
#define D8 15
#define A0 17
#define TX 1
#define RX 3
#define MSG_BUFFER_SIZE 128

// Initialize clients
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
char msg[MSG_BUFFER_SIZE];
int iteration = 0;
int ID = -1;
int first_run = 1;

void setup() {
  //Initial setup
  digitalWrite(D3, HIGH);
  pinMode(D3, OUTPUT);
  delay(4000);
  Serial.begin(9600);
  ...
}

```

I really don't understand where is the problem.

# Answer
D3 is connected to the FLASH button on the board. It is used to control the boot mode on startup. If this pin is LOW on startup it will stay in flash mode, ready to receive a new program. If it is high on startup it will then execute its saved program (normal boot).

What probably happens here is, that your relay board pulls D3 to LOW, when its connected (probably only a bit stronger than the NodeMCUs builtin pullup resistor). Probably it has a pulldown resistor on its input pin (to keep the relay open by default). The NodeMCU then sees D3 being LOW on startup and stays in flash mode, never executing your code. To let the NodeMCU execute your code, D3 needs to be HIGH at startup! If this happens randomly, then the pullup and pulldown resistors are probably have similar values, so that the noise in the system can switch the state of the pin.

You now have different possibilities:

* You could remove the pulldown resistor from your relay board, so that the pullup resistor on the NodeMCU can pull the pin to HIGH during start, until your program will set it to LOW again. Then you need to live with the fact, that the relay will be ON during startup of the NodeMCU, running your pump in that time.
* You can do the above, but also move the pump connections to the NC (Normally Closed) contact of the relay. This means the pump is activated, when D3 is LOW, and deactivated, if it is HIGH, so the logic is inverted. D3 being HIGH on startup would then mean the pump isn't running. The caveat is, that if the pumps power is on, which the NodeMCU/relay power is off, the pump will be running.
* You can use a different pin for this function. One that is free of a special boot function. We don't know, what you are doing with the other pins. D3 would be a good fit for an input pin, that needs the pullup resistor (like for connecting a button). Or an output pin, where the state at startup is not dictated by the outside device.
> 1 votes

---
Tags: esp8266, nodemcu, relay, pump
---


title: Serial com register formula

text:
# Question
Title: Serial com register formula
i am working on a atmega328p, learning to uses its registers instead a coding with common arduino code.

i've found this formula to get the baud rate on the Serial port (using USART protocol) :

how could i type this in C language ? or specifically in the arduino IDE ?

--

i made some researches and discovered that it could write it that way :

```
float _baudrate = (16000000/(16*9600));

```

then i convert the value to int (because i need an integer value)

```
int _baudrate_int = (int)_baudrate;enter code here

```

all this for a 9600 baudrate of course.

But when i do this, i don't understand why, the code does not calculate it right. i'm supposed to have 103-104 and i get 710.

it will work if i type (16\*9600) product manually. Which is 153600

```
float _baudrate = (16000000/153600);

```

then i get the right baudrate result. but what if i want the code to calculate everything ? how can i do ?

where's my mistake with this line of code ?

```
float _baudrate = (16000000/(16*9600));

```

# Answer
> 0 votes
Here:

> ```
> float _baudrate = (16000000/(16*9600)
>
> ```

other than the missing parenthesis and semicolon, you have an integer overflow. The issue is that, on AVR-based Arduinos, an `int` is only 16-bits long. The constants `16` and `9600` being small enough to fit in an `int`, they are implicitly given the `int` type. Then, their multiplication is also done with the `int` type, and the product overflows and wraps modulo 216 to 22528.

You can fix this by giving either or both of these numbers the `L` suffix, which will make them use the `long` data type. Alternatively, if you want a floating point calculation, you can use `.0` as a suffix.

Not that the avr-libc provides a header file with some macros for this calculation, which is then done by the preprocessor: \<util/setbaud.h\>: Helper macros for baud rate calculations. You can use them as follows:

```
#define BAUD 9600
#include <util/setbaud.h>

void set_baud_rate() {
    UBRR0 = UBRR_VALUE;
#if USE_2X
    UCSR0A |= _BV(U2X0);
#else
    UCSR0A &= ~_BV(U2X0);
#endif
}

```

**Edit:**

To answer the question in a comment: yes, the `L` suffix creates a `long` constant, and is thus similar to creating a `long` variable (except it is a constant instead of a variable).

I suggest you take a look at the line below from setbaud.h. In the case where U2X0 is not needed, the baud rate register value is computed as:

```
#define UBRR_VALUE (((F_CPU) + 8UL * (BAUD)) / (16UL * (BAUD)) -1UL)

```

A few things to note:

* It is all computed with integers, no floating point. Actually, the computation is performed by the compiler, at build time, not by the Arduino.
* The suffix `UL` is for `unsigned long`
* Adding 8 before dividing by 16 is a way to round the result to the nearest integer, instead of rounding to zero. Ties are rounded up.
* There is `-1UL` at the end, as this is required by the UART hardware (it is in the formula from the datasheet).

---
Tags: c
---


title: Flash ESP8266 from SPIFFS filesystem

text:
# Question
Title: Flash ESP8266 from SPIFFS filesystem
I'm searching for a way to flash an ESP8266 *programmatically*, i.e, without user interaction (and especially without the Arduino IDE).

Assuming I can put the program to be flashed on the SPIFFS filesystem, is there a way to flash the ESP with that file?

# Answer
Yes, it is (or at least WAS possible a few years ago) to have an ESP8266 self-program if you can get the file onto the file system, by using the `Update` core that is used by OTA and httpUpdate. This was a example program to do it, but I don't know if it still works. I would also suggest that you look at using LittleFS instead of SPIFFS as the latter has been depreciated.

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <FS.h>

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

  SPIFFS.begin();
  Dir dir = SPIFFS.openDir("/");

  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, LOW);

  File file = SPIFFS.open("/firmware-update.bin", "r");

  uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
  if (!Update.begin(maxSketchSpace, U_FLASH)) { //start with max available size
    Update.printError(Serial);
    Serial.println("ERROR");
  }

  while (file.available()) {
    uint8_t ibuffer[128];
    file.read((uint8_t *)ibuffer, 128);
    Serial.println((char *)ibuffer);
    Update.write(ibuffer, sizeof(ibuffer));
  }

  Serial.print(Update.end(true));
  digitalWrite(BUILTIN_LED, HIGH);
  file.close();
}

void loop() {
}

```
> 1 votes

# Answer
Yes, it still works, but now you need to pass data as a pointer:

```
Update.write(&ibuffer, sizeof(ibuffer));

```
> -1 votes

---
Tags: esp8266
---


# Question
Title: Very slow to connect to WiFi with ESP32 (minutes, not seconds)
I am having some issues with connecting to WiFi with an ESP32 board. It is very sloooooooooow. The first few times I tried, I left it alone for 20 minutes and it still wasn't able to connect. So I thought it didn't work. So I tried to use MicroPython and ESP-IDF and they both worked, although MicroPython was somewhat slow (~10-20 seconds), but ESP-IDF was instantaneous. Then I went back to Arduino and this time it eventually connected after 260 seconds (\> 4 minutes). Another try took 420 seconds (7 minutes). Has anyone else seen similar issues?

What I have tried:

* Tried another board of the same model to ensure it's not defective.
* Tried a different WiFi AP with the same results.

Although MicroPython and ESP-IDF framework work fine, I am still hoping to stick with Arduino for its simplicity and my hatred for Python, but don't hold it against me if you're fond of it :-).

My board: ESP-WROOM-32(https://www.amazon.com/gp/product/B0B764963C). In Arduino IDE, I'm choosing "ESP32-WROOM-DA Module". I have also tried "uPesy ESP32 Wroom DevKit" with the same results.

The core version is "esp32 by Espressif Systems" 2.0.11.

My network setup: TP-Link EAP225, running as a dedicated AP, not a router. My router is Linksys WRT1900ACS running OpenWrt 19.07.2 r10947-65030d81f3.

The other setup I tried is a D-Link DIR-842 running as both an AP and a router, although I didn't connect the upstream port.

My code:

```
#include <WiFi.h>

const char* ssid = "delingtest";
const char* password = "XxxxxYyyy00";

void setup() {
  Serial.begin(115200);
  Serial.println(millis()); // To time the connection
  Serial.print("Connecting to WiFi network ");
  Serial.print(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  do {
    Serial.print(".");
    delay(5000);
  } while (!WiFi.isConnected());

  Serial.println("done.");
  Serial.println(millis()); // To time the connection
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
}

```

Additional info:

```
Wed Mar 13 16:57:55 2024 daemon.info dnsmasq-dhcp[13394]: DHCPDISCOVER(br-lan) 40:22:d8:78:7a:38
Wed Mar 13 16:57:55 2024 daemon.info dnsmasq-dhcp[13394]: DHCPOFFER(br-lan) 192.168.1.145 40:22:d8:78:7a:38
Wed Mar 13 16:57:55 2024 daemon.info dnsmasq-dhcp[13394]: DHCPREQUEST(br-lan) 192.168.1.145 40:22:d8:78:7a:38
Wed Mar 13 16:57:55 2024 daemon.info dnsmasq-dhcp[13394]: DHCPACK(br-lan) 192.168.1.145 40:22:d8:78:7a:38 esp32-787A38

```

Edit:

I added some code to do a ping to the gateway after establishing the connection:

```
  IPAddress ip (192, 168, 1, 1);
  bool ret = Ping.ping(ip);

```

And timed it. Every ping took about 4-5 seconds. So, it's not just slow to connect to the WiFi network, it's also very slow do ping, and probably to do everything else.

Edit on edit: After turning on verbose logging, I realized that what `ping` actually does is to the effect of `ping -c 5`, with 1 second between pings. So, it does take 4ish seconds no matter what. Originally I thought it only sent one ping per call.

# Answer
Huh, I just tried a 3rd board and I think I have found the root cause. If the board is inserted in a breadboard. It's slooooooow, or even impossible to connect. But if I pull it out, it seems to connect in a few seconds. So, I guess the problem really is the breadboard interfering with the on-board antenna. I'll probably need to get a 32U with an external antenna connector for the final product.
> 4 votes

---
Tags: esp32, wifi
---


# Question
Title: Arduino Uno USB 5 V and external power supply 12 V overheating
I have a issue with my Arduino Uno r3.

I'm not sure why is that happening but I have a 5 V, 18 A power supply to power my LEDs. I connected 5 V from the Arduino to 5 V from the external power supply and I plugged this combined cable to my LEDs. I did the same with GND. On data pin 6 I used a 220 Ω resistor. Also I am using a 12 V power supply to power my Arduino.

At the same time the USB was plugged in.

In and between USB and power some chip is getting hot. I got scared and unplugged the whole Arduino. I am not sure how I should plug this in. It worked fine until I plugged in the external power supply and I was using few LEDs at the time.

This is what it looked like in more understandable way.

Please point out to me what I did wrong.

# Answer
> 1 votes
I suggest you do not use the 12V external power when you are already supplying it with an externally regulated 5V source.

The sole purpose of the 12V input is to provide a 5V regulated supply voltage for the microcontroller. The PCB outputs this on the 5V header. The problem is that you are feeding your external 5V into that pin.

You can either continue powering the Arduino from the 12V supply and disconnect the external 5V from the Arduino (keep the GND from the external 5V conected). Or you can just remove the 12V power source.

It could end up that you have damaged the chip that overheated. If the Arduino still works after doing one of the solutions above, then you may be lucky and not damaged anything.

As a precaution, please measure your external 5V source with a multimeter to make sure it is within specs that Arduino allows.

# Answer
> -1 votes
yes, as the other people say. I'm an electronician , your power supply 5V 18 Amperes , it's to dangerous to connect that to your arduino, the board is not creating to support a great power, if someone of your outputs receives all this unlimited power P = U × I = 5 × 18 = 90 Watts, your board is just able to smell a awful odour. yes, your board burnst with thi great possible intensity. 1. Connect all the several ground together and for supply the arduino take on the USB header . 2. connect your power supply directly on the leds board. warning test that, but it is possible that your board working not more, see all the led of your board and detect step by step if it works normally...

---

---
Tags: arduino-uno, usb, hardware, rgb-led
---


# Question
Title: RPi Pico board, using Earl Philhower RP204 library, SPI problem
I have tried a number of different programs, trying to get any of several SPI connected displays working with the Pico board. All of them seem to not initialize the SPI port properly. For instance, I use the `Adafruit_GFX` library.

The graphicstest demo program I tried unchanged except specifying the ILI9341 chipset, and the following code (obviously the `void setup()` and a few other lines, some commented out are original, to show context, and where in the code my lines have been placed).

The 'code' insert doesn't like the #defines and some of the other lines, sorry for the weird formatting

```
    #define TFT_DC 21

    #define TFT_CS 17

    #define TFT_RST 20

    #define TFT_MOSI 19

    #define TFT_SCK 18

    // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
    // If using the breakout, change pins as desired
    //Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);

    void setup() {
        Serial.begin(115200);
        delay(3000);
        Serial.println("ILI9341 Test!");

        bool ret;
        ////ret = setRX(pin_size_t pin);
        ret = SPI.setCS(TFT_CS);
        Serial.printf("setCS =%s\n", ret ? "T" : "F");
        ret = SPI.setSCK(TFT_SCK);
        Serial.printf("setSCK =%s\n", ret ? "T" : "F");
        ret = SPI.setTX(TFT_MOSI);
        Serial.printf("setTX =%s\n", ret ? "T" : "F");

```

What I get is nothing (0V) on the MOSI pin, and the SCK pin (18) shows the following:

Note that this is with no load, not even mounted on a circuit board, using multiple pico boards, all with the same issue.

I also tried using the TFT\_eSPI library by Bodmer, which is designed for 32 bit processors including the RP2040, and specifically for displays, with roughly the same result, except that the MOSI pin is held high.

BTW, CS and DS pins, both not part of the SPI hardware seem to be working properly, and I did check, the code is compiling for Hardware SPI.

I'm doing something wrong, and I can't figure out what!

# Answer
Ok, my bad, I had two problems. One was I didn't fully check the prototype board I made, there was a whisker short between the clock and the data line, causing the display to not work. The other is that when I looked at the clock line when not plugged into the board, I didn't believe the signal was correct.

Apparently, the Pico has a bit of noise on the clock line sometimes when it starts to send data, which doesn't appear to affect anything, so I haven't looked at it too closely.

The second thing that really blows my mind, is that the clock signal is consistently no higher than between 1.38 to a maximum of 1.48 volts. The Data line seems a bit better at just barely over 2V, but the displays I'm using don't seem to mind. I thought these were 3.3 volt I/O, and expected something at least over 2.5V or so. And since I had an issue with the wiring to the display, I never saw that it was "OK Anyway".

Thanks for everyone's suggestions.
> 0 votes

---
Tags: spi, raspberrypi-pico
---


# Question
Title: How to connect TFT screen (ST7735S) to Arduino?
I'm learning to work with Arduino and I decided to work with a TFT display (driver ST7735S, I connect to Arduino Uno), but I encountered a problem in the form that my contacts are labeled differently than in all the examples I looked at (example - no MOSI contacts/ MISO and CLK, instead of BL - BLK), because of which I am confused and cannot connect the screen correctly - please, help)

Display photo:

# Answer
#### Connections

Connections as follows:

* BLK -\> 5V
* CS -\> D10 (or anything, i.e. D9 - just change the `#define` below)
* DC -\> D9 (or anything, i.e. D8 - just change the `#define` below)
* RST -\> D8 (or anything, i.e. D7 - just change the `#define` below)
* SDA -\> D11
* SCL -\> D13
* VDD -\> 5V
* GND -\> GND

#### Using TFT library

You can use the TFT library:

```
#include <TFT.h>
#include <SPI.h>

```

With the following `#defines`:

```
#define CS 10
#define DC 9
#define RST 8

```

Note: if you used different pins, then just change the numbers.

Create an instance and initialise with:

```
TFT myDisplay = TFT(CS, DC, RST);

myDisplay.begin();

```

#### Using GFX

```
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>

```

With the following `#defines`:

```
#define CS 10
#define DC 9
#define RST 8

```

Note: if you used different pins, then just change the numbers.

Create instance1:

```
Adafruit_ST7735 myDisplay = Adafruit_ST7735(CS,  DC, RST);

```

Initialise with

```
myDisplay.initR(INITR_BLACKTAB);

```

---

### Further reading

#### Footnote

1 Alternative instance creation, which is slower, but you can use different MOSI/SCLK pins (hence the additional `#defines`):

```
#define SCLK 13   // You can change this
#define MOSI 11   // You can change this
Adafruit_ST7735 myDisplay = Adafruit_ST7735(CS, DC, MOSI, SCLK, RST);

```
> 1 votes

---
Tags: arduino-uno, display, tft
---


title: Running ADC triggered by TIMER1_COMPB

text:
# Question
Title: Running ADC triggered by TIMER1_COMPB
I'm trying to run ADC on channel 0 triggered by TIMER1\_COMPB. Everything seem to work ok but basic arithmetics is not working and variables inside ISR and even main loop don't get updated (x == 2 all the time)

Can somebody explain me why is it so? Even volatile variable was not changing... Arduino UNO, IDE v 1.8.6

```
#define SAMPLES_SIZE  205

const int adc_channel = 0;
const uint16_t t1_load = 0;

// 250 corresponds to 8kHz
const uint16_t t1_comp = 25000;

uint16_t samples[SAMPLES_SIZE];
volatile uint8_t samplePos = 0;

static int x = 0;

void initADC() {
  // Init ADC free-run mode; f = ( 16MHz/prescaler ) / 13 cycles/conversion
  ADMUX  = adc_channel; // Channel sel, right-adj, use AREF pin
  ADCSRA = _BV(ADEN)  | // ADC enable
           _BV(ADSC)  | // ADC start
           _BV(ADATE) | // Auto trigger
           _BV(ADIE)  | // Interrupt enable
           _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128:1 / 13 = 9615 Hz
  ADCSRB = _BV(ADTS2) | _BV(ADTS0);              // Timer/Counter1 Compare Match B
  DIDR0  = _BV(adc_channel); // Turn off digital input for ADC pin
}

void initTimer() {
  // Reset Timer1 Control Reg A
  TCCR1A = 0;

// Set CTC mode
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |= (1 << WGM12);

// Set prescaler to 8
  TCCR1B &= ~(1 << CS12);
  TCCR1B |= (1 << CS11);
  TCCR1B &= ~(1 << CS10);

// Reset Timer 1 and set compare value
  TCNT1 = t1_load;
  OCR1B = t1_comp;

// Enable Timer 1 compare interrupt
  TIMSK1 = (1 << OCIE1B);
}

void setup() {
  cli();
  initADC();
  initTimer();
  sei();

  Serial.begin(115200);
}

void loop() {
  while(ADCSRA & _BV(ADIE)); // Wait for audio sampling to finish
  cli();
  x = x + 2;
  Serial.print(samples[0]);
  Serial.print("\t");
  Serial.println(x);
//  for (int i = 0; i < SAMPLES_SIZE; i++) {
//    Serial.println(samples);
//  }
//  samplePos = 0;

  ADCSRA |= _BV(ADIE);       // Resume sampling interrupt
  sei();
}

ISR(ADC_vect) {
  int16_t sample = ADC;

  samples[0] = sample;
//  samplePos++;
  ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off

  if(samplePos >= SAMPLES_SIZE) {
    ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off
  }
}

//ISR(TIMER1_COMPB_vect) {
//}

```

Thanks in advance

# Answer
> 2 votes
Timer1 CTC mode requires you to put the CTC `TOP` value in `OCR1A` (see Table 15.5 in 328P datasheet). You didn't, so the timer is running all the way from 0 to 0xFFFF.

Timer1 ADC trigger mode requires you to put the ADC trigger value in `OCR1B`, which you did, so every time that the timer passes by your trigger value (`t1_comp`), it triggers an ADC conversion.

In short, you need to set both `OCR1A` and `OCR1B` to `t1_comp`.

# Answer
> 1 votes
I've found the solution, it's strange since I enabled CTC mode, but it started to work normally as soon as I reset Timer 1:

```
ISR(TIMER1_COMPB_vect) {
  TCNT1 = 0;
}

```

---
Tags: arduino-uno, interrupt, adc
---


# Question
Title: Slider servo doesn't give the right output
```
#include <HCPCA9685.h>
#include <Wire.h>
#define I2CAdd 0x40

HCPCA9685 HCPCA9685(I2CAdd);
String state = "";

int servo5Pos;
int servo5PPos;

void setup() {
  Wire.begin();
  Serial.begin(4800);
  HCPCA9685.Init(SERVO_MODE);
  HCPCA9685.Sleep(false);
  servo5PPos = 63;

}

void loop(){
  if (Serial.available() > 0){
    state = Serial.readString(); // Read the data as string
    Serial.print(state + "\n");
    // If "Waist" slider has changed value - Move Servo 5 to position
    if (state.startsWith("s5")){
      String stateS = state.substring(2, state.length()); // Extract only the number. E.g. from "s1120" to "120"
      servo5Pos = stateS.toInt(); // Convert the string into integer
      // We use for loops so we can control the speed of the servo
      // If previous position is bigger then current position
      Serial.print(servo5Pos);
      if (servo5PPos > servo5Pos){
        for (int pos = servo5PPos; pos >= servo5Pos; pos--) {
          HCPCA9685.Servo(5, pos);
          delay(20);
        }
      }
      if (servo5PPos < servo5Pos){
        for (int pos = servo5PPos; pos <= servo5Pos; pos++) {
          HCPCA9685.Servo(5, pos);
          delay(20);
        }
      }
      servo5PPos = servo5Pos;
    }
  }
}

```

I'm trying to communicate my MIT Block Code to this Arduino Code, to control a servo via slider. By giving it a ''s5'' text to move the servo. However, I get this output instead when I'm printing the data received. Below is the code output and MIT block code.

# Answer
> 1 votes
**Do not use `Serial.readString()`**

Your main issue here is that you seem to assume that the serial port transmits messages from your computer to your Arduino. It doesn't. It only transmits a stream of bytes (ASCII characters here), which is what the Arduino gets ate the other end.

`Serial.readString()` has no way of knowing where one message ends and the next one begins. Instead, it relies on a very simple heuristic: if one full second has elapsed with no byte being received, then it assumes whatever has been received so far is a complete message. This works reasonably well for messages manually typed at the serial monitor, because you are unlikely to type two messages within one second.

When you move the slider, however, your block code sends messages in quick succession: “s539.7”, then “s540.8”, then “s543”... The Arduino then receives a string of characters: `'s'`, `'5'`, `'3'`, `'9'`, `'.'`, `'7'`, `'s'`, `'5'`, `'4'`, `'0'`, `'.'`, `'8'`, `'s'`, `'5'`, `'4'`, `'3'`, ... This is interpreted as a single message by `Serial.readString()`.

**Solution**: Use an “end of message” indicator instead of (or in addition to) the “start of message” indicator. The characters CR (`\r`) and LF (`\n`) are popular choices. You can then use `Serial.readStringUntil()` to get a full message.

Or, better yet, do not use the `String` class at all. See Reading Serial on the Arduino.

---
Tags: bluetooth, servo
---


# Question
Title: ESP-WROOM-02 with on-board 18650 battery. How to charge it?
I have a ESP-WROOM-02 module with on-board 18650 battery. V+ and GND are exposed on the board.

Can I directly charge the battery using an USB-C connector with the two cables (red and black) directly soldered to the battery poles on the board?

# Answer
> 1 votes
The lithium battery must be charged by a specialized CC/CV control chip. The module in question already has one, namely a TP5400, sitting between the mounted micro-USB connector and the 18650 battery holder. You should use the same USB connector for both programming the MCU and charging the battery.

---
Tags: esp8266, battery, charging
---


# Question
Title: Split up Arduino code into multiple files using Arduino IDE
I am working on a very long code that requires multiple functions defined. I want to split the code into two files as main code ("Feeder\_Control" in the screenshot) and functions ("connections" in the screenshot) How to import the second file into main code to use its functions?

PS: In C/C++ same thing is done with #include "connections.h". How is it done in Arduino IDE.

.

# Answer
There is no need to use an `#include` directive for the additional .ino file.

Before compilation starts, the Arduino IDE concatenates all .ino files in your sketch into a single file, starting with the .ino file that matches the sketch folder name, followed by the rest of the .ino files in alphabetical order. So there is no difference between one massive .ino file and breaking the same code among multiple .ino files, other than the greater ease of navigating the code via tabs. After a bit more processing, this file is compiled as C++.

Reference: https://arduino.github.io/arduino-cli/latest/sketch-build-process/#pre-processing
> 22 votes

# Answer
Two comments to answer by per1234 (although old): You can have multiple .ino files in a project. However:

1. You can not separate the preprocessor portion from the main file (The file with the project's name) which must include ALL preprocessing.
2. Arduino IDE compiles all files in a project in a specific order (alphabetically by filename) and includes them into the main .ino file during the linking stage. Code in later .ino files can access variables and functions defined in earlier ones, but not vice versa.
> 0 votes

---
Tags: arduino-ide
---


# Question
Title: Arduino board with StandardFirmata doesn't respond to C# and Python client
I have a Seeeduino XIAO board with Firmata running on it. I'm currently trying to write C# client to communicate with this board. I have tried using Iot.Device.Arduino, SolidSolis.Arduino and *pyfirmata* for that purpose but I'm struggling with problem - board doesn't respond to any requests sent by my apps.

However, when I use Windows Remote Arduino Experience app, board is being successfuly found and I can control pins, retrieve info etc.

* I use these programs to communicate with board:

```
using Iot.Device.Arduino;

var arduino = new ArduinoBoard("COM3", 57600);
Console.WriteLine(arduino.FirmataVersion.Major); // This throws System.TimeoutException

```

```
import pyfirmata
port = 'COM3'
board = pyfirmata.Arduino(port)
print(board.firmata_version) # prints 'None'

```

```
#elif defined(SEEED_XIAO_M0)
#define TOTAL_ANALOG_PINS 11
#define TOTAL_PINS 17 // 11 digital / analog + 1 DAC output + 2 i2c + 3 spi
#define VERSION_BLINK_PIN LED_BUILTIN
#define PIN_SERIAL1_RX 7
#define PIN_SERIAL1_TX 6
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 10)
#define IS_PIN_ANALOG(p) ((p) >= 0 && (p) <= 10)
#define IS_PIN_PWM(p) ((p) >= 1 && (p) <= 10)
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) < MAX_SERVOS) // deprecated since v2.4
#define IS_PIN_I2C(p) ((p) == 4 || (p) == 5) // SDA = 4, SCL = 5
#define IS_PIN_SPI(p) ((p) == 4 || (p) == 10 || (p) == 9 || (p) == 8) // SS = A4
#define IS_PIN_SERIAL(p) ((p) == 6 || (p) == 7)
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_ANALOG(p) (p)
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
#define PIN_TO_SERVO(p) (p) // deprecated since v2.4

```

I've tried to rebuild Windows Remote Arduino Experience app with modifications - I've made it log every bytes it sends to Arduino or receives from Arduino. Then I've tried sending those bytes manually but result was still the same - board was not responding

There is a device in `Device manager`:

* USB device with Serial port (COM3) (ID - `USB\VID_2886&PID_802F&REV_0104&MI_00`)

P.S. How do I know that the board is not responding and it's not the app that doesn't work? The board has RX and TX leds, RX one blinks always but TX blinks only when I use Windows Remote Arduino Experience app.

What I am doing wrong? Is there any error in setup or code I've written?

# Answer
The problem was in serial port connection settings. When I used these i was finally able to get response from board:

```
var port = new SerialPort("COM3", 115600);

port.Open();

port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.DataBits = 8;
port.Encoding = Encoding.UTF8;
port.RtsEnable = true;
port.DtrEnable = true;
port.BreakState = false;

```
> 1 votes

---
Tags: serial, usb, uart, firmata, seeeduino-xiao
---


# Question
Title: I encounter an error in the ISR function when using the code specified in this community for arduinodue to act as a slave in spi communication
```
#include<SPI.h>

volatile boolean received;
volatile byte receivedData;

ISR (SPI_STC_vect)        //Inerrrput routine function
{
  receivedData = SPDR;   // Get the received data from SPDR register
  received = true;       // Sets received as True
}

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

  pinMode(MISO,OUTPUT);   //Sets MISO as OUTPUT
  SPCR |= _BV(SPE);       //Turn on SPI in Slave Mode
  received = false;
  SPI.attachInterrupt();  //Activate SPI Interuupt
}

void loop()
{
  if(received) {
    SPDR = receivedData;    // send back the received data, this is not necessary, only for demo purpose
    received = false;
    Serial.print(receivedData, HEX);
  }
}

```

the compiler gives an error with isr specified

# Answer
> 1 votes
This program seems to have been written for an AVR-based Arduino, like a classic Uno or Nano. The registers `SPCR` and `SPDR`, the bit `SPE` on `SPCR`, and the `SPI_STC` interrupt, are all documented on the ATmega328P’s datasheet.

Yours is an Arduino Due, which uses a completely different microcontroller. AVR-specific code cannot run on the Due.

---
Tags: serial, spi, arduino-due
---


# Question
Title: Heltec WiFi LoRa 32 (V3) - Encode/decode packets to binary (make message shorter)
I'm using Heltec WiFi LoRa32 boards (ESP32-S3 + SX1262).

Could you please help me how to encode data e.g. from temperature and humidity sensor into binary or hexadecimal form - to make the LoRa packet length shorter? Similar to what LoRaWAN does.

For example I have two values:

```
float temperature = 21.56;
float humidity = 76.21;

```

I use the official Heltec library for LoRa radio (https://github.com/HelTecAutomation/Heltec\_ESP32/blob/master/src/radio/radio.c), I only transfer data via LoRa (not LoRaWAN), so it is necessary to make it work with the library function Radio.Send().

```
Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); //send the package out

```

I found this example: https://create.arduino.cc/editor/LogMaker360/770f60c9-52c5-4d29-b417-4804b278db20/preview and this tutorial: https://www.thethingsnetwork.org/docs/devices/bytes/

I'm confused in this, so I would appreciate a parto of code example compatible with Heltec library for encoding and decoding compatible with Heltec library functions.

Thank you

# Answer
If you want to send both temperature and humidity in a single packet, the easiest way is to define the packet as a `struct` with two fields:

```
struct LoraData {
    float temperature;
    float humidity;
};

```

You can then send the raw bytes by typecasting the address of such a `struct` to `uint8_t*`. This, however, is generally not recommended, because it violates C++ type aliasing rules. You can circumvent this issue by defining a `union`:

```
union LoraPacket {
    LoraData data;
    uint8_t bytes[sizeof(LoraData)];
};

```

This represents an area of memory that can be interpreted as containing either the numeric data `data`, or an array of bytes. Then you can fill the `data` field and send the raw bytes:

```
void send_dummy_data()
{
    LoraPacket packet = {
        .data = {
            .temperature = 12.56,
            .humidity = 76.21
        }
    };
    Radio.Send(packet.bytes, sizeof packet);
}

```

At the other end, you do the same thing backwards: you fill in the bytes and read back the numeric data:

```
void rx_done(uint8_t *payload, uint16_t size, int16_t, int8_t)
{
    if (size != sizeof(LoraPacket)) {  // sanity check
        Serial.println("Bad packet size");
        return;
    }
    LoraPacket packet;
    memcpy(&packet.bytes, payload, size);
    Serial.print("temperature: ");
    Serial.println(packet.data.temperature);
    Serial.print("humidity: ");
    Serial.println(packet.data.humidity);
}

```
> 1 votes

# Answer
> Radio.Send( (uint8\_t \*)txpacket, strlen(txpacket) );

Noted that `strlen(txpacket)` is only applicable if the `txpacket` is a string. Since temperature is a floating point value, it should be `sizeof(temperature)`(see further explanation below).

I think there is a misunderstanding that this send a "shorter" data because you saw the `uint8_t`, but it is not the case. A single-precision floating point data is stored as a 4-byte data in according to IEEE754 format. What the `RadioSend((uint8_t *) temperature, sizeof(temperature))` does is it simply cast the floating point value to a pointer of byte (i.e. uint8\_t) that is point to the beginning of the `temperature` in memory so that it can send the data byte-by-byte, the `sizeof(temperature)` is equivalent to `sizeof(float)` so it is equal to 4. The data that going through the radio transmission is still 4-byte floating point value.

To send the temperature and humidity, you just need to send the temperature and humidity data as:

```
float temperature = 21.56;
float humidity = 76.21;

RadioSend((uint8_t *) temperature, sizeof(temperature));
RadioSend((uint8_t *) humidity, sizeof(humidity));

```

However, as point out by @jsotola, if you want, there is a way to reduce the data to be sent from 4-byte floating point to 2-byte `int16_t` by converting the `float` to `int16_t` by multiply the floating point value with 100. The converted data is only 2-byte long as an `int16_t` without losing the precision of the floating point (which has precision of 2 decimal points).

```
float temperature = 21.56;
float humidity = 76.21;

int16_t temperature_in_integer = (int16_t) temperature * 100; // integer 2156
int16_t humidity_in_integer = (int16_t) humidity * 100;  // integer 7621

// send 2-byte each
RadioSend((uint8_t *) temperature_in_integer, sizeof(temperature_in_integer));
RadioSend((uint8_t *) humidity_in_integer, sizeof(humidity_in_integer));

```

On the receiving end, the received data need to be divided by 100 to get back the actual temperature and humidity value.

If this is a little confuse to you, I would suggest you pick up a book of C or C++ and learn the foundation of data types, data casting and pointer.
> 0 votes

---
Tags: esp32, lora, esp32-s3
---


# Question
Title: Arduino_DebugUtils.h: No such file or directory
How to get rid of this error?

```
/storage/emulated/0/ArduinoDroid/userlibraries/Arduino_ConnectionHandler/src/Arduino_ConnectionHandler.h:26:34: fatal error: Arduino_DebugUtils.h: No such file or directory

```

# Answer
> 1 votes
You need to install the `Arduino_DebugUtils` library.

From Arduino\_DebugUtils:

> To use this library, open the Library Manager in the Arduino IDE and install it from there.

---
Tags: arduino-ide, compilation-errors
---


title: Capturing frequency using a photodiode

text:
# Question
Title: Capturing frequency using a photodiode
I've just bought the following photodiode (here) and I am trying to make a simple Arduino circuit/code so that the photodiode is able to record an LED blinking at an arbitrary refresh rate (frequency).

I have an Arduino Uno driving the sensor, and a Raspberry Pi driving the LED at a given frequency.

I would like some help as my knowledge in signal processing is minimal, and I would appreciate any feedback or tips on whether what I am doing is correct or not.

Here is the Arduino code:

**CODE UPDATED!!**

```
//#include <TimerOne.h>
#include <Arduino.h>

const unsigned long ONESEC = 1000000; // microseconds
const int size = 600;
int sensorValue[size];
int dly = 1000000 / size; // delay so to fill N samples during 1 complete second (1,000,000 microseconds)

int maxValue = 0;
int minValue = 1000000;
double Alpha = 0.1; // [0.0 - 1.0] weight parameter
double filteredValue = 0.0;
double prevValue = 0.0;
double avgsum = 0.0;

int total = 0;
int avgtotal = 0;
const int s = 10;
int rounds = size / s;
int tmparr[s];

const int btnPin = 7;
const int sensorPin = A0;  // sensor pin

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

  // init tmparr
  for(int i=0;i<s;i++){
    tmparr[i] = 0;
  }
}

void waitForButton(int btnPin){
  Serial.println("Waiting...");
  while(digitalRead(btnPin) != 1){
    continue;
    }
  Serial.println("Button has been pressed!");
}

void loop() {  // code that loops forever

  int i = 0;
  unsigned long curTime = micros();
  unsigned long prevTime, startTime;
  prevTime = curTime;
  startTime = curTime;
  while(curTime - startTime <= ONESEC){ // sofar the time between the current and the start time is less than 1 second, keep recording data
    if(curTime - prevTime < dly){ // sofar the current and the previous time stamp has a differene of less than N seconds, do not record anything
      curTime = micros();
      continue;
    }
    sensorValue[i++] = analogRead(sensorPin);

    if(i > size){
      break;
    }
    prevTime = curTime;
    curTime = micros();
  }

  ///////////////////////
  ///////////////////////
  // Data processing ////
  ///////////////////////
  ///////////////////////

  // filter the signal and find maximum/minimum and avg

  for(int i=0;i<size;i++){
    int v = sensorValue[i];
    filteredValue = (v * Alpha) + (prevValue * (1-Alpha)); // exponential filtering
    sensorValue[i] = filteredValue; // re-writing the sensor data !! RAW DATA ARE BEING OVERWRITTEN !!
    avgsum = avgsum + filteredValue;
    prevValue = filteredValue;

    if(maxValue < filteredValue){
      maxValue = filteredValue;
    }
    if(minValue > filteredValue){
      minValue = filteredValue;
    }
  }
  avgsum = avgsum / size;

  // plotting and segregating the signal
  int peaks = 0;
  int prevState = -1;

  for(int i=0;i<rounds;i++){
    for(int j=0;j<s;j++){
      int v = sensorValue[(i*s)+j];
      total = total - tmparr[j];
      total = total + v;
      avgtotal = total / s;
      tmparr[j] = v;
      Serial.print(avgtotal); // new filtered value
      Serial.print(",");
      Serial.print(avgsum);
      Serial.print(",");
      Serial.println(v); // filtered value

      if(avgtotal > avgsum + (avgsum*0.01)){
        // Serial.println(1);
        if(prevState != 1){
          peaks++;
          prevState = 1;
        }
      }
      else{
        // Serial.println(0);
        prevState = 0;
      }
    }
  }
  Serial.print("peaks:");
  Serial.println(peaks);

}

```

So far I am getting somewhere close I guess. Down are some of the recorded measurements. Filtering the signal, I suspect, is not optimal to make clear distinction between peaks and trough in the signal. Also I am not sure if the shape of the signal is proper representation of the actual input signal given that the filtering influence that in a way or another based on the used parameters.

Any tips for what I should do and how I should proceed to make it more reliable and accurate?

---

**Update 1:**

Here is the Pi code:

```
import RPi.GPIO as GPIO # Import Raspberry Pi GPIO library
from time import sleep # Import the sleep function from the time module

GPIO.setwarnings(False) # Ignore warning for now
GPIO.setmode(GPIO.BOARD) # Use physical pin numbering
GPIO.setup(8, GPIO.OUT, initial=GPIO.LOW) # Set pin 8 to be an output pin and set initial value to low (off)

freq = 5.0 # Hz
cycle = 1.0/freq
hcycle = cycle / 2.0

while True: # Run forever
 GPIO.output(8, GPIO.HIGH) # Turn on
 sleep(hcycle) # Sleep for N second
 GPIO.output(8, GPIO.LOW) # Turn off
 sleep(hcycle)

```

---

**Update 2:**

After updating the code, for very low frequencies I get kinda nicely shaped-signal

example of 5 Hz signal

Things start to get messier with high frequency (not that high) at 30 Hz for instance, where trying to segregate the signal based on the total average line does not result in informative value for how many peaks and troughs there are, for several peaks can be under the lines and several troughs can be above the line. Output reads 25 peaks here.

so I am starting to think that the filtering technique I am using maybe is not the best. Any suggestions?

# Answer
Consider this loop:

```
for(int i=0; i< size;i++){
  // Read sensor value
  sensorValue[i] = analogRead(sensorPin);
  // wait between readings for N microseconds
  delayMicroseconds(dly);
}

```

The time taken by each iteration is the sum of the times taken by each individual operation (compare `i` to `size`, read the ADC, delay, increment `i` and jump to the start of the loop). Other than the delay, the longest operation here is `analogRead()`, as it blocks in a busy loop while the ADC performs its conversion. This can take anywhere between 104 µs and 112 µs. Even neglecting everything but `analogRead()` and `delayMicroseconds()`, you expect your loop to be about 6–7% too slow.

You should get better timings if you use `micros()` instead of `delayMicroseconds()`. Check the Arduino tutorial “Blink without delay” to see how you can manage your timings without delaying. You still won't get metrology-class timings though, as `micros()` is only as good as the ceramic resonator clocking your Uno, which should be roughly 0.1% accurate in its frequency. If you need anything better, you will have to find a better frequency standard.

---

**Edit**: Addressing the updated question.

There are a few issues I would like to address:

First, the way the updated code handles the acquisition timing is a bit convoluted. Furthermore, updating the time with `prevTime = curTime;` is prone to timing drift: you cannot count on `curTime` being exactly the time at which the ADC reading was scheduled, it can be a few microseconds later. Actually, `curTime` will always be later, as the acquisition period (1,666 µs) is not a multiple of the `micros()` resolution (4 µs). This timing drift can be avoided by making `prevTime` represent the time when the previous acquisition was *scheduled* (not when it was *performed*):

```
// Data acquisition.
unsigned long prevTime = micros();
for (int i = 0; i < size; i++) {
    while (micros() - prevTime < dly) continue;  // wait until it's time
    prevTime += dly;                         // update scheduled time
    sensorValue[i] = analogRead(sensorPin);  // acquire data
}

```

The limited resolution of `micros()` will still cause some jitter, but updating with `prevTime += dly;` ensures there is no systematic drift.

Second, I would avoid doing any kind of filtering on the Arduino itself. If the data is meant to be transferred to the PC anyway, just transfer the raw data. This gives you the chance of processing it on your PC, interactively experimenting with different types of filters, with the comfort of your favorite programming language or data-processing package. If the complete project requires the filtering to be done on the Arduino, do that later, once you have found the most appropriate filter on the PC.

Third, as filtering goes, you seem to have *a lot* of 50 Hz noise here. Maybe the noise is already present in the luminous flux, or maybe it is introduced somewhere between the photodiode and the Arduino. I would check the cabling to see whether there is a way to reduce inductive noise pickup. Are you using long cables between the photodiode and the Arduino? If so, is that a twisted pair? Is everything properly grounded? Are there any ground loops?

If you cannot get rid of the mains noise at the source, it will be very difficult to identify signals that are anywhere close to 50 Hz, as your 30 Hz experiment shows. You may want to try a notch filter specifically tuned to kill any 50 Hz component.

Fourth, you may want to try, at least once, to acquire at a faster rate: let's say with a 200 µs period. If that acquisition reveals a lot of high-frequency noise, then it may be worth using some decimating filter. For example, you could store, in each array position, the sum of eight samples taken at 200 µs intervals. That should give less noisy data, with a period of 1.6 ms per array cell (round value close to the current 1.666 ms). Note that this technique will be absolutely useless against 50 Hz noise though.

Fifth, it is possible to trigger the ADC from a timer, which gives very accurate and consistent timing. This, however, requires low-level programming, and digging into the ATmega datasheet. I would not care about perfect timings now, at least not until the above issues are fixed. It is, however, a possibility you may want to keep in mind in case in the future you want to get the best possible timings.
> 2 votes

# Answer
Counting in a loop like that is fine if you have a very low frequency signal, and are getting the hang of how loops, and reading from input pins, work. But there will be a lot of overheads. As Edgar Bonet points out in his answer there can be an overhead of between 104 µs and 112 µs for doing an analogRead call. Plus the overhead of the loop. And the delay won't be accurate to the microsecond. All this adds up.

There are two ways you can find a frequency:

1. Count "ticks" over a known interval. For example, counting 50 ticks over a second would give you 50 Hz.
2. Measure the period. In other words, find out how long elapses between a rising edge and a falling edge (and double that time). For example for 50 Hz the period would be 20 ms (1 / 50).

As I mention on my page about timers there are ways of doing that. To avoid giving a link-only answer I'll paste some of that code.

# Count pulses

```
// Timer and Counter example
// Author: Nick Gammon
// Date: 17th January 2012

// Input: Pin D5

// these are checked for in the main program
volatile unsigned long timerCounts;
volatile boolean counterReady;

// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;

void startCounting (unsigned int ms)
  {
  counterReady = false;         // time not up yet
  timerPeriod = ms;             // how many 1 ms counts to do
  timerTicks = 0;               // reset interrupt counter
  overflowCount = 0;            // no overflows yet

  // reset Timer 1 and Timer 2
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR2A = 0;
  TCCR2B = 0;

  // Timer 1 - counts events on pin D5
  TIMSK1 = bit (TOIE1);   // interrupt on Timer 1 overflow

  // Timer 2 - gives us our 1 ms counting interval
  // 16 MHz clock (62.5 ns per tick) - prescaled by 128
  //  counter increments every 8 µs.
  // So we count 125 of them, giving exactly 1000 µs (1 ms)
  TCCR2A = bit (WGM21) ;   // CTC mode
  OCR2A  = 124;            // count up to 125  (zero relative!!!!)

  // Timer 2 - interrupt on match (ie. every 1 ms)
  TIMSK2 = bit (OCIE2A);   // enable Timer2 Interrupt

  TCNT1 = 0;      // Both counters to zero
  TCNT2 = 0;

  // Reset prescalers
  GTCCR = bit (PSRASY);        // reset prescaler now
  // start Timer 2
  TCCR2B =  bit (CS20) | bit (CS22) ;  // prescaler of 128
  // start Timer 1
  // External clock source on T1 pin (D5). Clock on rising edge.
  TCCR1B =  bit (CS10) | bit (CS11) | bit (CS12);
  }  // end of startCounting

ISR (TIMER1_OVF_vect)
  {
  ++overflowCount;               // count number of Counter1 overflows
  }  // end of TIMER1_OVF_vect

//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR (TIMER2_COMPA_vect)
  {
  // grab counter value before it changes any more
  unsigned int timer1CounterValue;
  timer1CounterValue = TCNT1;  // see datasheet, page 117 (accessing 16-bit registers)
  unsigned long overflowCopy = overflowCount;

  // see if we have reached timing period
  if (++timerTicks < timerPeriod)
    return;  // not yet

  // if just missed an overflow
  if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
    overflowCopy++;

  // end of gate time, measurement ready

  TCCR1A = 0;    // stop timer 1
  TCCR1B = 0;

  TCCR2A = 0;    // stop timer 2
  TCCR2B = 0;

  TIMSK1 = 0;    // disable Timer1 Interrupt
  TIMSK2 = 0;    // disable Timer2 Interrupt

  // calculate total count
  timerCounts = (overflowCopy << 16) + timer1CounterValue;  // each overflow is 65536 more
  counterReady = true;              // set global flag for end count period
  }  // end of TIMER2_COMPA_vect

void setup ()
  {
  Serial.begin(115200);
  Serial.println("Frequency Counter");
  } // end of setup

void loop ()
  {
  // stop Timer 0 interrupts from throwing the count out
  byte oldTCCR0A = TCCR0A;
  byte oldTCCR0B = TCCR0B;
  TCCR0A = 0;    // stop timer 0
  TCCR0B = 0;

  startCounting (500);  // how many ms to count for

  while (!counterReady)
     { }  // loop until count over

  // adjust counts by counting interval to give frequency in Hz
  float frq = (timerCounts *  1000.0) / timerPeriod;

  Serial.print ("Frequency: ");
  Serial.print ((unsigned long) frq);
  Serial.println (" Hz.");

  // restart timer 0
  TCCR0A = oldTCCR0A;
  TCCR0B = oldTCCR0B;

  // let serial stuff finish
  delay(200);
  }   // end of loop

```

This is actually not so great for low frequencies because if the count is out by even one tick, your frequency is wrong by 2%. However it can count accurately (more or less) up to 5 kHz.

# Measure the period

The other technique is to measure the period, like this:

```
// Frequency timer
// Author: Nick Gammon
// Date: 10th February 2012

// Input: Pin D2

volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;

// here on rising edge
void isr ()
{
  unsigned int counter = TCNT1;  // quickly save it

  // wait until we noticed last one
  if (triggered)
    return;

  if (first)
    {
    startTime = (overflowCount << 16) + counter;
    first = false;
    return;
    }

  finishTime = (overflowCount << 16) + counter;
  triggered = true;
  detachInterrupt(0);
}  // end of isr

// timer overflows (every 65536 counts)
ISR (TIMER1_OVF_vect)
{
  overflowCount++;
}  // end of TIMER1_OVF_vect

void prepareForInterrupts ()
  {
  // get ready for next time
  EIFR = bit (INTF0);  // clear flag for interrupt 0
  first = true;
  triggered = false;  // re-arm for next time
  attachInterrupt(0, isr, RISING);
  }  // end of prepareForInterrupts

void setup ()
  {
  Serial.begin(115200);
  Serial.println("Frequency Counter");

  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  // Timer 1 - interrupt on overflow
  TIMSK1 = bit (TOIE1);   // enable Timer1 Interrupt
  // zero it
  TCNT1 = 0;
  overflowCount = 0;
  // start Timer 1
  TCCR1B =  bit (CS10);  //  no prescaling

  // set up for interrupts
  prepareForInterrupts ();

  } // end of setup

void loop ()
  {

  if (!triggered)
    return;

  unsigned long elapsedTime = finishTime - startTime;
  float freq = F_CPU / float (elapsedTime);  // each tick is 62.5 ns at 16 MHz

  Serial.print ("Took: ");
  Serial.print (elapsedTime);
  Serial.print (" counts. ");

  Serial.print ("Frequency: ");
  Serial.print (freq);
  Serial.println (" Hz. ");

  // so we can read it
  delay (500);

  prepareForInterrupts ();
}   // end of loop

```

This is better for low frequencies. Since this uses hardware timers you need to connect your input up to a specific pin as noted in the code. No doing analog reads, the time taken to do that would swamp any accuracy that you might get.
> 2 votes

---
Tags: arduino-uno, frequency
---


# Question
Title: How to use do while loop of the u8g library in page drawing mode
I am trying to use a rotary encoder with 128x64 OLED display on an Arduino nano. I am trying to create a menu that can be scrolled through using the rotary encoder. While testing the rotary encoder, I found out it bounces quite a lot, so I used Bounce2 library and few extra lines of code to get the encoder working properly.

https://wokwi.com/projects/393512353441494017 here's the wokwi simulation and code of just the rotary encoder and I have tested this code on real hardware and it works fine.

```
    #include <Bounce2.h>
    #include "U8glib.h"
    #define ENCODER_CLK 3
    #define ENCODER_DT 2
    #define ENCODER_SW 4

    //buttons
    Bounce2::Button encoder_clk = Bounce2::Button();
    Bounce2::Button encoder_dt = Bounce2::Button();
    Bounce2::Button encoder_sw = Bounce2::Button();
    #define LED_PIN 13

    bool led_state = LOW;

    void setup() {

      //serial monitor
      Serial.begin(115200);

      //encoder and button debouncing
      encoder_clk.attach( ENCODER_CLK, INPUT);
      encoder_dt.attach( ENCODER_DT, INPUT);
      encoder_sw.attach( ENCODER_SW, INPUT_PULLUP);

      encoder_clk.interval(5);
      encoder_dt.interval(5);
      encoder_sw.interval(5);

      encoder_clk.setPressedState(LOW);
      encoder_dt.setPressedState(LOW);
      encoder_sw.setPressedState(LOW);

      //test led
      pinMode(LED_PIN,OUTPUT);
      digitalWrite(LED_PIN,led_state);

    }

    void loop() {

      encoder_clk.update();
      encoder_dt.update();
      encoder_sw.update();

      if (encoder_clk.changed()) {
        // There was a change on the CLK pin
        bool dtValue = encoder_dt.read();
        bool ckValue = encoder_clk.read();
        if (ckValue == LOW && dtValue == HIGH) {
          Serial.println("Rotated clockwise ⏩");
        }
        if (ckValue == LOW && dtValue == LOW) {
          Serial.println("Rotated counterclockwise ⏪");
        }
      }

      if(encoder_sw.pressed()){
        led_state = !led_state;
         digitalWrite(LED_PIN, led_state);
         Serial.println("Button Pressed");
      }
    }

```

Then I decided to test the OLED display. Here is the wokwi simulation for oled and rotatry encoder together. https://wokwi.com/projects/393400062063669249

After adding the code for OLED display and the do while loop of u8g library, it has stopped registering rotary encoder inputs. I cannot get any thing displayed on serial monitor. I have tested this on real hardware as well and the result is the same. How do I fix this problem and what would be the better way to use the do while loop of the u8g library?

# Answer
> 1 votes
For reliably registering encoder transition, you need your main loop to be non-blocking. My guess is that the `do...while` loop blocks the Arduino for too long. If this is the case, one possible solution is to perform a single iteration of this `do...while` loop inside `loop()`. For instance, your current `loop()` looks like this:

```
void loop() {
    handle_the_encoder();

    u8g.firstPage();
    do {
        do_the_drawing();
    } while (u8g.nextPage());
}

```

You can change it into this:

```
void loop() {
    handle_the_encoder();

    static bool do_first_page = true;
    if (do_first_page) {
        u8g.firstPage();
        do_first_page = false;
    }
    do_the_drawing();
    if (!u8g.nextPage())
        do_first_page = true;
}

```

If needed, you may also break the drawing code into smaller chunks, and do a single chunk per loop iteration. This will require you implementing a finite state machine.

---
Tags: rotary-encoder, debounce, oled, u8glib
---


# Question
Title: How to set cables to connect CP2102 to Pro Mini?
How to connect the cables in order to program the pro mini with the CP2102 usb interface ? The TX RX and GND is easy, but I am not sure about the RST, DTR, DST, etc

When I try cables like this:

```
TX  ... RX
RX  ... TX
5V  ... VCC // my pro mini is 5V version
GND ... GND
RST ... RST

```

The board lits up and green starts blinking, this should be the default `blinker` program.

I click Upload, I get this error, and I assume the cables are not properly connected:

```
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x89
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x89

```

I know some people mentioned it works by adding some resistor and capacitor, but I was hoping that is an error and it should work without that complication.

# Answer
> 0 votes
Here's what works for me:

```
Pro Mini  ---------   CP2102

  DTR     ---------    DTR
  RST     ---------    RST   (optional if you wish to press some buttons)

  GND     ---------    GND
  RX      ---------    TX
  TX      ---------    RX
  VCC     ---------    VCC

```

---

*Tap on the image to see the HD image*

# Answer
> -1 votes
RST to RST. Ignore the others, they are irrelevant.

# Answer
> -1 votes
Pretty sure RST is Reset input to the CP2102, that will not work.

DTR to DTR (BLK on the Promini) will work, the DTR Low level goes thru the Promini's 0.1uF cap and 10K Reset pullup resistor to make a Reset pulse. That's how the FTDI Basic works when connected.

RTS (Request To Send output) might also work, that is supposedly a pulsed level.

---
Tags: programming, usb, pins, arduino-pro-mini, wires
---


title: Problem with USBSetup not declared

text:
# Question
Title: Problem with USBSetup not declared
Recently I've got into the Arduino USB HID stuff, so I've been trying it out. i found the library fingerprintusbhost which should in theory get the OS its plugged in.

However, I've come across this error and I'm not sure how to fix or make it work. I've been looking in the library itself, but with my limited knowledge I don't know what is wrong or how to fix it.

```
In file included from /home/tdvds/Documents/arduino uno/Material_Rubber_Ducky_Arduino_UNO_R3/sketch_mar20a/sketch_mar20a.ino:2:0:
/home/tdvds/Arduino/libraries/FingerprintUSBHost/src/FingerprintUSBHost.h:38:55: error: expected class-name before '{' token
 class FingerprintUSBHost_ : public PluggableUSBModule {
                                                       ^
/home/tdvds/Arduino/libraries/FingerprintUSBHost/src/FingerprintUSBHost.h:52:23: error: 'USBSetup' has not been declared
     int getDescriptor(USBSetup& setup);
                       ^~~~~~~~
/home/tdvds/Arduino/libraries/FingerprintUSBHost/src/FingerprintUSBHost.h:53:16: error: 'USBSetup' has not been declared
     bool setup(USBSetup& setup);
                ^~~~~~~~

exit status 1

Compilation error: exit status 1

```

Before you say "it's not a Leonardo", you can actually do it with an Uno as well, although it's a bit odder than a Leonardo.

# Answer
> 0 votes
This is as expected, if you try to use `PluggableUSBModule` on an Uno (or any board that doesn't have `USBCON` defined).

To avoid such errors, and get a meaningful compilation error message, you should include a compiler check such as

```
#if !defined(USBCON)
#error PluggableUSBModule can only be used with an USB MCU.
#endif

```

just after the `#include`s at the top of the library's header file, like so

```
#include <stdint.h>
#include <Arduino.h>
#include "PluggableUSB.h"

#if !defined(USBCON)
#error PluggableUSBModule can only be used with an USB MCU.
#endif

```

In short, if the FingerprintUSBHost.h had such a check, then users of the library wouldn't be so confused. You should probably raise a Github issue for the author of the `FingerprintUSBHost` library, pointing out this issue.

---

#### Reproducing the error

FWIW, it is easy to reproduce this error, by using the code from this example, Issue with writing USB Mass Storage "PluggableUSB.h" Module. Enter the code for the three files (the main sketch, `MassStorage.cpp` and `MassStorage.h`) and compile, with the Uno board selected. You will get the error

```
MassStorage can only be used with an USB MCU.

```

Then remove the three lines of the compiler check from `MassStorage.h`:

```
#if !defined(USBCON)
#error MassStorage can only be used with an USB MCU.
#endif

```

and then try to compile. You will get the same errors as you have in your post.

However, if you compile the unaltered original code, with a Leonardo board selected (which *does* have `USBCON` defined), you will not see any errors.

---
Tags: arduino-uno, hid
---


# Question
Title: Problems with reacting to joystick button press
I am trying to use a joystick in a project for device control. Pressing a joystick button should cause incrementing a variable. INPUT\_PULLUP mode is used for internal button.

As I understand it, when the button is not pressed there is a HIGH level on the GPIO pin, and there is a LOW level when the button is pressed. The signal read from the button in thd sketch is inverted to HIGH when the circuit is closed.

I used some sketches for eliminating debounce, but in all cases when the button is pressed a stream of incoherent symbols occurs on the serial port. It happens both in the simulator and the IDE.

What can cause this stream on the output when waiting for the message that button is pressed? The symbols also occured when I put a count-variable on the serial port. Does the button debounce look correct?

```
int Joystick_Y = A0;
int Joystick_X = A1;
int Joystick_but = 1;
int X;
int Y;
int X_prev = 0;
int Y_prev = 0;
int butt_flag = 0;
int butt;

const unsigned long debounceDelay = 50;
unsigned long last_press;

void setup() {
  Serial.begin(9600);
  pinMode(Joystick_but, INPUT_PULLUP);
}

void loop() {
  butt = !digitalRead(Joystick_but);

  if (butt == 1 && butt_flag == 0 && millis() - last_press > debounceDelay) {
    butt_flag = 1;
    last_press = millis();
    Serial.println("Button was pressed!");
  }

  if (butt == 0 && butt_flag == 1) {
    butt_flag = 0;
  }

  Y = analogRead(Joystick_Y);
  X = analogRead(Joystick_X);

  if (X < 512 && X > 485) {
    X = 512;
  }
  if (Y < 512 && Y > 485) {
    Y = 512;
  }

  if ((Y != Y_prev || X != X_prev) && (X != Y)) {
    Serial.print("X: ");
    Serial.print(X);
    Serial.print(" Y: ");
    Serial.println(Y);
  }

  Y_prev = Y;
  X_prev = X;
  delay(500);
}

```

# Answer
> 1 votes
As was mentioned in @chrisl 's comment: pin 1 on an Arduino Uno/Nano is the TX (transmit) pin for the Serial port. See here. This is the pin that is used to transmit serial data to the host.

When the same pin is also used as the joystick button, pressing it will interfere with serial output, causing the incoherent symbols you see to be transmitted.

Solution: Use a different (unused) pin.

Another potential problem is the `delay (500)` at the end of your `loop()` which, as @chrisl also noted, interferes with your debounce and will cause your code to react to button presses and joystick movements very slowly.

---
Tags: debounce, joystick
---


title: Reading I2C data from SW6106 register

text:
# Question
Title: Reading I2C data from SW6106 register
I am using the SW6106 powerbank IC as an I2C but no matter what I have tried I couldn't read something other than "FF".

Datasheet for the IC.

Timing diagram for reading data:

Timing diagram for writing data:

The code I use:

```
#include <Wire.h>

byte ADDRESS_SLAVE = 0x3C;
byte REGISTER_XY = 0xB0;
byte READ_LENGTH = 1;

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

  Wire.begin();
  Wire.setClock(400000); // set I2C 'full-speed'

  Wire.beginTransmission(ADDRESS_SLAVE);
  Wire.write(REGISTER_XY);  // set register for read
  Wire.endTransmission();
}

void loop() {
   Wire.requestFrom(ADDRESS_SLAVE,READ_LENGTH);
   byte buff[READ_LENGTH];
   Wire.readBytes(buff, READ_LENGTH);
   for (int i = 0; i < READ_LENGTH; i++) {
     Serial.println(buff[i], HEX);
   }
   Serial.println();
   delay(1000);
}

```

Serial monitor output:

I really couldn't understand anything from that timing diagram and couldn't read anything from the IC. I'd appreciate any help.

Edit: I edited the code a little bit to see what Wire.endTransmission(); returns.

```
#include <Wire.h>

byte ADDRESS_SLAVE = 0x3C;
byte REGISTER_XY = 0xB0;
byte READ_LENGTH = 1;

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

  Wire.begin();
  Wire.setClock(400000); // set I2C 'full-speed'
}

void loop() {
  Wire.beginTransmission(ADDRESS_SLAVE);
  Wire.write(REGISTER_XY);  // set register for read
  int x = Wire.endTransmission();
  Serial.println(x, DEC);
  delay(200);
}

```

And it retruns the following:

I really don't know where I am doing wrong.

# Answer
I know this post is very old, but I was able to get the register map from the manufacturer, Ismartware. Here's a link to the datapack for anyone else that may end up here while searching for the same thing.
> 1 votes

---
Tags: serial, power, i2c, battery
---


# Question
Title: Sending Analog Input Data from Serial Port to Google Sheets
So I'm trying to make use of my Arduino Uno while I purchase the components for my next project.

I've made use of the Digital Hourglass project from the Starter Kit to make sure I get up and move around every 20 minutes while I'm at home. A temperature sensor was included in the Starter Kit as well, so I figured I might as well make use of it since I have extra I/O pins.

I wrote the code for in the Arduino IDE to display the temperature and the current time. I'm using: `#include (Time.h)` to also show the current time. I have two questions.

End Goal:

A Google spreadsheet (Cloud) that I can access anywhere that can show me the temperature of my apartment throughout the day. I can track how the trend changes over time through the day, week, or month.

1. What is the best way to output the current time; as seconds since 1970 (Unix time) or date and time format? I guess it's a preference.
2. How do I output the data from the Arduino serial port directly to Google Sheets? That may be difficult, so the other option is to energize the Arduino in the morning and remove power at the end of the day, output the Serial port to a `.txt` file, and then import into Google sheets. How do I do this?

# Answer
1. Use Google's time stamp format: `MM-dd-yyyy hh:mm:ss`, see Google Sheets API v4 - Date and Number Formats.
2. There are a few ways. For example:

* A PC connected to the Internet with software on it that listens for data form the Arduino. It would get the Arduino data over serial then send that via the Internet to Google.
    * A Wi-Fi, or network, shield connected to the Internet. You could then use Google's API to send the data directly from the Arduino, see Google Sheets API v4 - Writing.
    * Or - as you mentioned - physically get the SD card and manually upload.
> 2 votes

# Answer
I'd use an ESP8266 and IFTTT.

https://ifttt.com/maker\_webhooks https://ifttt.com/google\_drive

You could write something on your PC that took the serial output from the Aurdino and posts a REST message to IFTTT.
> 1 votes

# Answer
Wouldn't it be great if the data from Arduino obtained via serial port could be inserted directly at a local google spreadsheet url, without using any api nor post requests?

As far as I know, Google Spreadsheets can be updated (by a human) in the local machine even without internet.

What would be the benefit?

If eventually internet goes offline for several hours, no arduino data would be lost.

In the good working solutions provided, internet is always mandatory, if I see correct. No internet? Lost data. It seems to me.

But I really don't know if a script can get serial data from Arduino and then update an existing google spreadsheet url, as a human would do (typing a new row).

An autoit or autohotkey script would do on Windows machines by simulating mouse clicks and typing, but it must exist more beautiful solutions.

A solution like this would accumulate data with or without internet and, as soon as internet returns, all data would be updated to the cloud. If I see correct. (I am sorry if I made any mistake).

---

I guess I have a not so bad solution: save all data to a txt file. Then, periodically, try to update all data to a google spreadsheet using Sheets API or any internet-dependent way (Web App, etc).

In this case, if there's no internet, data still accumulates at a txt file. When internet returns, no data would had been lost.
> 0 votes

---
Tags: arduino-uno, programming, analogread, temperature-sensor
---


# Question
Title: Serial.println printing just after the previous string in same line
I wrote serial.println in my code but the string was printed in same line on serial moniter.

```
#include <WiFi.h>//for connecting esp32 to a wifi

#include <TinyGPS++.h>//to obtain gps data from neo-6m gps module

#define WIFI_SSID "Airtel_pawa_4182"//wifi name in simple words
#define WIFI_PWD "Ahuja6230"//wifi password

TinyGPSPlus GPS;//creating a gps object from tinygps++ library

void setup() {
 Serial.begin(9600);
  //wifi setup{
  WiFi.begin(WIFI_SSID, WIFI_PWD);
  Serial.println("connecting to wifi");
  while(WiFi.status() != WL_CONNECTED){
   Serial.println(".");
   delay(1000);
  }
  Serial.println("Successfully connected to ");
  Serial.print(WIFI_SSID);
  //}

  //gps setup{
  Serial2.begin(9600);
  delay(1000);
  Serial.println("ESP32-GPS Tracker");
  Serial.println("Initializing...");
  //}
}

void loop() {
}

```

In this code the string "esp32-gps tracker" is printing just after the previous string in same line on serial moniter.

I tried running code again and again but it didn't work...

I am using esp32 board(just a detail)

What do i do?

# Answer
> 2 votes
The previous print statements are these:

```
  Serial.println("Successfully connected to ");
  Serial.print(WIFI_SSID);

```

The SSID won't be terminated by a newline. Perhaps you meant:

```
  Serial.print("Successfully connected to ");
  Serial.println(WIFI_SSID);

```

?

# Answer
> 1 votes
To follow on from previous answer, your solution is to either:

* change the previous Serial.print() to a Serial.println() so that that text is followed by a line end, or
* add a \n to the front of the line you are having the problem with, so it starts with a new line, to make up for the "missing" new line in the previous Serial.print().

# Answer
> 0 votes
When sending text through a serial line, it is customary to **terminate** each line with some sort of end-of-line marker: you print some text, and immediately *after* it the EOL to signify that “this is now a complete line”. Accordingly, the `Serial.println()` method prints the requested text, immediately *followed* by the EOL marker (in this case, CR+LF).

From your question, you seem to be thinking that the EOL immediately *precedes* the text. This is not the case.

See JRobert's answer for the correct way to build a line from multiple print statements: `println()` should be use on the last piece, not on the first one.

---
Tags: serial, programming
---