title: Code conversion

text:
# Question
Title: Code conversion
Following is the zabbix documentation with the query header format. Document Zabbix

I have difficulty implementing this header in C ++ (Arduino),

I saw an implementation of what I need in this forum here , however it is in Russian and is implemented in C #, I tried to translate it but to no avail.

So I need someone to help me write the function of the header examples in C ++ (Arduino).

Follows full Arduino code after @EdgarBonet change suggestion

```
#include <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>

// Config IP
IPAddress ip(192, 168, 0, 130);
IPAddress gw(192, 168, 0, 1);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
float contador = 0;

EthernetClient client;

//Config Server address
const char* server = "192.168.0.135";
int porta = 10051;

void setup() {
    Serial.begin(9600);
    Ethernet.begin(mac, ip);
}

void loop() {
    // Begin Json
    const size_t capacity = JSON_ARRAY_SIZE(1)
                          + JSON_OBJECT_SIZE(2)
                          + JSON_OBJECT_SIZE(3);
    DynamicJsonBuffer jsonBuffer(capacity);

    JsonObject& root = jsonBuffer.createObject();
    root["request"] = "sender data";

    JsonArray& data = root.createNestedArray("data");

    JsonObject& data_0 = data.createNestedObject();
    data_0["host"] = "ethernet";
    data_0["key"] = "variavel1";
    data_0["value"] = contador;

    String json = "";
    root.printTo(json);

    const uint8_t *dataSend = (const uint8_t *) json.c_str();
    uint64_t data_length = json.length();
    uint8_t packet[13 + data_length];  // 13-byte header + payload

    // Write the 5-byte signature.
    memcpy(packet, "ZBXD\1", 5);

    // Add the 8-byte packet length, LSB first.
    for (int i = 0; i < 8; i++) {
        packet[5+i] = data_length >> 8*i;
    }

    // Add the payload.
    memcpy(packet + 13, dataSend, data_length);
    if (client.connect(server, porta)) {
        Serial.println("Enviando ao servidor");
        delay(1000);
        // Send the packet.
        client.write(packet, sizeof packet);
        delay(1000);
        contador ++;
    }
}

```

Following server response:

```
2034:20191003:101411.196 Message size 2066888786 from 192.168.0.130 exceeds the maximum size 1073741824 bytes. Message ignored.

```

# Answer
The problem is quite explicit in the error message:

> expected 808529969 bytes

You told the server that you were going to give it 808529969 bytes, yet you provided much less. Why did you tell it you were going to send so much data? Maybe we can get a clue by rewriting this number in hexadecimal:

808529969 = 0x30313031

Breaking this into individual bytes, LSB first (as this is how the server expects it), you have

0x31 0x30 0x31 0x30

These are the bytes you sent to the server, and they all happen to be ASCII codes for digits, which make up the string "1010". I don't know how you came up with this, as the code you posted is not the one you tested (the posted code does not even compile!). But it seems at one point you tried to convert something to ASCII binary, and indeed `String(10, BIN)` produces exactly the string above.

The server expects the data length to be provided as binary bytes, **not** as an ASCII string. I personally try to avoid the `String` class, which can create memory issues. In this situation I would just work with an array of bytes, typed as `uint8_t` (the same as the Arduino `byte` type, only more standard). In the code below, I assume for simplicity that you keep a `String` for building the payload, but then I switch to a raw byte array:

```
const uint8_t *data = (const uint8_t *) json.c_str();
uint64_t data_length = json.length();
uint8_t packet[13 + data_length];  // 13-byte header + payload

// Write the 5-byte signature.
memcpy(packet, "ZBXD\1", 5);

// Add the 8-byte packet length, LSB first.
for (int i = 0; i < 8; i++) {
    packet[5+i] = data_length >> 8*i;
}

// Add the payload.
memcpy(packet + 13, data, data_length);

// Send the packet.
client.write(packet, sizeof packet);

```

Note that when working with binary, rather than text data, you have to use `memcpy()` instead of `strcpy()`, and `client.write()` instead of `client.print()`.
> 0 votes

---
Tags: arduino-uno, c, java
---


# Question
Title: Sending multi-byte data over I2C between different processors
I have been attempting to read data from an ATTINY84 via an ESP8266. Both are programmed via the Arduino IDE, though as PlatformIO is a proxy for that, I'm not certain what version of the ATTINY core is in use.

I have both devices connected to the I2C bus, with the Arduino as a slave. The ESP sends a code requesting a particular type of data, then calls Wire.requestFrom() to get 8 bytes of data. I am concerned over both my implementation and about potential endian-ness issues (even if it should turn out not to be an issue on these two particular devices, I'd like to know my future options).

The ATTINY code is a complex function that is called when there is a request (and the right option code, but that's probably not very relevant). It writes eight bytes using Wire.write after uncompressing them from the relevant arrays. (I have a lot of ADC data that technically should not fit in RAM.) Since this is is a callback function or possibly an interrupt, **do I need to be concerned about data corruption if the code is too slow to write the values onto the bus**? I have to imagine it's trying to read them even as it writes. I can also provide code snippets if it would help.

---

I am also unsure if I am running into Endian-ness issues by using bitshift to grab the 2 and 8 bits from the ADC return value. Would this always give me the correct values, or does the C++ compiler (as I assume it does not) simply refuse to handle differences between the data order? **Specifically, if I shift a uint16\_t (or any non-trivial datatype) right by 8 bits, and mask out the bottom 8 with &0xFF, do I *always* get the second-least-significant (in this *particular* case, high) byte, or can the compiler produce alternate outputs based on byte order?**

Does Arduino have an equivalent of network byte order (or does Wire automatically do so for its overrides of the functions) that I can get around this potential issue with?

# Answer
> 1 votes
There seems to be multiple questions in what you are asking. Here I try to answer specifically this one:

> if I shift a `uint16_t` (or any non-trivial datatype) right by 8 bits, and mask out the bottom 8 with `&0xFF`, do I always get the second-least-significant (in this particular case, high) byte, or can the compiler produce alternate outputs based on byte order?

Short answer: yes, you get the second-least-significant byte, irrespective of the platform's native endianness.

Now, I'll expand on this answer by showing the different ways you can convert an `uint16_t` to a sequence of bytes, and the implications on the byte order.

If you want to control the endianness, and you want your code to work independently of the native endianness of the platform, then bit shifting is the way to go. Let's assume you want to convert this:

```
uint16_t data;

```

into this:

```
uint8_t bytes[2];

```

You can do it this way in order to get the least significant byte first:

```
bytes[0] = data >> 0;  // least significant byte
bytes[1] = data >> 8;  // most significant byte

```

Or you can instead do the assignments the other way around (`data >> 8` goes to `bytes[0]`...) if you want MSB first. Note that there is no point in masking, as the assignment does it implicitly.

In contrast, if you wanted to put the bytes in *native* endianness (the endianness of the platform), the traditional way to do it is to cast the address of the number to a pointer to bytes, then read from this pointer:

```
bytes[0] = ((uint8_t *) &data)[0];  // first byte
bytes[1] = ((uint8_t *) &data)[1];  // last byte

```

You can swap the indices on one side of the assignments if you want to instead reverse the byte order. But note that this kind of casting is now frowned upon, as it violates aliasing rules. A common alternative is to have the number and the byte array share the memory within an `union`:

```
union {
    uint16_t data;
    uint8_t bytes[2];
} x = { .data = some_16_bit_value };
do_something_with(x.bytes[0]);  // use first byte
do_something_with(x.bytes[1]);  // use second byte

```

These are the main byte-splitting idioms you may come across. If your purpose is to have an endianness that you control and is independent of the platform, then stick with the first option: the old good bit shifting.

---
Tags: esp8266, attiny, byte-order
---


title: Use std::list in Arduino programming

text:
# Question
Title: Use std::list in Arduino programming
When trying to compile

```
#include <list>
std::list<byte> l = { 7, 5, 16, 8 };

```

in the Arduino IDE (with ATtinyCore for ATtiny4313), I get this message:

> error: list: No such file or directory
> #include \<list\>

**How to use the standard C++ `std::list` with Arduino/ATtiny?**

# Answer
I back up Michel Keijzers' suggestion to use a plain array, especially given the tiny amount of RAM in your MCU (only 256 bytes).

Concerning the removal of items from the list, and given that your list will be 16 bytes at most, you don't need to get fancy: just move back the items that are past the one you removed. It will not take long.

Here is a barebones implementation of a list that can hold at most 16 bytes and supports removal:

```
class List {
public:
    byte length;
    byte data[16];
    void append(byte item) {
        if (length < 16) data[length++] = item;
    }
    void remove(byte index) {
        if (index >= length) return;
        memmove(&data[index], &data[index+1], length - index - 1);
        length--;
    }
};

```

Note that this only takes 17 bytes of RAM (16 items max plus a length count). There is not vtable, as it has no virtual methods. You can get fancier if you want, make this a template parametrized by the data type and the maximum length, add accessors and such... but if you are just writing a simple sketch (as opposed to a general purpose library), I would recommend keeping it as simple as possible.

Example usage, based on your pseudo-code:

```
List l { .length = 3, .data = { 12, 82, 29 } };
l.remove(1);

```

This will indeed result in the list \[12, 29\].
> 3 votes

# Answer
I don't think that this library is supported by attiny (or even Arduino in general).

However, beyond that, it is not advised to use it, since it is uncertain how much memory and flash overhead it consumes.

Especially the memory is an issue for two reasons:

* Internally, you don't know the exact data structures used for the list. In most efficient way, it will only use 4 bytes (4 times 1 byte for the array), however, since it is a class under the hood a vtable is added, and who knows what more memory (maximum capacity, current capacity of the list etc).
* Also when adding/removing an item from the list, either the entire list is copied, or some tricks with pointers are used. In the first case you get memory gaps, in the second case maybe (and additional memory for the pointers is used).

My advice is to use just a simple array, and define a maximum of the array at compile time (if possible). Not as flexible, but robust, less memory usage and more reliable with a low SRAM device like the Attiny (and Arduino in general).

**Removing elements**

Based on your first comment:

Removing items is indeed an issue, however, note that if you use the standard library it might copy the entire array (excluding) the new item, so temporarily you will have double the array AND a memory gap.

There are some ways to implement it yourself:

* If you only want to remove items (and never add), add a new array with booleans that denote which are present and which are deleted (e.g. deleted\[4\] = 1 means that item 4 is deleted. This only cost 1 bit per element.
* Use two arrays with items, and copy them back and forth each time. This will cause not really a memory gap, but you need the storage needed for two arrays. And keep a variable which of the two arrays is the 'current'.
> 1 votes

---
Tags: c++, attiny, ide
---


title: Homodyne detection for arduino

text:
# Question
Title: Homodyne detection for arduino
In your code https://gist.github.com/edgar-bonet/0b03735d70366bc05fc6 for homodyne detection, is there a way to make the frequency detected a range of frequencies? For example detecting between 3kHz and 4kHz? Thanks in advance!

# Answer
> 0 votes
It may be possible to modify that program in order to get such a large frequency range:

* change the local oscillator frequency to 3.5 kHz
* drastically shorten the filter's time constant in order to get a wider passband

However, the homodyne detection scheme is best suited for building very narrow band filters. In your case, the upper limit you want is quite close to the Nyquist frequency (4,808 Hz), so I suggest you use a high-pass, rather than a band-pass filter. The simplest high-pass you can get is a numerical derivative:

y\[n\] = x\[n\] − x\[n−1\]

The gain of this filter is 2×sin(π×f/fsamp), so you get the −3 dB cutoff at fsamp/4 ≈ 2,404 Hz. If you need something better, you may want to try a higher order filter. But then you get deep into the territory of digital filter design, which can be tricky, especially if you have no experience with the z-transform or you want to implement the filter in fixed point.

**Edit**: If you really want a bandpass, the simplest I can think of is this two-pole filter:

y\[n\] = 0.360 x\[n\] − 0.885 y\[n−1\] − 0.552 y\[n−2\]

It will give you a maximum gain of roughly 1 at about 3.43 kHz, and −3 dB cutoffs at 3 and 4 kHz. A straightforward floating point implementation would be:

```
float filter(float x)
{
    static float y1, y2;
    float y = 0.360 * x - 0.885 * y1 - 0.552 * y2;
    y2 = y1;
    y1 = y;
    return y;
}

```

You should convert this to fixed point if you want to use it, otherwise I doubt your Arduino will have the processing power to run every sample through it. Below is a plot of this filter's gain, compared with the simple derivative, which I divided by 2 in order to normalize its gain:

Note that the gain gets flat as you approach the Nyquist frequency, and stays relatively high (above −5.4 dB).

---
Tags: arduino-uno
---


title: Gsm Sim800l Module

text:
# Question
Title: Gsm Sim800l Module
I am using below code for send sms but SMS Sent sucessfully but save in SIM memory & not able to see message text :

```
serialSIM800.write(“AT+CMGF=1\r”); //sending SMS in text mode
delay(1000);
serialSIM800.write(“AT+CMGS=“9827927887”\r”);
delay(1000);
serialSIM800.write(“Emergency at IIST\r”); // message
delay(1000);
serialSIM800.write(0x1A);
delay(1000);
Serial.println(“SMS sent successfully”);

```

Please help.

# Answer
> 1 votes
Set SMS Text Mode Parameters `AT+CSMP` to `AT+CSMP=17,167,0,0`

This setting is resolve your issue.

# Answer
> 1 votes
After few minutes of using Google, I found a library that contains everything you need to send/receive SMS and phone call. Here's the code I made in two minutes.

Currently I don't have SIM800L module, so I can't test it. Be sure you type a valid number format. For Croatia it's +385 XX XXX XXXX. +385 is an "international dialling code" for Croatia. Don't forget to put + before IDC.

```
serialSIM800.write("AT+CMGF=1\r");
serialSIM800.write("AT+CMGS=\"");
serialSIM800.write("PHONE_NUMBER");
serialSIM800.write("\"\r");
serialSIM800.write("Emergency at IIST");
serialSIM800.write("\r0x1A");

```

---
Tags: arduino-uno, gsm
---


# Question
Title: Arduino Nano burns with ESP-01 in parallel
So I have an Arduino Nano powered in parallel with an ESP-01 (for the ESP there is an extra LM1117-5.0 voltage regulator in series).

```
+12V ---------+---------+
              |         |
             Reg        |
              |        NANO
             ESP        |
              |         |
 GND ---------+---------+

```

My problem is that after a while, the Nano burns (my guess is the difference in current that both devices draw).

In any case, what could be the reason and what could I do to fix it?

Thanks!

# Answer
> 1 votes
Use the 5v regulator to power both the ESP and the Nano. Those onboard regulators have minimal heat dissipation and if they burn out you lose the whole Nano. Check how hot your external regulator gets and mount it on a heat sink if it gets too hot to touch. NB Connect the regulator output to the Nano 5v pin directly

# Answer
> 0 votes
12V is the upper limit for input voltage on an Arduino. With a 12V input the regulator has to convert 12-5, or 7 volts, to heat. (That's how linear voltage regulators work.) As the other poster said, Arduinos don't have much heat dissipation on their voltage regulators.

Like jksemple, I would suggest powering both the ESP and the Nano from the external regulator (You might want to cut a USB cable and wire it to your external voltage regulator, then plug it into your Nano. That way you're not bypassing the power control circuits on the Nano.

By the way, did you build a full voltage regulator with the LM1117 chip? You need some extra components like capacitors and resistors to complete the voltage regulator.

Finally, you might think about using a DC-DC buck converter rather than a linear regulator. That will run a lot cooler and waste a lot less power.

---
Tags: esp8266, arduino-nano
---


# Question
Title: Flash size in boards.txt ATmega 328p 32u4
The ATmega328p and ATmega32u4 microcontroller have 32Kb of flash memory (as datasheet). Bootloader for each microcontroleer has different size (about 512 byte for 328p and 4kb for 32u4).

Why in boards.txt the "upload.maximum\_size" parameters is 32256 for 328p and 28672 for 32u4?

I we have to consider bootloader size, the "upload.maximum\_size" parameter for 328p must be about 31.5k and not 32k. And, if we do not have to consider bootloader size, as the default boards.txt configuration (above) for 328p, the "upload.maximum\_size" parameter for 32u4 must be 32k not 28k. Correct?

Thank you

# Answer
> 1 votes
`1KB` is 1024 bytes, not 1000 bytes.

Therefore 32kb = 32768 bytes.

`32768-512=32256`, which is exactly the value used for upload.maximum\_size for the 328p.

4kb=4096 bytes. `32768-4096=28672` which is the value for the 32u4.

---
Tags: arduino-uno, atmega328, arduino-leonardo, atmega32u4
---


# Question
Title: Is volatile qualifier needed if shared variable cannot be changed externally during complete function call?
Consider the following example:

```
int i { 0 };

void incInt() {
    ++i;
}

int readInt() {
    return i;
}

setup() {
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(D1), incInt, CHANGE);
}

loop() {
    noInterrupts();
    int currI = readInt();
    interrupts();

    Serial.println(currI);
}

```

By wrapping the call to `readInt()` with `noInterrupts()` and `interrupts()` it is ensured that `i` cannot be changed externally during the execution of `readInt()`. `i` also cannot be changed externally during the execution of `incInt()`, as long as it is only called as ISR (interrupt service routine). Do I still need to declare `i` as `volatile`?

Does the situation change if `i` is accessed directly in the main loop:

```
loop() {
    noInterrupts();
    int currI = i;
    interrupts();

    Serial.println(currI);
}

```

In other words: What is the context in which the compiler expects a variable to not be changed externally if it is not declared `volatile`?

# Answer
Declaring a variable as `volatile` tells the compiler, that it always has to read the real variable and that it cannot use a cached value. Also the compiler cannot optimize this variable, since it is unknown, when the variable will change. For this it is irrelevant, how you actually read the variable in the main sketch, it only matters, that it get's read. Also this has nothing directly to do with doing the read atomically (with `noInterrupts()`) (though you only garantee correct values, when doing it)

So yes, you need to declare it volatile, or the compiler might think, that the value doesn't change and optimize it out in some way.

> What is the context in which the compiler expects a variable to not be changed externally if it is not declared volatile?

Externally here means outside of the main routine. This covers variables, that get changed in ISRs and also registers, that are changed by hardware (so the register definition in the used core are also `volatile`). The compiler cannot know, when these changes happen, because they are triggered by the hardware, not by the code. It will try to optimize your sketch (which is a rather complex procedure), and might see, that your variable is never changing in the code (the ISR does not get called from the main sketch, thus the compiler does not see it getting called) and will try to optimize it. To ensure, that your sketch works properly, it is your task to tell the compiler, that this variable can change at any time (so that it does not think the other way). You are doing this by declaring it as `volatile`
> 1 votes

# Answer
Let's forget about atomicity for a moment, which is a separate issue, and assume `i` is an atomic type (maybe `byte` or something equivalent). Consider the following code:

```
void loop()
{
    Serial.println(i);
}

```

Not so long ago I would have expected this to work just fine on Arduino, as there aren't many ways to compile this function… on its own! However, since version 1.6.10, the IDE enables link-time optimization. This means that the compiler (or rather, the optimizer working within the linker), can see the whole program and notice that `setup()` and `loop()` are called from only one function which belongs to the Arduino core:

```
int main()  // slightly simplified
{
    init();      // Arduino core initialization
    setup();     // User's initialization
    for (;;)
        loop();  // User's loop
}

```

This makes them perfect candidates for inlining:

```
int main()
{
    init();      // will likely be inlined too

    // Inlined setup():
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(D1), incInt, CHANGE);

    for (;;) {
        // Inlined loop():
        Serial.println(i);
    }
}

```

Now it should become clearer that repeatedly reading `i` from memory looks like a waste of time, which can be optimized-out. The `for` loop then becomes:

```
register uint8_t cached_i = i;  // save `i' in an internal CPU register
for (;;) {
    // Inlined loop():
    Serial.println(cached_i);
}

```

And now the program only prints zeros. That's why you need `volatile` to prevent that optimization.
> 1 votes

---
Tags: isr
---


title: Battery solution Nano 33 iOT

text:
# Question
Title: Battery solution Nano 33 iOT
Since the Nano 33 boards are quite new right now, I haven't found any details on how to hook one up with batteries.

I'm pretty daft when it comes to electronics (I'm a software man), and I read that the new Nano 33 requires 3.2V, which is a bit of a departure from the 5V the old models supported.

From what I can tell, I might be able to use a single LiFePO4 cell. Am I correct in this assumption? And if so, are there any pitfalls in going this route?

EDIT: I might have misunderstood the difference between operating voltage and input voltage. Does this mean that I can plug any AA battery pack in as a power source?

# Answer
> 7 votes
You can either use the 3.3V pin to supply power to the board, or use the Vin pin.

By using the VIN pin to power goes through a (step down) voltage regulator, that provides a nice stable 3.3V to the board. The regulator in the Nano 33 IoT is the `MPM3610`, which requires an input voltage of at least 4 - 4.5 Volt. Which is more that a LiPo or LiFePo single cell can supply. You could use a multi-cell battery pack. Or a USB power bank. So this solutions is not really ideal.

The other option was to connect the battery directly to the 3.3V pin. The voltage of a LiFePo however changes as it is being discharged. The voltage is around 3.65V when full, and 2.5-2.75V when "empty". The 3.2V rating is called the nominal voltage (kind of an average voltage). So it's a bit too high when full, and too low when empty. The voltage also isn't regulated, so it can fluctuate a bit, based on the amount of current that's being used.

The maximum voltage for the SAMD21 on this Nano is 3.63V. Maximum voltage for the gyro (LSM6DS3) is 3.6V. The absolute maximum voltage for the radio (NINA-W10) is 3.6V.

So a full LiFePo is slightly too high for the Nano. Though I think you should be fine. But don't try this with a regular LiPo of Lion battery (4.2V when full).

---
Tags: arduino-nano, battery, arduino-nano-33-iot
---


# Question
Title: Connecting to MQTT causes DHT11 Sensor to stop working?
I have a project I am working on, based on an ESP32 from NodeMCU. I have a bunch of sensors connected to said ESP32 - they all work and the code itself "works" with a minor quirk.

The issue in question starts with a DHT11 sensor. I started from the basic "hello world" DHT11 code (you can find it easily with a DHT11 search in google). That sensor works in my code that you can see below - I copied and pasted the sample code, and except for changing variables, did not alter the sample code really at all.

The issue I have is that while the sample code will read accurately on every loop, in my code, it reads from the sensor exactly once the first time the loop runs, and then never again.

I believe I have isolated the issue to this bit of code and the corresponding function it calls (it didn't used to be a function - that was a troubleshooting step):

```
  if (!client.connected()) {
    reconnectMQ();
  } etc...

```

By moving this statement and grouping the MQTT messaging to the end, the system runs a full loop with correct readings, exactly once, but after that function is called the DHT11 begins failing to read.

Things I have tried:

* different variable names for temp and humidity (in case "t" and "h" are in use in the MQ library)
* order of operations (made the loop work once)
* changing the reconnectMQ() to a full function and not just a loop in the main loop
* changing the logic of the DHT11 sensor to at least not hang forever trying to read - this meant it got through this part, but with 0 values
* "turning off" MQ - this means that everything works, but obviously is a bit like cutting off your arm for a sprained wrist.
* ENDLESS Google and Stack searches before resorting to this post.

I hate to do this as my project is 200 lines long, but I suspect the full code is needed to see what's possibly happening.

```
#include <time.h>
#include <DHT.h>
#include <WiFi.h>
#include <PubSubClient.h>

//use pin 23 to read temp and humidity
//our sensor is DHT11 type
//creates an instance of DHT sensor
#define DHTPIN 23
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

//Define the analog pins inbound for the Soil Moisture sensors
const int sm1Pin = 33;
const int sm2Pin = 34;
const int sm3Pin = 35;
const int sm4Pin = 32;

const int power = 22;
const int exec = 21;
const int net = 19;

//define the pin for the light level reading
const int light = 36;

//Init MQTT payload arrays
char data0[50];
char data1[50];
char data2[50];

// declare our Wifi and MQTT connections and other constant settings for the network
const char* ssid     = "*******";            // The SSID (name) of the Wi-Fi network you want to connect to
const char* password = "*******";                          // The password of the Wi-Fi network
const char* mqtt_server = "192.168.1.195";                             // The target mqtt server
const char* input_string = "{\"Reporting\":\"GardenUnit1\", ";       // The name of this garden monitor unit
String clientId = "GP1";
int lcount = 0;

// declare our Wifi and MQTT connections
WiFiClient espClient;
PubSubClient client(espClient);

//
// Reconnects to the MQTT message-bus if the connection died, or we're
// not otherwise connected.
//
void reconnectMQ() {

  digitalWrite(net, LOW);  // turn the Blue NET LED Off

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Wifi not connected - configuring");
    setup_wifi();
  } else {
    Serial.println("Wifi Connected - connecting MQTT");
  }

  // Attempt to connect
  Serial.println("Attempting to connect to MQTT Server...");
  while (!client.connected()) {
    if (client.connect(clientId.c_str())) {
      Serial.println("connected to MQTT server");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }

  // Once connected, publish an announcement...
  String payload = String(input_string) + "\"MQTT\":\"Reconnected\"}";
  payload.toCharArray(data1, (payload.length() + 1));
  client.publish("control", data1); //the "control" topic is just for notifications - change to fit your needs

  digitalWrite(net, HIGH);  // turn the Blue NET LED on
  delay(5000);
}

void setup_wifi() {
  delay(10);
  Serial.print("Connecting to ");
  Serial.print(ssid); Serial.println(" ...");

  WiFi.begin(ssid, password);             // Connect to the wifi network

  while (WiFi.status() != WL_CONNECTED) // Wait for the Wi-Fi to connect
    delay(1000);
    Serial.print('.');

  Serial.println('\n');
  Serial.println("Connected!");
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());         // Send the IP address of the ESP32 to the serial port

}

void setup() {
  Serial.begin(9600); // open serial port, set the baud rate as 9600 bps
  // These Options control the precision of the reading, and the voltage reduction capability of the ESP32
  // Attenuation number 3 is 11DB
  analogSetWidth(10);
  analogSetAttenuation((adc_attenuation_t)3);

  // Define the MQTT Server connection settings and then launch the MQTT Connection
  client.setServer(mqtt_server, 1883);

  // Set output and input pins to correct modes
  pinMode (power, OUTPUT);
  pinMode (exec, OUTPUT);
  pinMode (net, OUTPUT);

  //Turn on Green Power light
  digitalWrite (power, HIGH);

  //Connect to the wireless network
  setup_wifi();

  //This call starts the dht11 sensor instance
  dht.begin();
}

void loop() {
  //Turn on RED EXEC light - this means a sample is being taken
  digitalWrite (exec, HIGH);

  //Read DHT11 Temp and Humidity - Humidity is a % and temp is in Celcius
  float hum = dht.readHumidity();
  float temp = dht.readTemperature();
  // Check if any reads failed but insert bogus data so system continues
    if (isnan(hum) || isnan(temp)) {
        Serial.println("Failed to read from DHT sensor!");
        client.publish("garden1", "{\"Error\":\"Humidty/Temp Sensor Offline!\"}");
        hum = 0;
        temp = 0;
    } else {
        // print the result to Terminal
        Serial.print("Humidity: ");
        Serial.print(hum);
        Serial.print(" %\t");
        Serial.print("Temperature: ");
        Serial.print(temp);
        Serial.println(" *C ");
    }

  //Read value and print to serial for S1
  float s1 = analogRead(sm1Pin);
  Serial.print("Sensor 1: ");
  Serial.print(s1);
  Serial.println();
  //Read value and print to serial for S2
  float s2 = analogRead(sm2Pin);
  Serial.print("Sensor 2: ");
  Serial.print(s2);
  Serial.println();
  //Read value and print to serial for S3
  float s3 = analogRead(sm3Pin);
  Serial.print("Sensor 3: ");
  Serial.print(s3);
  Serial.println();
  //Read value and print to serial for S4
  float s4 = analogRead(sm4Pin);
  Serial.print("Sensor 4: ");
  Serial.print(s4);
  Serial.println();

  float L1 = analogRead(light);
  Serial.print("Light level: ");
  Serial.print(L1);
  Serial.println();

  if (!client.connected()) {
    reconnectMQ();
  }

  String payload = String(input_string) + "\"S1\":\"" + s1 + "\", \"S2\":\"" + s2 + "\", \"S3\":\"" + s3 + "\", \"S4\":\"" + s4 + "\"}";
  payload.toCharArray(data0, (payload.length() + 1));
  Serial.println("Publishing message 1:");
  while (!client.publish("garden1", data0)) {
    Serial.print(".");
  }
  String payload2 = String(input_string) + "\"Humidity\":\"" + hum + "\", \"Temperature\":\"" + temp + "\", \"Light\":\"" + L1 + "\"}";
  payload2.toCharArray(data2, (payload2.length() + 1));
  Serial.println("Publishing message 2:");
  while (!client.publish("garden1", data2)){
    Serial.print(".");
  }

  //Turn off RED EXEC light - this means a sample is done
  digitalWrite (exec, LOW);
  lcount = lcount + 1;
  delay(10000);
}

```

What happens when the code I have here runs is that I see all the messages at the Mosquito server and in serial monitor, and the loop runs as expected. Due to the logic I had to put in to keep the program running, after the first reading from the DHT11, temp and hum come back as 0 forever. This is obviously not what I want.

What is obvious: Something happens between the first reading of the DHT11 and the next that makes it unhappy.

What is not: What that something is. That something occurs in the MQTT connection, but for the life of me I cannot figure out what it is or isolate it.

So now I leave it to the community. What the heck is happening here?!

# Answer
Leaving this here in case anyone else has a similar issue as an "answer" to my own question:

Simply put - DHT11 library as used, and MQTT library as used conflict. That's it, that's the answer.

There are two options for correcting this depending on your needs:

* don't use or deeply examine and rebuild one of the libraries - frankly this was a negative ROI for me and not worth it
* Add an ESP.restart(); at the end of the main program loop and AFTER the sleep timer - this reboots the ESP and allows the DHT11 to read BEFORE the MQTT connection happens and the solution works.

This, in my mind is not "a fix" it is a workaround, but it does address the primary issue.
> 1 votes

# Answer
I've used the DHT11 library, not the DHT library in my sketches. The Example sketch should make it clear what minimal changes you'll need to make to your code. It always worked well for me.
> 0 votes

---
Tags: c++, esp32, mqtt
---


title: Why Wire.write twice?

text:
# Question
Title: Why Wire.write twice?
I'm checking an example for the MPU6050 and got to this part

```
Wire.beginTransmission(0x68);           //begin, Send the slave adress (in this case 68)
Wire.write(0x1B);                       //We want to write to the GYRO_CONFIG register (1B hex)
Wire.write(0x10);                       //Set the register bits as 00010000 (1000dps full scale)
Wire.endTransmission(true);             //End the transmission with the gyro

Serial.begin(9600);                     //Remember to set this same baud rate to the serial monitor
time = millis();                        //Start counting time in milliseconds

/*Here we calculate the gyro data error before we start the loop
 * I make the mean of 200 values, that should be enough*/
if(gyro_error==0)
{
  for(int i=0; i<200; i++)
  {
    Wire.beginTransmission(0x68);            //begin, Send the slave adress (in this case 68)
    Wire.write(0x43);                        //First adress of the Gyro data
    Wire.endTransmission(false);
    Wire.requestFrom(0x68,4,true);           //We ask for just 4 registers

```

Why is there two consecutive wire.write() in the begining and only one later? Is it different somehow?

# Answer
> 1 votes
The truth is, the Arduino Wire library sends the data only if `endTransmission` is called. Until then it collects the data in TX buffer. The version of the `write` function used in your snippet adds a byte to the TX buffer.

With I2C usually the first byte written is the address of the register to write. Then the data follow. In case of the first part in your snippet the data are only one byte long.

In the second part, first the register address is sent with `write` and then the data from this register and 3 following registers are requested.

---
Tags: arduino-uno, i2c, mpu6050
---


title: 'TCCR1B' was not declared in this scope

text:
# Question
Title: 'TCCR1B' was not declared in this scope
I'm trying to use a MS5540C (digital pressure sensor) and the sample code has this line:

```
 TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

```

I'm a bit of a noob to the IoT but its not beyond me to check the SPI.h and see that there is indeed no declaration.

I'm using an **Arduino UNO WiFi Rev 2**. (Seems like its pins are quit different from an UNO) I have noted in the comments that Im using pins 32,33,34 instead of 11,12,13

I'm not 100% sure what to ask … other than Is there a replacement call/function/method that should replace that line? ..or am I missing something else totally. As it stands now...when the program runs its results are inconsistent. I'm just commenting out the faulty line to get it to compile.

**Complete sketch** source: Future Electronics

```
/*
  MS5540C Miniature Barometer Module
  This program will read your MS5440C or compatible pressure sensor every 5 seconds and show you the calibration words, the calibration factors,
  the raw values and the compensated values of temperature and pressure.
  Once you read out the calibration factors you can define them in the header of any sketch you write for the sensor.

  Uno Pins:
  MS5540 sensor attached to pins 10 - 13:
  MOSI: pin 11
  MISO: pin 12
  SCK: pin 13
  MCLK: pin 9 (or use external clock generator on 32kHz)
  CS is not in use, but might be pin 10

  ==[ addendum start]=============================
  Uno WiFi Rev2 Pins:
  MOSI: pin 32
  MISO: pin 33
  SCK: pin 34
  MCLK: pin 9 (or use external clock generator on 32kHz)
  ==[ addendum end ]=============================

  created 29 February 2012
  by MiGeRA
*/

/*
  Calibration of my sensor example ...

  Calibration word 1 = 46958
  Calibration word 2 = 65369
  Calibration word 3 = 39392
  Calibration word 4 = 45914
  c1 = 23479
  c2 = 2074
  c3 = 717
  c4 = 615
  c5 = 1021
  c6 = 25
*/

#include <SPI.h>

const int clock = 9;

void setup() {
  Serial.begin(9600);
  SPI.begin(); //see SPI library details on arduino.cc for details
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz

  pinMode(clock, OUTPUT);
  delay(100);
}

void loop()
{
  Serial.println("=====================================================================");
  TCCR1B = (TCCR1B & 0xF8) | 1; //generates the MCLK signal

  analogWrite (clock, 128) ;
  resetsensor(); //resets the sensor - caution: afterwards mode = SPI_MODE0!

  //Calibration word 1
  unsigned int result1 = 0;
  unsigned int inbyte1 = 0;
  SPI.transfer(0x1D); //send first byte of command to get calibration word 1
  SPI.transfer(0x50); //send second byte of command to get calibration word 1
  SPI.setDataMode(SPI_MODE1); //change mode in order to listen
  result1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
  result1 = result1 << 8; //shift returned byte
  inbyte1 = SPI.transfer(0x00); //send dummy byte to read second byte of word
  result1 = result1 | inbyte1; //combine first and second byte of word
  Serial.print("Calibration word 1 = ");
  Serial.print(result1, HEX);
  Serial.print(" ");
  Serial.println(result1);

  resetsensor(); //resets the sensor

  //Calibration word 2; see comments on calibration word 1
  unsigned int result2 = 0;
  byte inbyte2 = 0;
  SPI.transfer(0x1D);
  SPI.transfer(0x60);
  SPI.setDataMode(SPI_MODE1);
  result2 = SPI.transfer(0x00);
  result2 = result2 << 8;
  inbyte2 = SPI.transfer(0x00);
  result2 = result2 | inbyte2;
  Serial.print("Calibration word 2 = ");
  Serial.print(result2, HEX);
  Serial.print(" ");
  Serial.println(result2);

  resetsensor(); //resets the sensor

  //Calibration word 3; see comments on calibration word 1
  unsigned int result3 = 0;
  byte inbyte3 = 0;
  SPI.transfer(0x1D);
  SPI.transfer(0x90);
  SPI.setDataMode(SPI_MODE1);
  result3 = SPI.transfer(0x00);
  result3 = result3 << 8;
  inbyte3 = SPI.transfer(0x00);
  result3 = result3 | inbyte3;
  Serial.print("Calibration word 3 = ");
  Serial.print(result3, HEX);
  Serial.print(" ");
  Serial.println(result3);

  resetsensor(); //resets the sensor

  //Calibration word 4; see comments on calibration word 1
  unsigned int result4 = 0;
  byte inbyte4 = 0;
  SPI.transfer(0x1D);
  SPI.transfer(0xA0);
  SPI.setDataMode(SPI_MODE1);
  result4 = SPI.transfer(0x00);
  result4 = result4 << 8;
  inbyte4 = SPI.transfer(0x00);
  result4 = result4 | inbyte4;
  Serial.print("Calibration word 4 = ");
  Serial.print(result4, HEX);
  Serial.print(" ");
  Serial.println(result4);

  //now we do some bitshifting to extract the calibration factors
  //out of the calibration words;
  long c1 = (result1 >> 1) & 0x7FFF;
  long c2 = ((result3 & 0x003F) << 6) | (result4 & 0x003F);
  long c3 = (result4 >> 6) & 0x03FF;
  long c4 = (result3 >> 6) & 0x03FF;
  long c5 = ((result1 & 0x0001) << 10) | ((result2 >> 6) & 0x03FF);
  long c6 = result2 & 0x003F;

  Serial.print("c1 = ");
  Serial.println(c1);
  Serial.print("c2 = ");
  Serial.println(c2);
  Serial.print("c3 = ");
  Serial.println(c3);
  Serial.print("c4 = ");
  Serial.println(c4);
  Serial.print("c5 = ");
  Serial.println(c5);
  Serial.print("c6 = ");
  Serial.println(c6);

  resetsensor(); //resets the sensor

  //Pressure:
  unsigned int presMSB = 0; //first byte of value
  unsigned int presLSB = 0; //last byte of value
  unsigned int D1 = 0;
  SPI.transfer(0x0F); //send first byte of command to get pressure value
  SPI.transfer(0x40); //send second byte of command to get pressure value
  delay(35); //wait for conversion end
  SPI.setDataMode(SPI_MODE1); //change mode in order to listen
  presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
  presMSB = presMSB << 8; //shift first byte
  presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
  D1 = presMSB | presLSB; //combine first and second byte of value
  Serial.print("D1 - Pressure raw = ");
  Serial.println(D1);

  resetsensor(); //resets the sensor

  //Temperature:
  unsigned int tempMSB = 0; //first byte of value
  unsigned int tempLSB = 0; //last byte of value
  unsigned int D2 = 0;
  SPI.transfer(0x0F); //send first byte of command to get temperature value
  SPI.transfer(0x20); //send second byte of command to get temperature value
  delay(35); //wait for conversion end
  SPI.setDataMode(SPI_MODE1); //change mode in order to listen
  tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
  tempMSB = tempMSB << 8; //shift first byte
  tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
  D2 = tempMSB | tempLSB; //combine first and second byte of value
  Serial.print("D2 - Temperature raw = ");
  Serial.println(D2); //voila!

  //calculation of the real values by means of the calibration factors and the maths
  //in the datasheet. const MUST be long
  const long UT1 = (c5 << 3) + 20224;
  const long dT = D2 - UT1;
  const long TEMP = 200 + ((dT * (c6 + 50)) >> 10);
  const long OFF  = (c2 * 4) + (((c4 - 512) * dT) >> 12);
  const long SENS = c1 + ((c3 * dT) >> 10) + 24576;
  const long X = (SENS * (D1 - 7168) >> 14) - OFF;
  long PCOMP = ((X * 10) >> 5) + 2500;
  float TEMPREAL = TEMP / 10;
  float PCOMPHG = PCOMP * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

  /*
    Serial.print("UT1 = ");
    Serial.println(UT1);
    Serial.print("dT = ");
    Serial.println(dT);
    Serial.print("TEMP = ");
    Serial.println(TEMP);
    Serial.print("OFFP = ");
    Serial.println(OFF);
    Serial.print("SENS = ");
    Serial.println(SENS);
    Serial.print("X = ");
    Serial.println(X);
  */

  Serial.print("Real Temperature in C = ");
  Serial.println(TEMPREAL);

  Serial.print("Compensated pressure in mbar = ");
  Serial.println(PCOMP);
  Serial.print("Compensated pressure in mmHg = ");
  Serial.println(PCOMPHG);

  //2-nd order compensation only for T < 20°C or T > 45°C

  long T2 = 0;
  float P2 = 0;

  if (TEMP < 200)
  {
    T2 = (11 * (c6 + 24) * (200 - TEMP) * (200 - TEMP) ) >> 20;
    P2 = (3 * T2 * (PCOMP - 3500) ) >> 14;
  }
  else if (TEMP > 450)
  {
    T2 = (3 * (c6 + 24) * (450 - TEMP) * (450 - TEMP) ) >> 20;
    P2 = (T2 * (PCOMP - 10000) ) >> 13;
  }

  if ((TEMP < 200) || (TEMP > 450))
  {
    const float TEMP2 = TEMP - T2;
    const float PCOMP2 = PCOMP - P2;

    float TEMPREAL2 = TEMP2 / 10;
    float PCOMPHG2 = PCOMP2 * 750.06 / 10000; // mbar*10 -> mmHg === ((mbar/10)/1000)*750/06

    Serial.print("2-nd Real Temperature in C = ");
    Serial.println(TEMPREAL2);

    Serial.print("2-nd Compensated pressure in mbar = ");
    Serial.println(PCOMP2);
    Serial.print("2-nd Compensated pressure in mmHg = ");
    Serial.println(PCOMPHG2);
  }

  delay(5000);
}

void resetsensor() //this function keeps the sketch a little shorter
{
  SPI.setDataMode(SPI_MODE0);
  SPI.transfer(0x15);
  SPI.transfer(0x55);
  SPI.transfer(0x40);
}

```

# Answer
> 3 votes
While writing this answer, I found out about the register emulation of the Arduino Uno Wifi. The Uno Wifi is a different chip, than the Uno, thus you have different registers. But the Uno Wifi was thought as a drop in replacement, so register emulation maps the old register names to the new registers, so that you can basically simply reuse the old code for the Uno. In my Arduino IDE (v1.8.9) I had a buildin Uno Wifi board, which seems to have the register emulation enabled without configuration option (I could compile your sketch even for the Uno Wifi). Through the board manager I installed the "Arduino megaAVR Boards" core, that contains the Arduino Uno Wifi rev2. If you choose this board in the board selection, you get the option to select the register emulation. For old code you need the emulation for ATmega328. With that, your old code should compile.

This makes the rest of my answer unnecessary, but since I already spend some time writing it, I will leave it in the answer for information and for the case, that you don't want to use the register emulation.

---

You get the error, because the sketch, that you copied is made for the Arduino Uno, not the Arduino Uno Wifi. While the first uses an ATmega328P chip, the last is build with an ATmega4809 (you can find this information here at the Arduino.cc store). These are different chips, thus you cannot simply reuse code that is made for the Uno on the Uno Wifi.

`TCCR1B` is the control register B of Timer 1. This name is specific to the ATmega328P chip. The ATmega4809 has even more timers than the 328P, but they seem to get configured via different registers. Refer to the datasheets on the product site of the ATmega4809. The timer hardware and it's registers are described in the more general megaAVR 0 series family datasheet. At the first glance it seems, that not only the register description is different from the 328P, but also the positions of the different configurations. This means, that every code, that uses direct register manipulations for the timer, must be rewritten for the 4809.

Fortunately, I see only 1 line here, that does this: The line, that generated the compiler error. (The SPI library very likely already has fitting definitions inside for the 4809). You have the line

```
TCCR1B = (TCCR1B & 0xF8) | 1;

```

That clears the 3 least significant bits (leaving the rest as it was) and setting the least significant bit to 1. According to chapter 16.11.2 of the 328P's datasheet (description of the TCCR1B register), these 3 bits are the clock selection. A bit code of `001` (only least significant bit set) means timer on, but with no prescaling.

To be honest, I'm not sure, if this line really does something, since directly after that, `analogWrite()` is called and I thought this function would overwrite the timer settings. But other posts (like this one) suggest, that it at least does not overwrite the clock selection.

I don't know, which timer get's used for outputting PWM to that pin, but for now, I will assume the first timer of type B. If you look into the families datasheet (as linked above) the clock source of the second timer (TCB) is configured with the register `TCB0.CTRLA` (see chapter 20.5.1). Bits 1 and 2 are configuring the prescaler (binary `00` for no prescaler), bit 0 enables the timer. So you can again write binary `001` to this register, leaving the rest untouched. So I suggest, you use this line instead of the old one

```
TCB0.CTRLA = (TCB0.CTRLA & 0xF8) | 1;

```

This should do the same with the second timer, that was done in the original sketch. If the first timer is used for this, you would have to change `TCB0` to `TCA0.SINGLE` (I really don't know, why this SINGLE is needed) and change `0xF8` to `0xF0`, since TCA has 3 bits for selecting the clock source.

---
Tags: arduino-uno, programming, spi, arduino-uno-wifi
---


# Question
Title: Arduino HTTP Request Fails Slow Cellular Connection
### Setup:

* Arduino Mega 2560 w/ Wiznet W5500 Ethernet Sheild
* Using TP-Link TL-MR6400 LTE router to connect to internet over cellular connection in Uganda.

---

Using an HTTP Post with the following,

```
client.println("POST /hook HTTP/1.1");
client.print("Host: "); client.println(server);
client.println("Accept: */*");
client.print("Content-Type: text/html;");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(PostData.length());
client.println();
client.println(PostData);

```

where PostData is a `String` and Ethernet2 is the library used.

This works just fine from the US to the same AWS server, or a https://requestbin.com/ instance.

---

When testing from Uganda using a Raspberry Pi and curl it works fine.

```
$ curl -vs -d 'ABCDEFG' -H "User-Agent: Arduino/1.0"  -H "Content-Type: text/html" -H "Connection: close"   http://<server here>/hook
*   Trying <ip here>...
* TCP_NODELAY set
* Connected to <server here> (<ip here>) port 80 (#0)
> POST /tg HTTP/1.1
> Host: <server here>
> Accept: */*
> User-Agent: Arduino/1.0
> Content-Type: text/html
> Connection: close
> Content-Length: 7
>
* upload completely sent off: 7 out of 7 bytes
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Content-Type: application/json; charset=utf-8
< Date: Tue, 06 Aug 2019 21:06:49 GMT
< x-pd-status: sent to primary
< X-Powered-By: Express
< Content-Length: 16
< Connection: Close
<
* Curl_http_done: called premature == 0
* Closing connection 0
{"success":true}

```

---

I even tried an HTTP GET example from the Ethernet2 library,

https://www.arduino.cc/en/Tutorial/WebClientRepeating

It worked just fine in the US but in Uganda I get,

```
My IP address: 192.168.1.177

connecting...

connecting...

connecting...

```

I increased the time between requests here to 100 seconds where it is listening for the whole time inbetween.

It seems that `client.connect(server, 80)` is successful and the `client.print` messages go through but the message never reaches the server so there is no response. My AWS server does not recieve the request and this is the same for the requestbin instance. This behavior is mirrored in all my Arduino tests.

I thought the ISP might be blocking but the RPi can send nearly the same message. I thought maybe a timeout somewhere but I can not find where with my tests. I thought my message was too long but I reduced the size to only 10 characters with the same results.

---

Trying to figure out why the Arduino HTTP request cannot reach any webhooks from Uganda and how to fix it if possible. Different ISP, slower connection, cellular connection?

Any help would be appreciated.

# Answer
**Buffering and flush()**

Many arduino libraries suffer of slow communication because the authors didn't use buffering. To not to send every small piece of data over a connection with overhead of protocol bytes use buffering. Data are collected until the buffer is full and then the collected data are send and the buffer is ready for next bytes. The flush() functions sends the buffer even if it is not full, but you do not have more data. (The flush() 'dilemma' was resolved and in Arduino core classes the flush() method is declared in Print class which is the Arduino standard interface for output streams.)

My StreamLib library offers a BufferedPrint class which wraps the target stream and buffers the data to be send over the target stream. Of course, do not forget to use flush() after last data printed.

---

**HTTP data length**

It is common practice in Arduino sketches to not to send the Content-length header with POST requests. In most cases it is because when the HTTP headers are send, the size of data is not known. The WebServer then doesn't know if it received all the data and waits until the connection is closed or timeout is reached. It leads to long time until a Web Server sends the response to requesting Arduino sketch.

If the data can be prepared to a string in memory, fill the Content-length HTTP header.

If the data to be send as response or in POST request wouldn't fit into available memory, ChunkedPrint from my StreamLib can be used with HTTP chunked Transfer-Encoding. And ChunkedPrint is an extension of BufferedPrint so the Web Server handles your request without hesitating.
> 1 votes

---
Tags: ethernet, http, ethernet-shield
---


title: SIM800L GSM module is not working

text:
# Question
Title: SIM800L GSM module is not working
I'm testing SIM800L GSM module with Arduino UNO and module is blinking 3 times every 15 seconds or sometime every 45 seconds. Why this is happening? In serial monitor it shows `Message Sent Successfully!` but I'm not getting any message.I tried with multiple numbers. Still not getting any message.

I have tested several codes which shows outputs of AT commands. Nothing was working. Power supply is 5V 5A.

```
/*
 *   Author@ExploreEmbedded
 *   Example to Send messages Interactively using GSM Sim800L
 *
 *   LIBRARY CREDITS:
 *   Thanks to Cristian Steib(steibkhriz@gmail.com) for the library.
 *
 *
 *
 *      PINOUT:
 *        _____________________________
 *       |  ARDUINO UNO >>>   Sim800L  |
 *        -----------------------------
 *            GND      >>>   GND
 *        RX  10       >>>   TX
 *        TX  11       >>>   RX
 *       RESET 2       >>>   RST
 *
 *
*/

#include <Sim800L.h>
#include <SoftwareSerial.h> //is necesary for the library!!
Sim800L Sim800L;  //to declare the library
char text[161]=""; //buffer to store message
char number[11]=""; //phone number to send message
int cnt;
bool error; //to catch the response of sendSms

void setup(){
    Sim800L.begin(); // initializate the library.
    Serial.begin(9600);
}

void loop(){

      //Read the Number
      Serial.print("\nEnter 10 digit Phone Number:");
      while(Serial.available()<=0);
      cnt = Serial.readBytesUntil('\n',number, 11);
      number[cnt] = '\0';
      Serial.println(number);

      //clear the serial input buffer so that no typed characters are pending

      delay(1000); //delay required before clearing the input buffer
      while(Serial.available()>0) //clear buffer
      {
        Serial.read();
      }

      //Read the Message to be sent
      Serial.print("Enter Message:");
      while(Serial.available()<=0);
      cnt = Serial.readBytesUntil('\n',text, 160);
      text[cnt] = '\0';
      Serial.println(text);
      delay(1000);

      while(Serial.available()>0) //clear buffer
      {
        Serial.read();
      }

      //Send the message and display the status
      error = Sim800L.sendSms(number,text);
      if(error)
      Serial.println("Error Sending Message");
      Serial.println("Message Sent Successfully!");

}

```

# Answer
I found what's happening. Module was shutdown due to over voltage.
> 1 votes

---
Tags: arduino-uno, gsm
---


# Question
Title: I don't know how to do the code for an rtc controlling a relay
I'm doing a project for my brother witch is an automatic watering thing, it's all working fine but I just don't know how to repeat the code to make the relay say come on for 5min at 0900 than 5min at 1200 and also 5min at 1700. how do I do this, I'm not very good at this so I need clear instructions or someone to write it. pls help. thank you, James.

here is the code I need to be repeated to meet what I need done, basically I just need the relay to trigger every 4h for 5min. its on an rtc on an Arduino UNO.

```
#include <DS3231.h>

int Relay = 4;

DS3231  rtc(SDA, SCL);
Time t;

const int OnHour = 19; //SET TIME TO ON RELAY (24 HOUR FORMAT)
const int OnMin = 55;
const int OffHour = 19; //SET TIME TO OFF RELAY
const int OffMin = 56;

void setup() {
  Serial.begin(115200);
  rtc.begin();
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
}

void loop() {
  t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);

  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

    else if(t.hour == OffHour && t.min == OffMin){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
}

```

# Answer
> 0 votes
You will most likely find nobody here, who will write the code for you, since this is not a free code writing service. But I will suggest a good way.

> I just need the relay to trigger every 4h for 5min

The phrase "every x hours" screams for using the modulo operator `%`. Modulo gives you the rest value of an integer division. See these values:

```
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...
7 % 4 = 3
8 % 4 = 0

```

You see, the modulo 4 operation gives you zero every 4 hours starting with midnight. So make an if statement based on that

```
if(hour % 4 == 0 && min == 0)

```

to switch on and

```
if(hour % 4 == 0 && min == 5)

```

to switch off. Just change your code in this way and you are done.

---
Tags: arduino-uno, programming, rtc
---


title: Problem with hc-05 bluettoth module

text:
# Question
Title: Problem with hc-05 bluettoth module
I wrote a simple program for controlling an LED using mobile. So, I bought the HC-05 bluetooth module configured it and then connected it to the arduino.

This is the code that I wrote for it.

```
int ledPin1=13;
int state;
int flag=0;

void setup()
{
    pinMode(ledPin1, OUTPUT);
    digitalWrite(0,HIGH);

    second:
    Serial.begin(9600);
}

void loop()
{
    if(Serial.available() >0)
    {
        state = Serial.read();
        flag=0;
    }
    if (state == '0')
    {
        digitalWrite(ledPin1, LOW);
        if(flag == 0){
            Serial.println("led off");
            flag=1;
        }
    }
    if (state == '1')
    {
        digitalWrite(ledPin1, HIGH);
        if(flag == 0){
            Serial.println("led on");
            flag=1;
        }
    }
}

```

Everything is working cool with the serial monitor. But, I'm not able to control it using my mobile. I gave an input 1 in serial monitor and if showed "led on". the same thing appears on the commanding interface of the app used in the mobile. So, the bluetooth is transmitting information from the arduino to mobile but I'm not able to send commands from the mobile and control the led. I tried using various apps like Blueterm, Ardudroid etc but, the situation remains the same.

What am I doing wrong? Is there something wrong with the code?

I'm using Arduino Uno.

# Answer
> 2 votes
Your android app might be sending extra characters like "end of line", which will cause the return value of `Serial.read()` to be other than `1` or `0` after the first byte. Nevertheless, it looks like it should still turn on or off the LED as soon as it reads the first byte, and do nothing when it reads the following bytes. I have used the "hyperterminal rs232" app successfully to send single characters, maybe give that I try to see if it helps and ensure it is configured at the correct baud rate.

I would recommend to send back to the serial stream the characters read, to ensure they have been received correctly, so I would change this:

```
if(Serial.available() >0)
{
    state = Serial.read();
    flag=0;
}

```

to:

```
if(Serial.available() >0)
{
    state = Serial.read();
    Serial.print(state);
    flag=0;
}

```

**Edit:**

Just realised this in `setup()`:

```
digitalWrite(0,HIGH);

```

You are setting the receive pin of the UART peripheral to hight, so that is probably why you are not reading data from your phone.

# Answer
> 0 votes
Why don't you try making another code. If you want to use library, use `#include <SoftwareSerial.h>`

Do not use `digitalWrite(0, HIGH)` in `void setup(){...}`

Declare `ledPin = 13;`

Use only `pinMode` and `Serial.begin(9600)` in `void setup()`

In `loop()` do ask `if (Serial.available()){...}`

---
Tags: arduino-uno, led, bluetooth
---


# Question
Title: Arduino and PHP communication only work if I open the Arduino IDE
I have a problem. I try to open a channel to arduino and PHP talk, the PHP would send a command and the Arduino should answer that. It works, but only if I execute some steps before:

1. sudo chmod 777 /dev/ttyACM0
2. sudo arduino
3. Open the serial monitor in arduino IDE
4. Close the serial monitor
5. Now everything is ok, they can talk

The first step is ok, I really need to do this, the 2-4 seems irrelevant, but the communication do not start without it. I put one LCD in arduino to print what he receive, when I send "HEYARD" with PHP to him, the RX led blinks and the TX led also, but nothing is printed on LCD. If I do the 2-4 steps, when PHP send "HEYARD", LCD show HEYARD and arduino answer with "HEYPHP"

Anyone could help? There is some way to open it via Terminal, or, at least, open the Serial Monitor from arduino and close to see if this start

# Answer
> 1 votes
Here the setup block:

```
<?php
    require("php_serial.class.php");
    $serial = new phpSerial();
    $serial->deviceSet("/dev/ttyACM0");
    $serial->confBaudRate(9600);
    $serial->confParity("none");
    $serial->confCharacterLength(8);
    $serial->confStopBits(1);
    $serial->confFlowControl("none");
    $conect = mysql_connect("localhost", "root", "") or print (mysql_error());
    mysql_select_db("ANM", $conect) or print(mysql_error());
?>

```

And here the connection block:

```
<?php
    $serial->deviceOpen();
    exec("echo 'HEYARD' > /dev/ttyACM0");
    sleep(1);
    $read = $serial->readPort();
?>

```

# Answer
> 0 votes
stty -F /dev/ttyACM0 ignpar stty -F /dev/ttyUSB0 ignpar

> IGNPAR Ignore framing errors and parity errors.

That is what you need to fix minor framing issues.

Screen switches this by default; but NONE of the serial drivers do. Especially when connecting PIs or BBB to Arduinos

---
Tags: serial, linux
---


# Question
Title: What is causing this warning in Arduino IDE?
I'm using DS3231 module with rinkydink library and it is working just fine, however every time i want to compile the code Arduino IDE shows this warning:

```
C:\Program Files (x86)\Arduino\libraries\DS3231\DS3231.cpp:291:106:
warning: ISO C++ forbids converting a string constant to 'char*'
[-Wwrite-strings]

```

What is this warning and how to solve it?

# Answer
The warning was caused by this line:

```
char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

```

In C++, the content of a character string such as `"Jan"` cannot be modified. Thus, if you assign the string to a pointer, the pointer should be declared as **const** char \*:

```
const char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

```

The same applies to the other arrays of strings: `daysLong`, `daysShort` and `monthLong`. As a consequence, the prototypes of the methods `getDOWStr()` and `getMonthStr()` should be changed in order to return a `const char *`.

BTW, are you sure this library is still maintained? This should have been fixed a long time ago, and it seems the source was last modified in 2015. You may be better off using a more modern alternative. For instance, in the Arduino library manager, you can find DS3231 and Adafruit's RTClib.
> 2 votes

# Answer
The DS3231 library from Rinky Dink is the best RTC library there is...I know, I tried them ALL. This library allows one to print date and time strings with only 3 Arduino print statements: Serial.print(rtc.getDateStr()); Serial.print(" -- "); Serial.println(rtc.getTimeStr()); Other RTC libraries force user to make the strings up themselves, at a cost of about 12 lines of useless Serial.print commands.
> 1 votes

---
Tags: arduino-uno, library
---


# Question
Title: SoftwareSerial receives beginning of data mangled
I'm using SoftwareSerial to communicate with a Sigfox module. Documentation for the `read` function assigns its value to a `char`. However using it I get mangled characters and also have read in other question that I should assign it to `int` as it can return `-1` for no data and `[0;255]` for received character.

This is my basic troubleshooting example:

```
#include <SoftwareSerial.h>
SoftwareSerial Sigfox(11,10);

void setup() {
  Serial.begin(9600); // HW serial
  Sigfox.begin(9600); // SW serial --> sigfox
}

void loop() {
  if(Sigfox.available()) {
    int c = Sigfox.read();
    Serial.write(c);
  }
  if(Serial.available()) Sigfox.write(Serial.read());
}

```

When `c` is char, I get `-5` instead of `OK`. Also other output is mangled. When `c` is int, it receives the data OK.

My question is - why they use `char` in the example in documentation? Why is `char` signed in Arduino?

I want to read the entire line of text from serial port and store it into array. How to define that array? I have found an example on web that uses `char buffer[32]`, but then again I get mangled data when I assign to it. If I use array of `byte`/`int`/`unsigned char`, I can't print it as `Serial.write(SF_buffer);` won't compile because of `no matching function for call to 'write(unsigned char [32])'`.

So what variable types should I use to receive and store the text from SoftwareSerial correctly?

Here is my function for reading the whole line:

```
unsigned char SF_buffer [32]; // max length of line to read from serial
bool SigfoxReadine() { // return true when whole line was received and is in buffer
  static int SF_cnt=0;
  while (Sigfox.available()) {
    int c = Sigfox.read();
    SF_buffer[SF_cnt++] = c;
    if ((c == '\n') || (SF_cnt == sizeof(SF_buffer)-1)) {
       SF_buffer[SF_cnt] = '\0';
       SF_cnt = 0;
       return(true);
    }
  }
  return(false);
}

```

**UPDATE:**

Trying `readBytesUntil` \- the same result, but I have found that issue is only when I send data to module using `println` as in this example:

```
#include <SoftwareSerial.h>
SoftwareSerial Sigfox(11,10);

void setup() {
  Serial.begin(9600); // HW serial
  Sigfox.begin(9600); // SW serial --> sigfox
  Sigfox.println("AT$I=11");
}

void loop() {
  if(Serial.available()) Sigfox.write(Serial.read());
  SF_read();
}

void SF_read() {
  if (Sigfox.available()) {
    char buff[32];
    int l = Sigfox.readBytesUntil('\n', buff, sizeof(buff));
    if (l > 0 && buff[l - 1] == '\r') {
      l--; // to remove \r if it is there
    }
    buff[l] = 0; // terminate the string
    Serial.println(buff);
  }
}

```

The response to first command (in setup) is mangled. The response to the same AT command manually written into serial monitor (and sent to module via Sigfox.write in loop) is OK.

> ӂ\*⸮FBB1E27EE7
>
> 3430E2FBB1E27EE7

Also maybe I'm little lost in when to use print and when write... Example says to use `write()` to send back the char that was `read()`. Juraj's response uses `println()` to print the null-terminated buffer. What is the difference when I write/println this buffer?

# Answer
> 2 votes
I like the readBytes or readBytesUntil function. It doesn't end on a small gap between received bytes and fills the buffer. This functions are blocking with timeout, but if read some other device the input is usually fast and terminated reliably.

example for readBytesUntil:

```
if (Serial.available()) {
  char buff[32];
  int l = Serial.readBytesUntil('\n', buff, sizeof(buff));
  if (l > 0 && buff[l - 1] == '\r') {
    l--; // to remove \r if it is there
  }
  buff[l] = 0; // terminate the string
  Serial.println(buff);
}

```

# Answer
> 1 votes
Last test showed it mangles data only when using `println()` and doesn't depend on the `char` type. Then I remembered something about CRLF in the Sigfox datasheet:

> Is recommended to use full duplex UART. In case of using half duplex, AT commands has to be ended only with one of ‘\r’ or ‘\n’ not both. Because if you send “AT\r\n” the Sigfox devkit starts sending “OK” instantly after it receive ‘\r’, but microcontroller is still sending byte ‘\n’.

SoftwareSerial is in fact half-duplex only (although I didn't find it in the reference documentation) and `println()` sends both '\r' and '\n', so while sending the later, Sigfox module is already trying to send back the answer, which gets mangled by SoftwareSerial.

Feel free to add your answer to explain why `char` is signed in Arduino and when to use `print()` and when `write()` with serial port.

---
Tags: softwareserial, data-type
---


# Question
Title: Arduino Uno board not recognized in IDE. Board is not in device manager!
My arduino uno is not recognized by the Arduino IDE. I'm using 1.8.0, The IDE is not showing the COM. The tool section is showing only COM 1, i.e. the hardware.

I opened Device manager, there is no board for UNO.

Help me please.

Arduino Nano works fine.

I have CH340 driver already installed. My computer do not make any "hardware connected sound". I have 3 arduino IDE versions - 1.8.0, 1.8.9, 1.8.10!.

# Answer
I had a similar problem with my Arduino. My solution is to unplug it, replug it and do what you need to do before the computer can auto-configure it. I hope it helps! :) BTW make sure you are choosing the right board.
> 0 votes

# Answer
According to https://www.arduino.cc/en/Guide/ArduinoUno, you may need to install a separate driver for the Arduino Uno because it does not have a true USB port. The details are in the link.
> 0 votes

---
Tags: arduino-uno
---


title: Library compilation error

text:
# Question
Title: Library compilation error
Need help for this Tutorial. I tried to compile the code, but I'm getting compiling error.

I tried to ask on that forum too but got no answer, the error is:

```
In file included from C:\Program Files (x86)\Arduino\libraries\SD\src/utility/SdFat.h:32:0,
Multiple libraries were found for "SD.h"from C:\Program Files (x86)\Arduino\libraries\SD\src/SD.h:20,
 Used: C:\Program from D:\FEMV3FKI7YLJVQQ\FEMV3FKI7YLJVQQ.ino:1:
 Not used: C:\Users\IBNUM
C:\Program Files (x86)\Arduino\libraries\SD\src/utility/BlockDriver.h:31:10: fatal error: FatLib/BaseBlockDriver.h: No such file or directory
Multiple libraries were found for "SPI.h"
 #include "FatLib/BaseBlockDriver.h"
 Used: C:\Program
          ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

```

How can I fix this Arduino compile error?

# Answer
> 1 votes
I have the same problem since version 1.8.10.

With a good running sketch I don't get any message "Multiple libraries were found" (and no warnings also)

But with every small compiler error I get a whole list of "Multiple libraries were found"

My custom libraries are in a sketchbook location D:\DATA BACKUPPED\Documenten Albert\Arduino\Sketchbook-and-user-libraries

---
Tags: library, compilation-errors
---


title: Relay board not working with nodemcu

text:
# Question
Title: Relay board not working with nodemcu
This is the relay board

I am using nodemcu to make a home automation project which is controlled by google assistant. This is the code i am using is this one

```
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define Relay1            D0
#define Relay2            D1
#define Relay3            D2
#define Relay4            D3

#define WLAN_SSID       "Subhodip"             // Your SSID
#define WLAN_PASS       "09003244135"        // Your password

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "SubhodipRoy"            // Replace it with your username
#define AIO_KEY         "50a98bb44f6b48b69e645badadf8fb577894"   // Replace with your Project Auth Key

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe Light1 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME"/feeds/Relay1"); // FeedName
Adafruit_MQTT_Subscribe Light2 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay2");
Adafruit_MQTT_Subscribe Light3 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay3");
Adafruit_MQTT_Subscribe Light4 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Relay4");

void MQTT_connect();

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

  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  pinMode(Relay3, OUTPUT);
  pinMode(Relay4, OUTPUT);

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Setup MQTT subscription for onoff feed.
  mqtt.subscribe(&Light1);
  mqtt.subscribe(&Light3);
  mqtt.subscribe(&Light2);
  mqtt.subscribe(&Light4);
}

void loop() {

  MQTT_connect();

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(20000))) {
    if (subscription == &Light1) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light1.lastread);
      int Light1_State = atoi((char *)Light1.lastread);
      digitalWrite(Relay1, Light1_State);

    }
    if (subscription == &Light2) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light2.lastread);
      int Light2_State = atoi((char *)Light2.lastread);
      digitalWrite(Relay2, Light2_State);
    }
    if (subscription == &Light3) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light3.lastread);
      int Light3_State = atoi((char *)Light3.lastread);
      digitalWrite(Relay3, Light3_State);
    }
    if (subscription == &Light4) {
      Serial.print(F("Got: "));
      Serial.println((char *)Light4.lastread);
      int Light4_State = atoi((char *)Light4.lastread);
      digitalWrite(Relay4, Light4_State);

    }
  }

}

void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;

  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
    retries--;
    if (retries == 0) {
      // basically die and wait for WDT to reset me
      while (1);
    }
  }
  Serial.println("MQTT Connected!");

}

```

Connecting the pins as stated below

VIN--\>VCC D0--\> IN1 D1--\> IN2 D2--\>IN3 D3--\>IN4 Gnd--\>Gnd

But only IN2,IN3 and IN4 led of relay board are only glowing the IN1 is not glowing and the relays are not switching on/off...

Anyone please help....

Please give any solution... Why the relays are not switch-on?

Please reply as soon as possible... I am very disturbed... Even cant sleep at night....

# Answer
> 1 votes
From the description and comments it looks like the problem is HW related. I recommend you to do a relay module test (wthout NodeMCU):

1. Try to switch the relays on/off just by connecting the power source you are using for powering the NodeMCU. Connect VCC–5V, GND–GND and one of the IN channels directly to 5V pin. If the relay switches on, try another channel. If not, try to connect IN to GND instead of 5V (inverted logic).
2. If 1. did not worked, check the yellow jumper on the right side of the relay board. The jumper must be attached (in case you don't want to use another independent power source just for relays).
3. If 2. did not worked, check if the relay board is not intended for use with 12 V DC power source (check the relay marking).

At this point you should know if all channels of the relay module are working and also the switching logic (inverted/noninverted). The next step should be connecting the relay module to the NodeMCU and run a "blink" example for all channels. If all is working well, we will be sure the problem is NOT HW related...

---
Tags: nodemcu, adafruit, iot, home-automation
---


# Question
Title: Atmega collecting and relaying interrupt calls
I like to collect all possible interrupt and relay them to an alternative handler interrupt table what the user can set.

In order to do this i have to:
1) collect all/any interrup request
2) identify where is the interruption came from
3) relay the call to another table the user pointed.

If you familiar with interrupts you know if you registers a single function to all interrupt handler there's no way to idenfity the source of the interrupt. But registering unique interrupt handler that carries the information of the source and calls another function to dispatch call, for each interrupt is a code space wasting. Eg.: the atmega328 has 24 interrupt handlers. Each of the is compiled with the avr-gcc consumes 76 bytes.

---

But i have and idea how it is possible to register one handler function and identify the source:

```
00000000 <__vectors>:
   0:   0c 94 34 00     jmp 0x68    ; 0x68 <__ctors_end>
   4:   0c 94 51 00     jmp 0xa2    ; 0xa2 <__bad_interrupt>
   8:   0c 94 51 00     jmp 0xa2    ; 0xa2 <__bad_interrupt>
   c:   0c 94 51 00     jmp 0xa2    ; 0xa2 <__bad_interrupt>

```

If i define an interrupt handler (even if it can fit the 4 byte space) a jmp instruction is placed. If it can be replaced to eg.: call 0xa2 (which can fit in 4 bytes), is can be used to identify the interrupt source address.

Because `call` stores the return address, the function started at 0xa2 can read back that address and therefor idenfity the caller. Then add an extra `pop` (pop the stack address accumulated by the `call` at the interrup table) and `reti` (to return as like from an interrupt handler) after the function body.

If this can work theorically, to achieve this only one question remains:

How can i replace the `jmp` instructions to `call` in interrupt table?

# Answer
The interrupt vector table is provided by the C runtime. It is not *normally* intended to be overridden by user code. You can, however, do it, if you replace the whole C run time by your own, and compile your sketch with the `-nostartfiles` option.

I have played this game once I was trying to accurately assess interrupt latencies. See the details in this answer (the answer is long, but you can go right to the last section).
> 1 votes

# Answer
The answer i've accepted is the proper answer for the problem i asked. However replacing the C runtime requires to attach and maintain a lot of crt.S files oiginally related to the GCC. To avoid this i "slept several times over this prolem" and came out another solution.

After compiling the host application that have to redirect the interrupt calls (script source). I wrote a utility that rewrites every interrupt jumps at the beginning of the ihex (source) with an offset to the target application.

Ok this solution doesn't collect and identify and relay the incoming interrupts, just relay them. As far as there's no target application, nothing enables these interrupts and cause fault. This solution also doesn't use extra code space.
> 1 votes

---
Tags: interrupt, atmega328, avr, avr-gcc, assembly
---


title: ESP32 access point code not compiling

text:
# Question
Title: ESP32 access point code not compiling
I'm trying to use the ESP32 board to control an LED, buzzer, and motor (ABA) through an access point.

I got some code from this page: https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/ Which is amazing! I changed some names here and there and evrything okay (to control ONLY 2 things).

Now that I wanted to add the 3rd device, the code is not compiling.

I get this error:

```
exit status 1

too few arguments to function 'String SendHTML(uint8_t, uint8_t, uint8_t)'

```

With the line in bold marked.

**server.send(200, "text/html", SendHTML(ABA1status,false));**

```
#include <ETH.h>
#include <WiFi.h>
#include <WiFiAP.h>
#include <WiFiClient.h>
#include <WiFiGeneric.h>
#include <WiFiMulti.h>
#include <WiFiScan.h>
#include <WiFiServer.h>
#include <WiFiSTA.h>
#include <WiFiType.h>
#include <WiFiUdp.h>

#include <HTTP_Method.h>
#include <WebServer.h>

/* Put your SSID & Password */
const char* ssid = "ESP32DeltaSolutions";  // Enter SSID here
const char* password = "deltasolutions123";  //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,1,2);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

WebServer server(80);

uint8_t LED1pin = 25;
bool LED1status = LOW;

uint8_t BUZZ1pin = 32;
bool BUZZ1status = LOW;

uint8_t ABA1pin = 35;
bool ABA1status = LOW;

void setup() {
  Serial.begin(115200);
  pinMode(LED1pin, OUTPUT);
  pinMode(BUZZ1pin, OUTPUT);
  pinMode(ABA1pin, OUTPUT);

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);

  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/buzz1on", handle_buzz1on);
  server.on("/buzz1off", handle_buzz1off);
  server.on("/aba1on", handle_aba1on);
  server.on("/aba1off", handle_aba1off);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
  if(LED1status)
  {digitalWrite(LED1pin, HIGH);}
  else
  {digitalWrite(LED1pin, LOW);}

  if(BUZZ1status)
  {digitalWrite(BUZZ1pin, HIGH);}
  else
  {digitalWrite(BUZZ1pin, LOW);}

  if(ABA1status)
  {digitalWrite(ABA1pin, HIGH);}
  else
  {digitalWrite(ABA1pin, LOW);}

}

void handle_OnConnect() {
  LED1status = LOW;
  BUZZ1status = LOW;
  ABA1status = LOW;
  Serial.println("GPIO4 Status: OFF | GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,BUZZ1status,ABA1status));
}

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO4 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED1status));
}

void handle_led1off() {
  LED1status = LOW;
  Serial.println("GPIO4 Status: OFF");
  server.send(200, "text/html", SendHTML(false,LED1status));
}

void handle_buzz1on() {
  BUZZ1status = HIGH;
  Serial.println("GPIO5 Status: ON");
  server.send(200, "text/html", SendHTML(BUZZ1status,true));
}

void handle_buzz1off() {
  BUZZ1status = LOW;
  Serial.println("GPIO5 Status: OFF");
  server.send(200, "text/html", SendHTML(BUZZ1status,false));
}

void handle_aba1on() {
  ABA1status = HIGH;
  Serial.println("GPI35 Status: ON");
  server.send(200, "text/html", SendHTML(ABA1status,true));
}

void handle_aba1off() {
  BUZZ1status = LOW;
  Serial.println("GPI35 Status: OFF");
  **server.send(200, "text/html", SendHTML(ABA1status,false));**
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t LED1status,uint8_t BUZZ1status,uint8_t ABA1status){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #3498db;}\n";
  ptr +=".button-on:active {background-color: #2980b9;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP32 Web Server</h1>\n";
  ptr +="<h3>Using Access Point(AP) Mode</h3>\n";
  ptr +="<h3>Delta solutions</h3>\n";

   if(led1stat)
  {ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
  else
  {ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

  if(buzz1stat)
  {ptr +="<p>BUZZ1 Status: ON</p><a class=\"button button-off\" href=\"/buzz1off\">OFF</a>\n";}
  else
  {ptr +="<p>BUZZ1 Status: OFF</p><a class=\"button button-on\" href=\"/buzz1on\">ON</a>\n";}

  if(aba1stat)
  {ptr +="<p>ABA1 Status: ON</p><a class=\"button button-off\" href=\"/aba1off\">OFF</a>\n";}
  else
  {ptr +="<p>ABA1 Status: OFF</p><a class=\"button button-on\" href=\"/aba1on\">ON</a>\n";}

  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;

```

Any suggestions?

Thanks!

# Answer
> 1 votes
The syntax of six `SendHTML` you use with `true` and `false` is actually wrong.

By defining a function like this `String SendHTML(uint8_t LED1status,uint8_t BUZZ1status,uint8_t ABA1status)`, you mean that first, second and third input to this function are Status of LED1, Status of BUZZ1 and Status of ABA1.

So try replacing all six `SendHTML` with `true` and `false` functions to this `SendHTML(LED1status,BUZZ1status,ABA1status)`

---
Tags: arduino-uno, esp8266, arduino-ide, esp32
---


title: Noisy analogRead

text:
# Question
Title: Noisy analogRead
I'm trying to read voltage using Arduino, here's the code:

```
float r1 = 99700;
float r2 = 10004;
float adc, voltage;
unsigned long analog;
void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
  pinMode(A0, INPUT);
}

void loop() {
  for (int i = 0; i < 64; ++i) {
    analog += analogRead(A0);
    delay(1);
  }
  analog = analog / 64;
  adc = (analog * 2.441) / 1024;
  voltage = adc / (r2 / (r1 + r2));
  Serial.print(analog);
  Serial.print(", ");
  Serial.print(adc);
  Serial.print(", ");
  Serial.print(voltage);
  Serial.println(" ");
}

```

Had a VERY noisy reading and what I did was adding an external voltage reference (TL431) and also connected a 9V switching adapter to Arduino UNO. But I still had some noise in analog readings so as you can see in the code I'm taking 64 sample and averaging them.

After doing all those noise reduced a lot but not completely:

What else should one do to get an steady reading?

<sub>*By taking 1024 sample noise will be removed but then I'm sacrificing performance...*</sub>

# Answer
> 2 votes
I solved the problem by adding 3 capacitors:

1. 220uF on the Arduino power supply.
2. 100uF on TL431 output.
3. 1uF on A0 input.

I also increased the sampling rate to 128 times (and removed the delay).

Here's the result, as accurate as my multimeter:

There's still 2mV difference in higher voltages which is because of my 2.5V reference voltage and Arduino ADC 10bit resolution (2.5 / 1024 = 0.002).

---
Tags: analogread, adc
---


# Question
Title: How to make a custom character on a TFT LCD display? (128x128)
I'm currently using the ucglib library. I'm new to arduino and I'm wanting to simply display a lcd smiley I made with the byte generator. I still have some of the original 'font hello world' stuff down the bottom but I'm curious how to make my character work.

I want to make different smileys in different colours but I'm unsure how to go about this as every guide is on a 16x2 lcd and not a tft one. I have an arduino nano that is just hooked up to that lcd display. I'm going to make pressing buttons change the smiley after I've figured out how to actually put a smiley into it. Hope someone can help.

```
 * LED =   3.3V
 * SCK =   13
 * SDA =   11
 * A0 =    8
 * RESET = 9
 * CS =    10
 * GND =   GND
 * VCC =   5V

    #include "Ucglib.h"  // Include Ucglib library to drive the display

// Create display and define the pins:
Ucglib_ST7735_18x128x160_HWSPI ucg(8, 10, 9);

int smiley = byte customChar[] = {
  B00000,
  B01010,
  B01010,
  B00000,
  B10001,
  B10001,
  B11111,
  B00000
};

void setup(void)  // Start of setup
{

  //ucg.begin(UCG_FONT_MODE_TRANSPARENT);  // It doesn't overwrite background, so it's a mess for text that changes
  ucg.begin(UCG_FONT_MODE_SOLID);  // It writes a background for the text. This is the recommended option

  ucg.clearScreen();  // Clear the screen

  ucg.setRotate180();  // Put 90, 180 or 270, or comment to leave default

  ucg.setColor(0, 255, 255, 255);  // Set color (0,R,G,B)
  ucg.setColor(1, 0, 0, 0);  // Set color of text background (1,R,G,B)
  ucg.setPrintPos(0,24);  // Set position (x,y)
  ucg.print("Welcome");  // Print text or value

  // Draw smiley:
  ucg.setColor(0, 255, 255);  // Set color (0,R,G,B)
  ucg.drawFrame(0, 58, 60, 30);  // Start from top-left pixel (x,y,wigth,height)

void loop(void)  // Start of loop
{

  Variable1++;  // Increase variable by 1
  if(Variable1 > 150)  // If Variable1 is greater than 150
  {
    Variable1 = 0;  // Set Variable1 to 0
  }

  // Convert Variable1 into a string, so we can change the text alignment to the right:
  // It can be also used to add or remove decimal numbers.
  char string[10];  // Create a character array of 10 characters
  // Convert float to a string:
  dtostrf(Variable1, 3, 0, string);  // (<variable>,<amount of digits we are going to use>,<amount of decimal digits>,<string name>)

  // We are going to print on the display everything that is dynamic on the loop, to refresh continuously:

  // Write to the display the Variable1 with left text alignment:
  ucg.setFont(ucg_font_inb16_mr);  // Set font
  ucg.setColor(0, 255, 255, 0);  // Set color (0,R,G,B)
  ucg.setColor(1, 0, 0, 0);  // Set color of text background (1,R,G,B)
  ucg.setPrintPos(9,81);  // Set position (x,y)
  ucg.print(Variable1);  // Print text or value

  // There is a problem when we go, for example, from 100 to 99 because it doesn't automatically write a background on
  // the last digit we are not longer refreshing. We need to check how many digits are and fill the space remaining.
  if(Variable1 < 10)  // If Variable1 is less than 10...
  {
    // Fill the other digit with background color:
    ucg.print(" ");
  }
  if(Variable1 < 100)  // If Variable1 is less than 100...
  {
    // Fill the other digit with background color:
    ucg.print(" ");
  }

  // Write to the display the string with right text alignment:
  ucg.setFont(ucg_font_inb16_mr);  // Set font
  ucg.setColor(0, 0, 255, 0);  // Set color (0,R,G,B)
  ucg.setColor(1, 0, 0, 0);  // Set color of text background (1,R,G,B)
  ucg.setPrintPos(76,81);  // Set position (x,y)
  ucg.print(string);  // Print text or value

}  // End of loop

```

# Answer
> 1 votes
Simple: you don't.

You only need to create a "custom character" on character-only displays (where you are actively programming a new character into the display's internal character set).

With a graphical display there is no "character" - only graphics. The graphics library has fonts, which it then uses to convert text into graphics.

To display something that isn't in your currently selected font, just draw it. That could be from a bitmap graphic (there will be examples in your chosen graphics library) or using primitives, like circles and lines.

---
Tags: arduino-nano, display, tft
---


# Question
Title: Menus not changing when button is pressed TFT 128 x 128
I've just followed a tutorial so that when a button is pressed it goes through a menu. Click once, next slide. Only issue is it isn't appearing on my screen at all. It has uploaded but I'm a total novice when it comes to breadboards etc. Here is my code:

```
    #include "Ucglib.h" // library for this display
#include <TFT.h> // Hardware-specific library
#include <SPI.h>

#define CS   10
#define DC   8
#define RESET  9

#define up 5
#define down 6

TFT TFTscreen = TFT(CS, DC, RESET);
const int menuSize = 4;
String menuItems(menuSize);

bool upLastState = HIGH;
bool downLastState = HIGH;

int currentMenu = 0;
String temp;
char currentPrintOut(10);

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

  pinMode(up, INPUT_PULLUP);
  pinMode(down, INPUT_PULLUP);

  menuItems[0] = ":)";
  menuItems[1] = ":(";
  menuItems[2] = "X(";
  menuItems[3] = ":S";
  menuItems[4] = ":T";

  //initialize the library
  TFTscreen.begin();

  MenuChanged();
}

void loop() {
  if (digitalRead(up) != upLastState) {
    upLastState = !upLastState;
  }

  if (!upLastState) {
    if (currentMenu > 0) {
      currentMenu--;
    } else {
      currentMenu = menuSize - 1;
    }
    MenuChanged();
  } else {
  }

 if (digitalRead(down) !=downLastState) {
  downLastState = !downLastState;

  if (!downLastState) {
    if (currentMenu < menuSize - 1) {
      currentMenu++;
    } else {
      currentMenu = 0;
    }
    //Serial.printIn(menuItems[currentMenu]);
    MenuChanged();
  } else {
    //Release
  }
 }

   delay(50);
 }

 void MenuChanged() {
  Serial.println(menuItems[currentMenu]);

// clear the screen with a black background
  TFTscreen.background(0,0,0);
  TFTscreen.setTextSize(9);
  TFTscreen.stroke(255,255,255);

  temp = String(menuItems[currentMenu]);
  temp.toCharArray(currentPrintOut, 10);

  TFTscreen.text(currentPrintOut, 40, 32);
}

```

Edited back to original as per request

# Answer
> 0 votes
You can make things much simpler:

```
int count = 0;
int button = 5;
int buttonStatus;
unsigned long timer = 0;

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

void loop() {
  buttonStatus = digitalRead(button); // read the button status
  if (buttonStatus == LOW) {
    if (millis() - timer > 200) { //de-bouncing the button
      count++; // increase +1 each time button is pressed
      // clear screen function should be here
      timer = millis();
    }
  }
  if (count > 3){ // if count is bigger than 3 start over.
    count = 0;
    // clear screen function should be here
  }
  switch (count){
    case 1: // if count == 1
    // show charecter :)
    break; // break out of this case!
    case 2:
    // show charecter :(
    break;
    case 3:
    // show charecter :D
    break;
    default: // if none of above cases is valid
    count = 0;
    // clear screen function should be here
  }
  Serial.println(count);
  delay(100);
}

```

simulate this circuit – Schematic created using CircuitLab

So each time button is pressed `count` value will increase by 1. you can also add another button to decrease this value...

You might also notice when pushing the button it'll count more than once, you'll also need to De-Bounce the button. tutorial.

**Edit:** added de-bounce function.

---
Tags: arduino-nano, button, resistor, tft
---


# Question
Title: counting revolution of incremental encoder
I'm doing a project which requires me to use an faulhaber encoder,and the one i have is a 2channel 16lines per revolution. I haven't worked with encoders before and based on what i found the lines per revolution mean how many pulses i get for each revolution and so in my code i used an interrupt and counted the times my channel A changed till it got to 32 counting once for every high to low and once for every low to high for my 16 pulses which then by my belief means that I've had one revolution but when i test the code after around like 1/6 of a spin my counter reaches 32 and I'd appreciate if someone can tell me where I'm going wrong with this .

This is the datasheet of the encoder I'm using IE2\_16 .

**here is the code :**

```
volatile long int ticks = 0 ;
unsigned long int rev = 0 ;
const int channelA = 2 ;
void setup(){
   Serial.begin(9600);
   pinMode(6,OUTPUT);
   pinMode(7,OUTPUT);
   pinMode(8,OUTPUT);
   pinMode(channelA,INPUT);
   attachInterrupt(digitalPinToInterrupt(channelA), numCunts,  CHANGE);
   digitalWrite(7,LOW);
   digitalWrite(8,HIGH);
   analogWrite(6,15);
}
void loop(){
       Serial.println(rev);

    if(ticks>=32){
       ticks = 0;
       rev++;

      }
}

void numCunts(){
  ticks+=1 ;
  }

```

# Answer
No, there are several problems with your decoding. First, you are detecting every change. You want to detect only rising or falling edge changes.

Second, the changes are likely noisy, so you need to write your decoder to "debounce" the readings. With a 2-channel encoder like you're using, the usual way to do that is to only respond to rising edge changes on channel A after you've seen a rising edge change on channel B, and visa-versa.

See this link for a description of how they work: http://www.creative-robotics.com/quadrature-intro

I tried my hand at writing my own decoder, but it's harder than you might think to get it right. I'd suggest using somebody else's rotary encoder library.

And a quick google search revealed this library on github: https://github.com/PaulStoffregen/Encoder

(I don't know if it's any good or not. It's the first hit I found.)
> 0 votes

---
Tags: arduino-uno, rotary-encoder
---


# Question
Title: How to burn arduino bootloader on SAMD21 chips using J-Link mini
I am planning on making my own custom PCB of a SAMD21 board. I would like to ask if anyone has experience uploading arduino bootloader on a J-link Mini although adafruit has a guide on this device, its not uploading a arduino bootloader.

On a related note which pins should I connect it to my SAMD21 chip ?

# Answer
> 1 votes
The Atmel EDBG would work for Arduino Zero since that has the EDBG chip. With Jlink, you can use Atmel Studio. Once the Jlink is connected to the chip via the 10 pin SWD header, goto the programmer option in Atmel Studio, select the chip and programmer and burn your firmware with the selected programmer. You can follow a tutorial here which walks through it.

---
Tags: samd21g
---