# Question
Title: How to use the M117 temperature sensor from mysentech?
Anyone can help me decode the temperature of the M117 chip from mysentech.com?

I tried things, but I get a constant raw value of 0xFFFF, which becomes 1 once 2's complemented is applied.

The chip shows up at the expected address (TEMP\_SENSOR\_ADDRESS is 0x45) during a scan operation of the I2C bus.

```

    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
    // Select data register
    Wire.write(0x00);
    // Stop I2C Transmission
    Wire.endTransmission();
    delay(300);

    // == Request for the raw temp 2 bytes
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 2);
    const size_t count = Wire.available();
    log("%d bytes available", count);

    if (count!=2) {
        *ready = false;
        warn("I2c temp is not available");
    }
    else {
        *ready = true;
        // Get the raw data as the 16-bit big endian (MSB-LSB)
        byte data0 = Wire.read();
        byte data1 = Wire.read();
        const uint16_t raw = data0<<8 | data1;
        const int sign = raw>>15 == 1 ? -1 : 1;

        // Get the raw temperature as a 2's complement of the 16-bit (MSB-LSB) value
        const int16_t c2Raw = ~raw + 1;

        // Apply scale and offset
        temperature = sign * float(c2Raw)/256.0 + 40;
        log("raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C",
            raw, raw,
            c2Raw, c2Raw,
            temperature
        );
    }

```

**\[UPDATE | SEPT. 2nd 2022\]** Following the discussion I had with @jsoleta, my current code is as follows. But still getting FFFF AC. AC being the correct CRC for FFFF. Coud it be the result of a wiring issue of the component on our custom PCB?

The logs:

```
b5725|—|  Thermometer: Command: Writing to register command 0xCC44
b5725|—|  Thermometer: Command byte 0: cc
b5725|—|  Thermometer: Command byte 1: 44
b5725|—|  Thermometer: Command: register transmitted 2 bytes
b5725|—|  Thermometer: 3 bytes available
b5725|—|  Thermometer: Actually read 3 bytes: ff ff ac
b5725|—|  Thermometer:  CRC matched: computed: ac == read: ac
b5725|—|  Thermometer: raw: ffff (65535) | Raw 2's complement  0001 (1) | temperature: 39.996094°C
b5725|—|  Thermometer: raw: ffff (65535) | temperature: 39.996094°C
b5725|—|  Thermometer: Transmitting board temperature 40.0°C over the RS-485 bus (raw is 799 - 0x031f)

```

The updated code:

```
loat I2cThermometer :: readTemperature(bool *ready) {
    float temperature = 0;

    log("Command: Writing to register command 0xCC44");
    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);

    // Select data register 0x00, config 0x01

    const uint16_t command =
        0xcc44  // Wait for temperature measurement
        //0xf32d    // Read status
        //0x611d    // Measurement result set alarm
    ;
    byte * data = (byte*)&command;
    Wire.write(data[1]); log("Command byte 0: %02x", data[1]);
    Wire.write(data[0]); log("Command byte 1: %02x", data[0]);

    // Stop I2C Transmission
    const auto readCount = Wire.endTransmission();
    log("Command: register transmitted %d bytes", readCount);
    delay(15);
    // == Request for the raw temp 2 bytes + CRC
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 3);   // 2-byte data + 1-byte CRC
    const size_t count = Wire.available();
    log("%d bytes available", count);

    if (count!=3) {
        *ready = false;
        warn("No temp data is not available");
    }
    else {
        *ready = true;

            // Get the raw data as the 16-bit big endian (MSB-LSB)
            byte data[3];
            const size_t r = Wire.readBytes(data, sizeof data);
            log("Actually read %d bytes: %02x %02x %02x", r, data[0], data[1], data[2]);
            const byte crc = MY_CRC8(data, 2);
            if (crc != data[2]) {
                warn("CRC mismatch: computed: %02x != read: %02x", crc, data[2]);
            }
            else {
                success("CRC matched: computed: %02x == read: %02x", crc, data[2]);
            }
            const uint16_t raw = *(uint16_t*)data;

            const int sign = raw>>15 == 1 ? -1 : 1;

            // Get the raw temperature as a 2's complement of the 16-bit big engdian (MSB-LSB)
            const int16_t c2Raw = ~raw + 1;

            // Apply scale and offset
            temperature = sign * float(c2Raw)/256.0 + 40;
            #if LOG_LEVEL >= LOG_LEVEL_DEBUG
            log("raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C",
                raw, raw,
                c2Raw, c2Raw,
                temperature
            );
            #endif

        #if LOG_LEVEL >= LOG_LEVEL_DEBUG
        log("raw: %04x (%d) | temperature: %f°C",
            raw, raw,
            temperature
        );
        #endif

        writeBoardTemperatureMessage(temperature);
    }

    if (!(*ready)) {
        #if LOG_LEVEL >= LOG_LEVEL_INFO
        log("Temperature is not ready %d°C", temperature);
        #endif
        return temperature;
    }

    #if LOG_LEVEL >= LOG_LEVEL_INFO
    log("Temperature is %d°C", temperature);
    #endif

    return temperature;
}

```

# Answer
> -1 votes
Ok, I found something weird. My code do work if I request the sensor every 4 seconds at max. But if the frequency is below that, it won't work.

Will replace the sensor, rolling back to TMP112, as before.

# Answer
> 1 votes
> WARNING: I have no way to test/verify the parts of this that directly apply to your chip.

## Issue conversion command

This device does not appear to follow the common write-register-address followed by read-register-value scheme. **Instead, it seems in order for the device to sample and convert temperature at all you must first issue a command to perform the conversion. You're not doing that, so that seems to be the principal problem.** You're reading whatever the value is prior to every having asked for a conversion an the datasheet says indicates this is indeterminate. So 0xFFFF is plausible and unremarkable for a value you'd get not having already requested conversion.

Issuing the conversion command (again, I'm not able to test this):

```
void request_temperature_conversion() {
  Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
  Wire.write(0xCC);
  Wire.write(0x44);
  const auto check_me = Wire.endTransmission();
  delay(15); // Ensure a completed conversion.
}

```

## Read result

To read the result of value of the most recent conversion:

```
uint16_t read_u16_temperature() {
  const auto read_count = Wire.requestFrom(
    TEMP_SENSOR_ADDRESS,
    3 // the actual transaction includes an 8-bit as well as 16-bit sample
  );
  uint8_t temp_payload[2];  // 2 because i'm going to ignore the CRC.
  Wire.read(temp_payload, sizeof temp_payload);

  return uint16_t(temp_payload[0]) << 8 | temp_payload[1];
}

int16_t read_s16_temperature() {
  int16_t r;
  const uint16_t u = read_u16_temperature();
  memcpy(&r, &u, sizeof r);
  return r;
}

```

## Together

Again, I can't really test this.

```
request_temperature_conversion();
temperature =
  sign
  * float(read_s16_temperature()) / 256
  + 40;

```

You probably can and should avoid the use of the floating point type. If you're logging this data and transmitting this data to somewhere else to be logged, you may be better off transmitting/storing the raw values which can be (re)interpreted later rather than having different versions of your sketch potentially affecting how a calculation is done on the values.

## Manufacturer's documentation

The website you have linked to has a datasheet in Chinese. You may get some use out of you machine translate it to English (or whatever). Google Drive is capable of this. Probably more useful are the archives of sample code intended for STM32. That's where all the information came from, including crucially the use of `0xCC44` command to prompt conversion. The 15ms delay is also lifted from what I read in the STM32 sample code in the rar archive from the site; I didn't put much thought into its significance or how the part behaves if you don't wait long enough. You should read through it, because there's more about configuring the chip, the CRC, etc.

---
Tags: esp32, temperature-sensor, temperature
---


# Question
Title: Why does Serial.print(1) cost 228 bytes more program memory compared to Serial.print((char)(48+1))?
Just discovered this. When I cast an int to a char inside a Serial.print statement it costs way less program memory. I'm not sure why. Could someone explain this to me? In the following example the difference is 228 bytes!

```
Serial.print(1); // 1676 bytes program storage space. 184 bytes of dynamic memory.

```

```
Serial.print((char) (48 + 1)); // 1448 bytes program storage space. 184 bytes of dynamic memory.

```

EDIT: Adding from different comments:

```
Serial.print('1'); // Sketch uses 1448 bytes program memory, 184 bytes dynamic memory

```

```
Serial.write(48 + 1); // Sketch uses 1448 bytes program memory, 184 bytes dynamic memory

```

EDIT: For an int \> 9, adding quotes in following example saves 218 bytes program memory but adds 4 bytes to dynamic memory usage.

```
Serial.print(123); // 1676/184 bytes
Serial.print("123"); // 1458/188 bytes
Serial.print(String(123)); // 2772/194 bytes

```

EDIT2: Max digits in Arduino-uno int is 5(?). You save 80 bytes by converting it to a char array, in comparison to just printing the integer:

```
Serial.print(12345); // 1676/184 bytes

```

```
char digits[5];
int number = 12345;
for (int i = 4; i >= 0; i--) {
  digits[i] = (number %10) + 48;
  number /= 10;
}
Serial.print(digits); // 1596/184 bytes

```

To test for yourself, uncommenting one or the other:

```
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print(1); // uses 1676/184 bytes
  //. Serial.print((char) (48 + 1)); // uses 1448/184 bytes
  //  Serial.print('1'); // uses 1448/184 bytes
  //  Serial.write(48 + 1); // 1448/184 bytes
  //  Serial.print(123); // 1676/184 bytes
  //  Serial.print("123"); // 1458/188 bytes
  //  Serial.print(String(123)); // 2772/194 bytes
  //  Serial.print(12345); // 1676/184 bytes | 1676/184
  //  Serial.print("12345"); // 1458/188 bytes | 1460/190
  //  char buff[5];
  //  itoa(12345, buff, 10);
  //  Serial.print(buff); // 1604/184 bytes
  char digits[5];
  int number = 12345;
  for (int i = 4; i >= 0; i--) {
    digits[i] = (number %10) + 48;
    number /= 10;
  }
  Serial.print(digits); // 1596/184 bytes
}
void loop() {
  // put your main code here, to run repeatedly:

}

```

EDIT: Second question: Shouldn't this be optimised somehow? Or should I always take care of this myself? And why/how? ;)

**the chars 0-9 have a decimal value of 48-57 in the Ascii table, hence (char)(48 + 0-9) prints 0-9*

# Answer
The difference is simply this:

* Print this character

and

* Interpret this integer as a sequence of digits, work out the ASCII characters that represent each digit in turn, and print them.

As you can see even just writing out what the second one does takes more words. Printing an integer is a lot more work than just printing one character. Think about what it takes to print the value 2034578 and how you would do that given that you can only output individual numbers 0-9 and the data isn't stored as the numbers 0-9 but a series of just 0 and 1...

It takes work. Lots of work.
> 3 votes

---
Tags: arduino-uno, arduino-nano, memory-usage
---


# Question
Title: ESP_ATMod and its many library dependencies
I'm trying to install https://github.com/JiriBilek/ESP\_ATMod onto an ESP8266. The sketch has Includes to many libraries. Those libraries have includes to other libraries and so on. Do I have to manually follow all these dependencies and download them to compile and upload my sketch? Or is there an easier way.

# Answer
An Arduino sketch is a folder not a file. The ESP\_ATMod sketch has 11 files:

```
asnDecode.cpp
asnDecode.h
command.cpp
command.h
debug.h
ESP_ATMod.h
ESP_ATMod.ino
settings.cpp
settings.h
WifiEvents.cpp
WifiEvents.h

```

The sketch doesn't include libraries which would require installation. It uses only libraries bundled with the esp8266 platform: EEPROM, ESP8266mDNS, ESP8266WiFi and LittleFS. You don't have to install any libraries.

You can download all the files at once with "Download ZIP":
> 0 votes

---
Tags: esp8266
---


title: Send file post request from the ESP32

text:
# Question
Title: Send file post request from the ESP32
Is it impossible to send a file post request from the ESP32 using the SPIFFS file system? ESP32 freezes while sending.

Code example:

```
File file = SPIFFS.open("/Images/test.bmp", FILE_READ);

String start_request = ""; String end_request = "";
start_request = start_request +
                "\n--AaB03x\n" +
                "Content-Disposition: form-data; name=\"userfile\"; filename=\"CAM.bmp\"\n" +
                "Content-Transfer-Encoding: binary\n\n";
end_request = end_request + "\n--AaB03x--\n";
uint16_t full_length;
full_length = start_request.length() + file.size() + end_request.length();

WiFiClient client;
if (!client.connect("server_name", 80)) {
  Serial.println("Connected FILED!");
  return;
}

Serial.println("Connected ok!");
client.println("POST /Home/Index HTTP/1.1");
client.println("Host: example.com");
client.println("User-Agent: ESP32");
client.println("Content-Type: multipart/form-data; boundary=AaB03x");
client.print("Content-Length: "); client.println(full_length);
client.print(start_request);

while (file.available()){
  client.write(file.read());
}

Serial.println(">>><<<");
client.println(end_request);

```

# Answer
> -1 votes
One can send a POST request with data fields appended with binary data as shown in the code below. The presented code was made to make a POST request to a Dataverse repository, however, can be easily adapted to any other POST request. Finally, the code below is optimized for Tensilica's Xtensa LX6/7 microprocessors, vis-a-vis ESP32.

The full code can be found here:

https://github.com/aeonSolutions/openScienceResearch-Smart-DAQ-Device-able-to-Upload-Live-Experimental-Sensor-Data-to-a-Data-Repo

```
// *********************************************************
//            Upload Dataset to Harvard's Dataverse
// *********************************************************
void UploadToDataverse() {
  //Check WiFi connection status
  if(WiFi.status() != WL_CONNECTED){
    mserial.printStrln("WiFi Disconnected");
    if (connect2WIFInetowrk()){
      UploadToDataverse();
    }
  }
  // Start sending dataset file
  File datasetFile = FFat.open("/"+EXPERIMENTAL_DATA_FILENAME, FILE_READ);
  if (!datasetFile){
    mserial.printStrln("Dataset file not found");
    return;
  }

  String boundary = "7MA4YWxkTrZu0gW";
  String contentType = "text/csv";
  // DATASET_REPOSITORY_URL = "/api/files/:persistentId/replace?persistentId=" +PERSISTENT_ID;
  DATASET_REPOSITORY_URL =  "/api/datasets/:persistentId/add?persistentId="+PERSISTENT_ID;

  String datasetFileName = datasetFile.name();
  String datasetFileSize = String(datasetFile.size());
  mserial.printStrln("Dataset File Details:");
  mserial.printStrln("Filename:" + datasetFileName);
  mserial.printStrln("size (bytes): "+ datasetFileSize);
  mserial.printStrln("");

  WiFiClientSecure client;

  int str_len = SERVER_URL.length() + 1; // Length (with one extra character for the null terminator)
  char SERVER_URL_char [str_len];    // Prepare the character array (the buffer)
  SERVER_URL.toCharArray(SERVER_URL_char, str_len);    // Copy it over

  client.stop();
  client.setCACert(HARVARD_ROOT_CA_RSA_SHA1);
  if (!client.connect(SERVER_URL_char, SERVER_PORT)) {
      mserial.printStrln("Cloud server URL connection FAILED!");
      mserial.printStrln(SERVER_URL_char);
      int server_status = client.connected();
      mserial.printStrln("Server status code: " + String(server_status));
      return;
  }
  mserial.printStrln("Connected to the dataverse of Harvard University");
  mserial.printStrln("");
  // We now create a URI for the request
  mserial.printStr("Requesting URL: ");
    mserial.printStrln(DATASET_REPOSITORY_URL);

  // Make a HTTP request and add HTTP headers
  // post header
  String postHeader = "POST " + DATASET_REPOSITORY_URL + " HTTP/1.1\r\n";
  postHeader += "Host: " + SERVER_URL + ":" + String(SERVER_PORT) + "\r\n";
  postHeader += "X-Dataverse-key: " + API_TOKEN + "\r\n";
  postHeader += "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n";
  postHeader += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
  postHeader += "Accept-Encoding: gzip,deflate\r\n";
  postHeader += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
  postHeader += "User-Agent: AeonLabs LDAD Smart DAQ device\r\n";
  postHeader += "Keep-Alive: 300\r\n";
  postHeader += "Connection: keep-alive\r\n";
  postHeader += "Accept-Language: en-us\r\n";

  // jsonData header
  String jsonData = "{\"description\":\"LIVE Experimental data upload from LDAD Smart 12bit DAQ \",\"categories\":[\"Data\"], \"restrict\":\"false\", \"tabIngest\":\"false\"}";
  String jsonDataHeader = "--" + boundary + "\r\n";
  jsonDataHeader += "Content-Disposition: form-data; name=\"jsonData\"\r\n\r\n";
  jsonDataHeader += jsonData+"\r\n";

  // dataset header
  String datasetHead = "--" + boundary + "\r\n";
  datasetHead += "Content-Disposition: form-data; name=\"file\"; filename=\"" + datasetFileName + "\"\r\n";
  datasetHead += "Content-Type: " + contentType + "\r\n\r\n";

  // request tail
  String tail = "\r\n--" + boundary + "--\r\n\r\n";

  // content length
  int contentLength = jsonDataHeader.length() + datasetHead.length() + datasetFile.size() + tail.length();
  postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";

  // send post header
  int postHeader_len=postHeader.length() + 1;
  char charBuf0[postHeader_len];
  postHeader.toCharArray(charBuf0, postHeader_len);
  client.print(charBuf0);
  mserial.printStr(charBuf0);

  // send key header
  char charBufKey[jsonDataHeader.length() + 1];
  jsonDataHeader.toCharArray(charBufKey, jsonDataHeader.length() + 1);
  client.print(charBufKey);
  mserial.printStr(charBufKey);

  // send request buffer
  char charBuf1[datasetHead.length() + 1];
  datasetHead.toCharArray(charBuf1, datasetHead.length() + 1);
  client.print(charBuf1);
  mserial.printStr(charBuf1);

  // create buffer
  const int bufSize = 2048;
  byte clientBuf[bufSize];
  int clientCount = 0;

  while (datasetFile.available()) {
    clientBuf[clientCount] = datasetFile.read();
    clientCount++;
    if (clientCount > (bufSize - 1)) {
        client.write((const uint8_t *)clientBuf, bufSize);
        clientCount = 0;
    }
  }

  datasetFile.close();

  if (clientCount > 0) {
      client.write((const uint8_t *)clientBuf, clientCount);
      mserial.printStrln("[binary data]");
  }

  // send tail
  char charBuf3[tail.length() + 1];
    tail.toCharArray(charBuf3, tail.length() + 1);
    client.print(charBuf3);
  mserial.printStr(charBuf3);

  // Read all the lines of the reply from server and print them to mserial
    mserial.printStrln("");
    mserial.printStrln("Response Headers:");
  String responseHeaders = "";

  while (client.connected()) {
    // mserial.printStrln("while client connected");
    responseHeaders = client.readStringUntil('\n');
    mserial.printStrln(responseHeaders);
    if (responseHeaders == "\r") {
      mserial.printStrln("======   end of headers ======");
      break;
    }
  }

  String responseContent = client.readStringUntil('\n');
  mserial.printStrln("Harvard University's Dataverse reply was:");
  mserial.printStrln("==========");
  mserial.printStrln(responseContent);
  mserial.printStrln("==========");
  mserial.printStrln("closing connection");
  client.stop();
  }

```

---
Tags: esp32
---


title: Display issues with 4 Digit, 14 segment

text:
# Question
Title: Display issues with 4 Digit, 14 segment
I have this HT16K33 4 Digit 14-segment display I got brand new. I connected it to my Arduino UNO, wired it up and uploaded some quick test code. However, the display looks completely broken (see image below), only some segments turn on.

I soldered the connection pins to the HT16K33 board (see picture below). My solder isn't the best but it also shouldn't be too bad.

I did a quick resistance check on the connection pins to see if the pins were soldered correctly, and they seemed good. I'm not too sure how to test the ji2c pin though...

Here is the Wiring on my breadboard:

Finally here is the code i'm currently using:

```
#include "HT16K33.h"
#include <Wire.h>
HT16K33 seg(0x070);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Wire.begin();
  if(!seg.begin()){
    Serial.println("ERROR");
    while(1);
  }
  Wire.setClock(100000);

  Serial.println("displayTest()");
  seg.displayOff();
  delay(1000);

  seg.displayOn();
  seg.displayClear();
  seg.displayInt(5);
}

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

}

```

I'm a bit troubled here and confused at what's going on... Help would be greatly appreciated

# Answer
so @6v6gt's comment made me re-search for a library for a 14-segment HT16K33. It seems he/she was in the money since it started working after switching library. While I couldn't find any yesterday, I found this page today which covers 7-segment and 14-segment HT16K33: https://learn.adafruit.com/adafruit-led-backpack/0-54-alphanumeric?view=all#library-reference-3052482

So I switched from the HT16K33 library to the "Adafruit\_LEDBackpack" and "Adafruit\_GFX" Libraries.

Code for those wondering:

```
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();

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

alpha4.begin(0x70);  // pass in the address

alpha4.writeDigitAscii(0, 'A');
alpha4.writeDigitAscii(1, 'B');
alpha4.writeDigitAscii(2, 'C');
alpha4.writeDigitAscii(3, 'D');
alpha4.writeDisplay();
}

void loop() {
}

```

One question I have is (which is an entirely different subject), how do I go from here to rotate the letters and alphabet 180 degrees?
> 3 votes

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


# Question
Title: ESP 32 unable to connect to https website and return the data using GET
I have created a ThingHTTP below:

```
https://api.thingspeak.com/apps/thinghttp/send_request?api_key=BVLJ7A6KNK9VVAYK

```

In my browser I could see the reply. But I am unable to make this work in my ESP32. I understand that this is a https so I would have to declare the root cert details. I have tried to modify based on this tutorial:

```
https://github.com/witnessmenow/arduino-sample-api-request/blob/master/ESP8266/HTTP_GET/HTTP_GET.ino

```

My code as follows:

```
#include <WiFi.h>
#include <WiFiClientSecure.h>

//------- Replace the following! ------
char ssid[] = "SSID";       // your network SSID (name)
char password[] = "pass";  // your network key

// For Non-HTTPS requests
// WiFiClient client;

// For HTTPS requests
WiFiClientSecure client;

// Just the base of the URL you want to connect to
#define TEST_HOST "https://api.thingspeak.com/apps/thinghttp/send_request?api_key=BVLJ7A6KNK9VVAYK"

const char *server_cert = "-----BEGIN CERTIFICATE-----\n"
                                  "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n"
                                  "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n"
                                  "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n"
                                  "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n"
                                  "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n"
                                  "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n"
                                  "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n"
                                  "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n"
                                  "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n"
                                  "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n"
                                  "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n"
                                  "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n"
                                  "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n"
                                  "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n"
                                  "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n"
                                  "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n"
                                  "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n"
                                  "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n"
                                  "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n"
                                  "-----END CERTIFICATE-----\n";

void setup() {

  Serial.begin(115200);

  // Connect to the WiFI
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  //--------

  // Checking the cert is the best way on an ESP32
  // This will verify the server is trusted.
  client.setCACert(server_cert);

  // If you don't want to verify the server
  // Unlike the fingerprint method of the ESP8266 which expires frequently
  // the cert lasts years, so I don't see much reason to ever
  // use this on the ESP32
  // client.setInsecure();

  makeHTTPRequest();
}

void makeHTTPRequest() {
  delay(5000);
  // Opening connection to server (Use 80 as port if HTTP)
  if (!client.connect(TEST_HOST, 443))
  {
    Serial.println(F("Connection failed"));
    return;
  }

  // give the esp a breather
  yield();
  client.connect(TEST_HOST, 443);
  // Send HTTP request
  client.print(F("GET "));
  // This is the second half of a request (everything that comes after the base URL)
  client.print(""); // %2C == ,
  client.println(F(" HTTP/1.1"));

  //Headers
  client.print(F("Host: "));
  client.println(TEST_HOST);

  client.println(F("Cache-Control: no-cache"));

  if (client.println() == 0)
  {
    Serial.println(F("Failed to send request"));
    return;
  }
  //delay(100);
  // Check HTTP status
  char status[32] = {0};
  client.readBytesUntil('\r', status, sizeof(status));
  if (strcmp(status, "HTTP/1.1 200 OK") != 0)
  {
    Serial.print(F("Unexpected response: "));
    Serial.println(status);
    return;
  }

  // Skip HTTP headers
  char endOfHeaders[] = "\r\n\r\n";
  if (!client.find(endOfHeaders))
  {
    Serial.println(F("Invalid response"));
    return;
  }

  // This is probably not needed for most, but I had issues
  // with the Tindie api where sometimes there were random
  // characters coming back before the body of the response.
  // This will cause no hard to leave it in
  // peek() will look at the character, but not take it off the queue
  while (client.available() && client.peek() != '{')
  {
    char c = 0;
    client.readBytes(&c, 1);
    Serial.print(c);
    Serial.println("BAD");
  }

  // While the client is still availble read each
  // byte and print to the serial monitor
  while (client.available()) {
    char c = 0;
    client.readBytes(&c, 1);
    Serial.print(c);
  }
}

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

}

```

the program was able to compile, and was able to run until it shows it connect to the network. But then it returned "Connection failed!" I believe it stuck at this line :

```
if (!client.connect(TEST_HOST, 443))

```

I am not sure what is the problem here. Comments appreciated.

# Answer
> 1 votes
Things wrong with your GET request (which are nothing to do with Arduino - just learn the basics of the protocol you are trying to use *before* you use it):

* You are trying to open a socket to a URL not to a server. That can never work. Connect to the server instead (hint: the server, or "FQDN", is the bit between the `https://` and the next `/`).
* You aren't providing any path in your `GET` request, only a comment that says what you should provide. Hint: the path is everything that comes after (and including) the `/` following the FQDN.
* Your `Host:` header should contain just the FQDN, not the whole URL. By now you should know what the FQDN is.
* You should also include `Connection: close` in your headers to inform the server you won't be keeping the socket open.

Correct those problems and you might begin to see something useful happening.

# Answer
> -1 votes
The piece of code below is from a firmware code I've been programming lately to use on Tensilica's Xtensa LX6/7 compatible MCUs (ESP32). The code below makes an HTTPS request using WIFIClientsecure library.

```
String GetInfoFromDataverse(String url) {
  //Check WiFi connection status

  if(WiFi.status() != WL_CONNECTED){
    mserial.printStrln("WiFi Disconnected");
    if (connect2WIFInetowrk()){
      GetInfoFromDataverse(url);
    }
  }

  int str_len = SERVER_URL.length() + 1; // Length (with one extra character for the null terminator)
  char SERVER_URL_char [str_len];    // Prepare the character array (the buffer)
  SERVER_URL.toCharArray(SERVER_URL_char, str_len);    // Copy it over

  client.stop();
  client.setCACert(HARVARD_ROOT_CA_RSA_SHA1);

  if (!client.connect(SERVER_URL_char, SERVER_PORT)) {
      mserial.printStrln("Cloud server URL connection FAILED!");
      mserial.printStrln(SERVER_URL_char);
      int server_status = client.connected();
      mserial.printStrln("Server status code: " + String(server_status));
      return "";
  }

  mserial.printStrln("Connected to the dataverse of Harvard University");
  mserial.printStrln("");

  // We now create a URI for the request
  mserial.printStr("Requesting URL: ");
  mserial.printStrln(url);

  // Make a HTTP request and add HTTP headers
  // post header
  String postHeader = "GET https://" + SERVER_URL + url + " HTTP/1.1\r\n";
  postHeader += "Host: " + SERVER_URL + ":" + String(SERVER_PORT) + "\r\n";
  //postHeader += "X-Dataverse-key: " + API_TOKEN + "\r\n";
  postHeader += "Content-Type: text/json\r\n";
  postHeader += "Accept: text/html,application/xhtml+xml,application/xml,application/json,text/json;q=0.9,*/*;q=0.8\r\n";
  postHeader += "Accept-Encoding: gzip,deflate\r\n";
  postHeader += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
  postHeader += "User-Agent: AeonLabs LDAD Smart DAQ device\r\n";
  postHeader += "Keep-Alive: 300\r\n";
  postHeader += "Connection: keep-alive\r\n";
  postHeader += "Accept-Language: en-us\r\n";

  // request tail
  String tail = "\r\n--" + boundary + "--\r\n\r\n";

  // content length
  int contentLength = tail.length();
  postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";

  // send post header
  int postHeader_len=postHeader.length() + 1;
  char charBuf0[postHeader_len];
  postHeader.toCharArray(charBuf0, postHeader_len);
  client.print(charBuf0);

  mserial.printStrln("======= Headers =======");
  mserial.printStrln(charBuf0);
  mserial.printStrln("======= End of Headers =======");

  // Read all the lines of the reply from server and print them to mserial
  String responseHeaders = "";

  mserial.printStr("Waiting for server response...");
  long timeout= millis();
  long ttl=millis()-timeout;
  while (client.connected() && abs(ttl) < 30000) { // 30 sec.
    ttl=millis()-timeout;
    responseHeaders = client.readStringUntil('\n');
    if (responseHeaders == "\r") {
      break;
    }
  }
  if (abs(ttl) < 30000){
    mserial.printStrln("OK");
  }else{
    mserial.printStrln("timed out.");
  }

  String responseContent = client.readStringUntil('\n');
  client.stop();

  return responseContent;
  }

```

---
Tags: esp32
---


# Question
Title: Arduino Mega, 6 push buttons for each analog input (A0-A9) - closing one results in reading by other
On day to day basis I'm more of a high level programmer, with little electronics knowledge, apologies in advance if I lack some nomenclature or basics. I communicate with my Arduino Mega via firmata, so won't really bother with code as I believe my issue is 100% hardware issue (if proven wrong I'll share details surely)

I'm creating a 'keyboard' with 60 arcade style push buttons (2pin), and I distinguish them by different resistance when circuit closes with A0-A9 (10 analog pins, 6 buttons each), and I need the rest of the pins for other functionalities.

I've created a circuit similar to this fritzting schema:

So my issue is: when press button A0/button 1, pins A1 & A2 also read the same value. If I press A0/button 2, I get a different value and can determine which button in A0 was pressed, but again - A1 & A2 also read this, even though I didn't press them.

I suspect I might've taken a different approach or even out of the box "keyboard" chips, but this is the route I've taken.

How do I make it so when I press A0/button 1, A1/A2 doesn't read the value? Do I need separate V5? Or I simply need to put the wires differently somehow?

Update: as per **chrisl** comment

I've updated the circuit by adding a resistor for each button group:

And that has solved my issue.

# Answer
> 1 votes
Of course all three analog inputs show the same value. You have literally connected them to each other. Each green wire is connected to a red wire, which leads to the resistor at the bottom. Thus all three inputs are tied together.

You can fix this by using one bottom resistor for each group of 2 buttons, each connected between 5V and the analog input/button system.

And when using analog inputs for multiple buttons the binary resistor latter is an interesting concept, which might give you more buttons per analog input (depending on the noise in your environment). Though the typical way to read so many buttons would be using an additional chip/microcontroller to scan the buttons in a matrix style arrangement. With your current circuit you still need 30 analog inputs.

---
Tags: arduino-mega, analogread, button, resistor
---


# Question
Title: Analog output gives a close range of values
I try to get a good range of values from **VMA309 sound sensor**.

However, when I connect it properly it gives me a range of values +/-5 like below. The documentation says it should give numbers between 0 and 1024.

I turned the potentiometer both sides all the way and that only changed the number, but it keeps gives number in a range of 5 numbers:

An example:

```
626
623
624
624
624
624
623
624
624

```

My code:

```
int sensorPin = A5;
int sensorValue = 0;
void setup ()

{
  Serial.begin (9600)  ;
}

void loop()
{
  sensorValue = analogRead(sensorPin);
  delay (500);
  Serial.println (sensorValue, DEC);
}

```

What am I doing wrong here?

An image of the wires: I also tried the wiring directly without a breadboard. But that gave the same results.

I used the code as given from the VMA 309 documentation.

# Answer
> 1 votes
I have had a smimilar issue extracting the data to ardino module. -with 5V power supply the counts were varying from 1009~1023. -with 3.3V power supply the counts were in the range of 610~640

I connected an scope and found out the MIC module gives an AC outputput of 340mV max sitting over DC signal of 3.3(at 5V supply) and 1.7(at 3.3Vsupply).

On thing was very clear that However the MIC is giving and out put, we need to consider the analoag ref. voltage, for an ADC the input can never be higher than Vref. i.e. 2.56V.So 5V suppy is not going to work. Also if 1.1 Vref is selected the ADC will remain saturaed alaways at 1023 and won't work. Also consider a need to subtruct and offset of 1.7V while working with 3.3V supply.

As a summary, 1- Set Vref of Arduino ADC module to 2.56V 2- Use 3.3V supply for **VMA309 sound sensor** 3- Consider a DC offset of 640 counts approx and the actual voice signal will be sitting on this offset value. May need to decouple in a software code. 4- Set a **VMA309 sound sensor module** threshold at a reasonable point to capture the full spectrum of voice. 5- The delay(ms) in a code shall be removed to get max capture rate or Set an ADC in a free running mode to caputure at max sampling rate(15KSPS for ATmega2560).

# Answer
> 0 votes
Arduino is a lot of fun, but you better stay away from such modules.

The module is a resistor and a electret microphone. There is also a comparator for the digital output. When you have an electret microphone, and add a resistor of 4k7 or 10k, then you have the same.

The signal from the microphone is not amplified and the Arduino only gets the analog value of the audio. The module does not measure how loud the audio is.

I think Velleman makes them: www.velleman.eu/products/view/?id=435532
They are so kind to have a schematic available: vma309\_scheme.pdf

Can you move on and use the Arduino for something else?
This module with this microphone is probably not going to work.
If you want to measure the sound level, then perhaps you can make a circuit yourself or buy a better module.

The "Sound Pressure" is how loud audio is.
The most used standard is called "Sound Pressure Level" or "SPL" and is measured in dB (deciBell).

---
Tags: arduino-uno, analogread, sound
---


# Question
Title: How do I go about pausing/stopping the timer1 task setup in this library, so I can use timer1 for something else in my code
So I want to use this library, that uses timer1 to fetch samples from analog input on pin A0. It works great, and so after proper detection I'd like to perform all kinds of different tasks. But for those I need timer1 again and I think this library keeps it's timer1 routine continuously running. (Am I right?)

(EDIT: clarification) I think therefore a different library using timer1 won't work as expected. That's why after the first library's task is done, I'd like to free up timer1 for the second library.)

```
/*
  Original text created by Jacob Rosenthal:

  The Goertzel algorithm is long standing so see
  http://en.wikipedia.org/wiki/Goertzel_algorithm for a full description.
  It is often used in DTMF tone detection as an alternative to the Fast
  Fourier Transform because it is quick with low overheard because it
  is only searching for a single frequency rather than showing the
  occurrence of all frequencies.

  This work is entirely based on the Kevin Banks code found at
  http://www.embedded.com/design/configurable-systems/4024443/The-Goertzel-Algorithm
  so full credit to him for his generic implementation and breakdown. I've
  simply massaged it into an Arduino library. I recommend reading his article
  for a full description of whats going on behind the scenes.

  Created by Jacob Rosenthal, June 20, 2012.
  Released into the public domain.

  Modifications 6v6gt 09.09.2019
  1. Restructure instance variables to permit multiple instances of class.
  2. Make sample array static to share it between instances
  3. Pass in sample array as pointer so it can be reused outside class.
  4. Drive ADC by timer1 instead of polling ADC in loop()
      and reduce resolution to 8 bits.
  5. Separate coeeficient calculation from constructor because it
       now relies on data unknown at invocation (sample rate)
  5. Some consolidation of methods.
  6. Software "as is". No claims made about its suitability for any use.
       Use at your own risk. Special care required if you use other
       analog inputs or an AVR chip other than ATmega328P (Uno etc.).
*/

#include "Arduino.h"
#include "Goertzel.h"

// set by Goertzel::init()
uint8_t * Goertzel::testData;             // static declaration in .h
uint16_t Goertzel::N ;                    // ditto
uint16_t Goertzel::SAMPLING_FREQUENCY ;   // ditto

volatile bool Goertzel::testDataReady = false ; // static declaration in .h

//ADC interrupt service routine
ISR(ADC_vect) {
  // load sample buffer on sample conversion.
  static uint16_t sampleIndex = 0 ;
  if ( ! Goertzel::testDataReady   ) {
    if ( sampleIndex < Goertzel::N  ) {
      *(Goertzel::testData + sampleIndex++ )  = ADCH ; // 8 bits. Direct adressing into byte buffer
    }
    else  {
      Goertzel::testDataReady = true ;    // make buffer available to consumer
      sampleIndex = 0 ;
    }
  }
  TIFR1 = _BV(ICF1); // reset interrupt flag
}

// constructor
Goertzel::Goertzel(float TARGET_FREQUENCY  )
{
  _TARGET_FREQUENCY = TARGET_FREQUENCY; //should be integer of SAMPLING_RATE/N
}

//static method
void Goertzel::init( uint8_t *sampleArray , uint16_t sampleArraySize, uint16_t sampleFrequency ) {
  // set up sample array, number of samples and sample frequency.

  // load class static variables
  testData = sampleArray ;
  N = sampleArraySize ;
  SAMPLING_FREQUENCY = sampleFrequency ;

  // initialise ADC and Timer1. Timer1 triggers ADC at frequency SAMPLING_FREQUENCY.
  // ISR(ADC_vect) called when conversion complete.
  cli() ;

  // Setup Timer1 for chosen sampling frequency.
  TCCR1A = 0;
  TCCR1B = _BV(CS10)  |    // Bit 2:0 – CS12:0: Clock Select =  no prescaler
           _BV(WGM13) |    // WGM 12 = CTC ICR1 Immediate MAX
           _BV(WGM12);     // WGM 12 ditto
  ICR1 = ( (F_CPU ) / SAMPLING_FREQUENCY ) - 1;

  // Setup ADC for triggering by timer1; 8bit resolution; Analog Port PC0 (pin A0) ADMUX
  ADMUX =  _BV(REFS0) ;    // Fixed AVcc reference voltage for ATMega328P
  ADMUX |= _BV(ADLAR) ;    // left adjust conversion result in ADCH (8bit)
  DIDR0 |= _BV(ADC0D);     // DIDR0  Digital Input Disable Register 0
  ADCSRB = _BV(ADTS2) |    // Bit 2:0  ADTS[2:0]: ADC Auto Trigger Source
           _BV(ADTS1) |    // Timer/Counter1 Capture Event
           _BV(ADTS0);     // ditto

  ADCSRA = _BV(ADEN) |      // Bit 7   ADEN: ADC Enable
           _BV(ADSC) |      // Bit 6   ADSC: ADC Start Conversion
           _BV(ADATE) |     // Bit 5   ADATE: ADC Auto Trigger Enable
           _BV(ADIE) |      //
           _BV(ADPS0) |     // Bits 2:0  ADPS[2:0]: ADC Prescaler Select Bits  (div 8 )
           _BV(ADPS1);      // ditto
  sei() ;

}

// instance method
void Goertzel::getCoefficient( void ) {
  // previously in constructor. Now SAMPLING_FREQUENCY unknown at invocation time.
  float omega = (2.0 * PI * _TARGET_FREQUENCY) / SAMPLING_FREQUENCY;
  coeff = 2.0 * cos(omega);
}

// instance method
float Goertzel::detect()
{
  Q2 = 0;
  Q1 = 0;
  for ( uint16_t index = 0; index < N; index++)
  {
    // byte sample is ( *( testData + index ) );
    float Q0;
    Q0 = coeff * Q1 - Q2 + (float) ( *( testData + index ) - 128 ) ; //  128 for 8bit; 512 for 10bit resolution.
    Q2 = Q1;
    Q1 = Q0;
  }

  /* standard Goertzel processing. */
  float magnitude = sqrt(Q1 * Q1 + Q2 * Q2 - coeff * Q1 * Q2);
  return magnitude  ;
}

```

I'm new to using timers on Arduino, but I want to understand and learn more about it. So I'm reading up on it. Seeing that it's not the easiest subject to wrap my head around I'd like to ask for some directions.

On this splendid page I gathered some examples of stopping / disabling timer1.

```
  TCCR1B = 0;
  TIMSK1 = 0;    // disable Timer1 Interrupt

```

Nick Gammons Timer info page

However I don't completely recognise the usage of the library's timer names, registers, variables yet. And so I'm unsure what part of the code is doing what exactly, ie where, how and when the timer starts. And therefore I'm equally unsure how to go about stopping it when the task is done, and to start it again when a new detection is needed. It seems there is TCCR1A, TCCR1B, cli() and sei() that have something to do with it and ISR(ADC\_vect). One of you probably knows ;)

EDIT: Reading the suggested ATmega328p datasheet I found out a little bit more about the following abbreviations:

```
cli // disable interrupts during timed sequence __disable_interrupt();
sei // Set global Interrupt Enable __enable_interrupt();
TCNT1 // Timer/Counter (setting 0 will reset)
TIFR1 // Timer Interrupt Flag Register
TCCR1A // Timer/Counter Control Register 1a (setting 0 will reset)
TCCR1B // Timer/Counter Control Register 1b (setting 0 will reset)
TIMSK1 // Timer Interrupt Mask Register
ICR1 // Input Capture Register
ICF1 // Input Capture Flag
ICP1 // Input Capture Pin
WGM // Waveform Generation Mode
CS // Clock Select Bits (prescaler??)
F_CPU // The CPU speed (What is the default value? 8000000??? 1000000??? 16000000???)
DIDR1/DIDR0 // Digital Input Disable Registers (if left enabled they will use excessive power when Analog input is floating or close to VCC/2)
ADMUX // ADC Multiplexer Selection Register
REFS1 & REFS0 // Voltage Reference Selection
ADLAR // ADC Left Adjust Result
MUX
ADEN // ADC Enable
ADSC // ADC Start Conversion
ADATE // ADC Auto Trigger Enable
ADTS // ADC Trigger Source Select
ADCSRB //
ADIE // ADC Conversion Complete Interrupt Enable
ADPS0 & ADPS0 // ADC Prescaler Select Bits

```

But hasn't really lightened things up entirely for me. What is \_BV? for example.

EDIT: I think I'm starting to make sense of it more. Am I right here(??):

```
ADMUX = (0b00 << REFS0) | (1 << ADLAR) | (0b00000 << MUX0);
Is the same as:
ADMUX = (0b00 << REFS0); // 0 shift has no effect so can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (0b00000 << MUX0); // 0 shift has no effect so can be omitted
Is de same as:
ADMUX = (1 << REFS0); // can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (1 << MUX0); // can be omitted
is the same as:
ADMUX = _BV(REFS0); // can be omitted
ADMUX |= _BV(ADLAR);
ADMUX |= _BV(MUX0); // can be omitted
Is the same as:
ADMUX = (1 << ADLAR);
Is the same as:
ADMUX = _BV(ADLAR);

```

Understanding it all would be great, but may be unnecessary. If only I'd know how I can stop and free Timer1 usage for other purposes. Starting it all up again would be easier I guess ;)

# Answer
> 0 votes
Time hasn't been on my side lately. But here is the code I've come up with so far. Needs testing still to see if it solves all my problems but in regards to my original question this seems to hold the answer I was looking for. Later on I might add some more info/links to register settings, hex/binary/ascii tables, bitwise operations and what they all do. But the manual is your friend pretty much.

Alright then. First of all this print function comes in handy:

```
// Handy while experimenting with all different bitwise operations and settings
void printRegSettings() {
  const String regNames[8] = {"TCCR1A", "TCCR1B", "ICR1", "ADMUX", "DIDR0", "ADCSRA", "ADCSRB", "TIFR1"}; //other: "TCNT1", "OCR1A", "OCR1B", "TIMSK1"
  uint8_t regVars[8] = {TCCR1A, TCCR1B, ICR1, ADMUX, DIDR0, ADCSRA, ADCSRB, TIFR1}; //other: TCNT1, OCR1A, OCR1B, TIMSK1

    for (uint8_t index = 0; index < sizeof(regVars)/sizeof(regVars[0]); index++) {
      Serial.print(regNames[index]+" = 0b");
      for (uint8_t i = 8; i > 0; i--) {
        Serial.print(bitRead(regVars[index], i-1));
      }
    Serial.write('\n');
    }
}

```

Next put all library register settings in function, notice the boolean in the end, for emptying the ISR (later described):

```
void dtmfTimerSetup () {

  TCCR1A = 0;
  TCCR1B = _BV(CS10) | // Bit 2:0 – CS12:0: Clock Select = no prescaler
           _BV(WGM13) | // WGM 12 = CTC ICR1 Immediate MAX
           _BV(WGM12); // WGM 12 ditto
  ICR1 = ( (F_CPU ) / 9600 ) - 1;

  ADMUX = _BV(REFS0) ; // Fixed AVcc reference voltage for ATMega328P
  ADMUX |= _BV(ADLAR) ; // left adjust conversion result in ADCH (8bit)
  DIDR0 |= _BV(ADC0D); // DIDR0 Digital Input Disable Register 0
  ADCSRB = _BV(ADTS2) | // Bit 2:0 ADTS[2:0]: ADC Auto Trigger Source
           _BV(ADTS1) | // Timer/Counter1 Capture Event
           _BV(ADTS0); // ditto
  ADCSRA = _BV(ADEN) | // Bit 7 ADEN: ADC Enable
           _BV(ADSC) | // Bit 6 ADSC: ADC Start Conversion
           _BV(ADATE) | // Bit 5 ADATE: ADC Auto Trigger Enable
           //_BV(ADIE) | //
           _BV(ADPS0) | // Bits 2:0 ADPS[2:0]: ADC Prescaler Select Bits (div 8 )
           _BV(ADPS1); // ditto

  Goertzel::dtmfListenerISR = true;
}

```

Next add a function to clear all these settings. Initial values of registers is 0 as far as I checked. So setting them zero does the job. Again notice the boolean false this time.

```
void clearTimerSettings() {
  //Empty Goertzel dtmf interrupt ISR routine
  Goertzel::dtmfListenerISR = false;

  //reset all altered registers to initial value 0
  Serial.println(F("***CLEARING ALL BIT SETTINGS***"));
  TCCR1A = TCCR1B = ICR1 = ADMUX = DIDR0 = ADCSRA = ADCSRB = TIFR1 = 0;

// pauze but don't erase current interrupt settings:
// bitClear(ADCSRA, ADIE); //risk interference when different timer adc library sets bit again
}

```

In Goertzel.h Add this static bool declaration to class Goertzel public:

```
static volatile bool Goertzel::dtmfListenerISR;

```

Add boolean declaration to Goertzel.cpp and add 'if statement' inside ISR(ADC\_vect) to only execute interrupt if dtmfListenerISR is true.

```
volatile bool Goertzel::dtmfListenerISR;

//ADC interrupt service routine

ISR(ADC_vect) {
  //if dtmfListenerISR is false, this code is skipped, freeing timer1 for other purposes
  if (Goertzel::dtmfListenerISR) {

    // load sample buffer on sample conversion.
    static uint16_t sampleIndex = 0 ;
    if ( ! Goertzel::testDataReady  ) {
      if ( sampleIndex < Goertzel::N  ) {
        *(Goertzel::testData + sampleIndex++ )  = ADCH ; // 8 bits. Direct adressing into byte buffer
      }
      else  {
        Goertzel::testDataReady = true ;    // make buffer available to consumer
        sampleIndex = 0 ;
      }
    }
    TIFR1 = _BV(ICF1); // reset interrupt flag
  }
}

```

Finally use these functions like this in your sketch. The setup can be done in setup but the clearing should take place in your void loop of course, once the library and timer interrupt have finished their job and you want another library / timer routine to take over. Just for testing I put them all inside a setup and a simple sketch now.

```
void setup() {
  Serial.begin(115200);
  //setup/initialize timer interrupt routine:
  dtmfTimerSetup();
  //FOR TESTING: check and print current settings:
  printRegSettings();
  //clear timer interrupt routine;
  clearTimerSettings();
  printRegSettings(); //only for testing purposes

}

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

```

Ofcourse for the other libraries using timer1 you should do the same: setup functions with register settings / cleanup and declare/set boolean for ISR part. There might be some overkill here, but so far I didn't find a more elegant way of achieving all this.

# Answer
> 2 votes
I'm not sure why you need to stop the timer in the first place. Timers are just things that count "ticks" which can be programmed to arrive at various speeds (usually some division of the processor speed).

Imagine you have a clock in your kitchen. And imagine you are baking a cake. You observe the time that you put the cake into the oven. Then you note at what time the cake will be done. Meanwhile that same clock can be used to time boiling an egg. You don't need to stop or "reset" the clock to achieve this.

Just let the clock run and do its thing, and meanwhile make a note of what time needs to arrive for things to be "done".

Meanwhile, the Uno (and Nano) have other timers. You can use those. It's like owning three clocks, that can run at different speeds — or perhaps more accurately — different levels of precision.

# Answer
> 2 votes
I am answering here only a tiny part of the question:

> ```
> ADMUX = (0b00 << REFS0); // 0 shift has no effect so can be omitted
> ADMUX |= (1 << ADLAR);
> ADMUX |= (0b00000 << MUX0); // 0 shift has no effect so can be omitted
>
> ```
>
> Is de same as:
>
> ```
> ADMUX = (1 << REFS0); // can be omitted
> ADMUX |= (1 << ADLAR);
> ADMUX |= (1 << MUX0); // can be omitted
>
> ```

No, it is not the same.

Starting from the first line: `(0b00 << REFS0)` means “**zero** left-shifted by REFS0 (i.e. six) bits”. It is not a zero shift, as stated in the comment: it is a 6-bit shift. The resulting value is zero, because the number being shifted is zero to start with, and because vacated bits are zero-filled during a left-shift.

In contrast, `(1 << REFS0)` means “**one** left-shifted by REFS0 bits”. The resulting value is:

2REFS0 = 26 = 0b01000000 = 64

In the first code snippet, ADMUX ends up with only the ADLAR bit being set. In the second snippet, all three bits (REFS0, ADLAR and MUX0) are set.

**Edit**: explaining the notion that “vacated bits are zero-filled during a left-shift”. Let's assume x = 0bABCDEFGH is a byte, where A…H are the individual bits (“0b” is a prefix meaning “what follows is in binary”). Left-shifting this byte gives the following:

```
x << 0 = 0bABCDEFGH
x << 1 = 0bBCDEFGH0
x << 2 = 0bCDEFGH00
x << 3 = 0bDEFGH000
...

```

By “vacated bits are zero-filled” I mean that the bits that are beyond the last original bit (beyond H) are replaced by zeros. Note that a zero shift “has no effect” in the sense that `x<<0` is the same as `x`. Note also that shifting the value zero by any amount always yields zero.

In this particular code, the value being written to ADMUX can be computed as follows:

```
1 << REFS0 = 1 << 6 = 0b00000001 << 6 = 0b01000000
1 << ADLAR = 1 << 5 = 0b00000001 << 5 = 0b00100000
1 << MUX0  = 1 << 0 = 0b00000001 << 0 = 0b00000001
──────────────────────────────────────────────────
(1<<REFS0) | (1<<ADLAR) | (1<<MUX0)   = 0b01100001

```

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


# Question
Title: Lag in sensor reading when Arduino Powered with 12V adaptor
So I am trying to power an arduino to measure water flow. It works all fine and dandy when I am powering it with laptop, but when I directly power it with 12V 1.5A adaptor the readings take a second to come to the LCD even though the pump starts running. Also when they come, I can see that sometimes it hangs. Why is that?

Before taking the readings I am switching on a motor which is also directly powered by the adaptor just like the arduino.

Below is a block diagram.

Would adding a voltage regulator that steps down 12V to 9v between arduino and adaptor help?

# Answer
> 2 votes
Your power supply is actually advertised at 1.2 Amps. It's assumed you are powering the Arduino, the Relay, the Water Valve Solenoid and the Water-Pump-Motor all w/the same 1.2A power supply. It is within reason that the sum of all those loads exceeds your power supply's capabilities.

> It works all fine and dandy when I am powering it with laptop ...

It is assumed you were only powering the Arduino with the laptop. Providing the Arudino with an independent power source is a common solution to this type of problem. Obtaining a larger power supply (more Amps) is another possible solution.

Why does it eventually work?

Motors require more Amps when under a physical load. If the water is stationary, the motor will have to "get it moving" requiring more current. The term "locked motor current" is used here in this article.

Also, inductor loads require more Amps when ever the voltage potential is suddenly changed. The motor and relay are likely both seen as inductive loads. This is referred to as inrush current.

Both of these can be assumed transitory. Once the motor is moving and after the potential across the inductive loads are closer to zero, the initial current demand will subside and the power supply may then be capable of sustaining the constant voltage needed by the Arduino's processor.

Alternate solution:

Obtaining a larger power supply is likely the better solution. Another option involves filtering the power only for the Arduino. This option is discussed in this thread on forum.arduino.cc where a diode and capacitor are used to somewhat isolate the power for the motor, relay and solenoid from the Arduino.

# Answer
> 0 votes
Welcome. Your pump is turning on as soon as the power is turned on because the relay is connected to 5V. Your processor needs to initialize itself and then the display, the pump is up and running. On your laptop the pump was powered from the power supply and the Arduino by the laptop. The arduino was on and up and running when the pump was started. Hope this helps. I will take a SWAG and say this is powered up when the pump is needed and powered down when it is not needed.

---
Tags: arduino-nano, sensors, power
---


# Question
Title: ESP8266, prints ready at start but no response to AT command
I have been using **ESP8266** wifi module with **Arduino as FTDI**. The power for ESP8266 comes from **LM317** 5V - 3.3v regulated supply(I am sure 5V is powerful enough to give upto 1A of current).

The RX of ESP8266 is connected to RX of Arduino via a **voltage divider** to ensure 3.3V logic level. But still, I am not getting any response to **`AT`** command, though my laptop and phone wifi have successfully connected to *AI-Thinker...* SSID(which is an open hotspot from ESP8266).

I am also having some **garbage values** on the serial port immediately after I turn on the power supply to ESP8266. I have tested all baud rates available in Arduino IDE v1.0.5 with no results.

The resistor values for lm317 are R1 = 125 Ohm, R2 = 225 Ohm with which I am getting around 3.2 Volts.

The connections are as follows:-

---

-----Arduino UNO-----

RESET ------------ GND

---

Arduino UNO ----- ESP8266

TX ------------------- TX

RX ---5V to 3.3v--- RX

GND ----------------- GND

---

ESP8266 --------- LM317(5V to 3.3V)

VCC --------------- 3.3V

GND --------------- GND

CH\_PD ------------ 3.3V

---

---

**EDIT - 1**: I have bought a **new *ESP8266***, and even it doesn't responds to any `AT` commands, thought there is some difference in the previous ESP8266 output and this new ESP8266 output.

The difference is a sort of **good** news to me, it **sends `ready`** after sending some garbage at `115200` baud on boot which never happened with previous one(ESP8266).

Is anyone having some clue why there is no response to `AT` commands? May it be a issue with **TX** line?

---

**EDIT - 2**: I have also used **another Arduino** with same connections doubting the **TX** pin on Arduino, but with same luck, bad luck. Still, nothing got changed.

---

**EDIT - 3**: I am shifting 5v to 3.3v by using three 100 ohm resistors.

# Answer
The problem was with my **logic level shifting**.

Any Arduino pin can provide only upto *40mA* of current. What current you are trying to draw is:-

> 5 Volts / 100 Ohm = *50mA*

which is clearly more current than what an UNO can provide. Your ESP also adds up its own resistance meaning even more current draw requirement from RX pin.

Instead of using three 100 ohm resistors, use some **high valued resistors** such as 1K ohm resistors(or even higher value) in the **voltage divider circuit** so that no much current pass through it, consuming less power **affordable** by the Arduino RX pin.

Remark: If you don't know how logic level shifting works with voltage divider circuit, click here.
> 0 votes

# Answer
Connect TX of arduino to esp8266 RX, and arduino RX to esp8266 TX.

See this link for more info.
> 0 votes

# Answer
First of all your connectons are wrong: -----Arduino UNO-----

RESET ------------ GND (Why)

Arduino UNO ----- ESP8266

TX ------------------- RX

RX ------------------- TX

(RX is the recieving end, TX is the transmitting end, one should allways connect a transmitter to a reciever both directions, never a transmitter to transmitter or reciever to reciever, and use a logic level shifter)

GND ----------------- GND

ESP8266 --------- LM317(5V to 3.3V) (only for Vcc)

VCC --------------- 3.3V

GND --------------- GND

CH\_PD ------------ 3.3V

In these cases you should use a logic level shifter like 74LVC245 or sparkfun level converter and not a voltage regulator. If you must use lm317 connect it correctly, diodes, capacitors and an adjusting potmeter or resistor. Typical application found in the datasheet on p. 10

baudrate should be 57600 on the esp8266.

glhf :)
> 0 votes

# Answer
Which version of arduino IDE are you using? I use 1.6.12 and works, it does not work for 1.8 versions. Also ensure 3.3v power input for the esp8266 separately from arduino power. I suggest using a PC power supply (color orange is 3.3v).
> 0 votes

# Answer
The issue you are running into is that the Arduino Uno cannot source enough current at 3.3V for esp8266 operation. I had to use a separate power supply with grounds tied together and then my esp8266 responded to AT commands.

Summary:

* I use the Arduino Uno as the serial bridge (RESET tied to GND)
* an external power supply for the esp8266
* and a bidirectional level shifter for 3.3V to 5V TX/RX data paths
* Connected CHPD of esp8266 to GND, waited 5 sec then reconnected to 3.4V
* Arduino IDE \> Tools\> Serial Monitor \> Both NL&CR \> 115200 Baud Rate
> 0 votes

# Answer
First of all do not use any resistors(try it) for RX pin. Connect it directly.

Second connect RST pin of ESP8266 to 3.3V power supply.

And also try to use arduino directly with esp8266 once. Do not use lm317 or any other separate power supply. Use 3.3 volt power supply of arduino.

And i dont know why you have connected RESET pin of Arduino to GND. Please answer me that.
> -1 votes

---
Tags: arduino-uno, esp8266, ftdi
---


title: Blue pill acting as if it had 10bit ADC

text:
# Question
Title: Blue pill acting as if it had 10bit ADC
I just got myself a STM32F103C8 Blue pill board. I am having funny behaviour with the analog readings. It behaves as if the unit was 10bits and not 12 bits.

I uploaded the very trivial Arduino code below. Just to read the analog input A0.

```
void setup() {
  Serial.begin(38400);
}
void loop() {
  Serial.println(analogRead(A0));
  delay(1000);
}

```

If I connect pin A0 to the 3.3v I get this output below.

```
1022
1022
1023
1022
1022
etc...

```

If I connect to a 1.5V source the above values becomes around 500.

It all behaves as if it was 10bits really which I fail to understand. Any ideas why?

# Answer
If you run Arduino code on it, maybe it makes sense to have 10-bit ADC readings on this platform too like on all other Arduino platforms. Unless you configure the libraries to return full 12 bit, if even possible.

This is more an Arduino platform question though.
> 2 votes

# Answer
Adding the following line in the setup() section solves the problem.

```
analogReadResolution(12)

```
> 1 votes

---
Tags: stm32
---


# Question
Title: Creating an AC pulse with arduino and perhaps components
I want to create an AC PWM pulse with arduino. The microcontoller, will be also responsible for specifying the frequency (which will be around 500 Hz).

External electronic components can also be used. Like an H-Bridge perhaps.

EDIT: This is the final waveform I want to produce:

I know the arduino is not capable of producing 36 V output. I plan to just create this waveform, with whatever the arduino can output and then step up the voltage. But this is the final waveform that I want produced.

# Answer
Yes, you want a H-bridge. That is the simplest way to make that "negative\*" voltage.

But you can't just create a square wave and throw it blindly at a H-bridge, you have to be much more careful, otherwise you will cause short circuits and dissipate massive amounts of power.

You will need a "discrete" H-bridge where you have proper control over each transistor, and the best way of doing that is with discrete transistors (MOSFETs are best).

The important thing to remember though is than no transistor ever turns off or on instantaneously - so you have to add a "dead zone" into your waveform. Turn one pair of MOSFETs off, then wait a moment, before turning the other pair on. Otherwise you get a brief overlap in the switching where massive currents can flow straight through everything as all the MOSFETs are turned on (or partially on) at the same time.

Some microcontrollers have programmable dead zones in their PWM outputs, but I am not sure if the AVR chips do - you'll have to check the datasheet - but it's not too hard to arrange a suitable waveform in software or using timers and interrupts (you could look at the `tone()` function and support code for some ideas for the latter).

The programming sequence, if you have 4 outputs H1/H2/L1/L2 for the HIGH and LOW sides of the H bridge pairs 1 and 2, would be:

1. Turn on H1 and L2
2. Pause
3. Turn off H1 and L2
4. Brief Pause
5. Turn on H2 and L1
6. Pause
7. Turn off H2 and L1
8. Brief Pause
9. Repeat

You haven't specified what your load is, but with an H-bridge it is important to remember that the output is not referenced directly to ground but ground alternates from side to side. If you want to properly isolate it from the Arduino ground a transformer can be used as the load to the H-bridge then use the output of the transformer to drive your real load. You can also use the transformer to change the output voltage (the ratio of windings is the same as the ratio of input to output voltage - so a 1:1 winding transformer will give the same voltage out as it gets in).

---

* "Negative" only that the current flows the opposite way through the load, not an actual negative voltage WRT to Arduino GND.
> 2 votes

---
Tags: pwm, signal-processing
---


# Question
Title: 1Hz & 32Hz from 32.768 kHz on ATmega328P at 8MHz & DS3231 32K
I have a 32.768 kHz signal at the ATmega328P input. I need to get 2 signals from this signal: 1Hz and 32Hz. How well will it work? How to do this with a ATmega328P Timer/Counter? What gain will the Timer/Counter give compared to my solution?

```
void setup() {
   pinMode(S32768Hz_PIN, INPUT_PULLUP); // 32.768 kHz signal
   attachInterrupt(digitalPinToInterrupt(S32768Hz_PIN), s32768Isr, FALLING); // Pin 3
}

volatile bool s32768IsrWasCalled = false;  // ISR flag 32768Hz
void s32768Isr() {
   s32768IsrWasCalled = true;
}
uint16_t s32Counter = 0;
uint16_t s1Counter = 0;

void loop() {
  if (s32768IsrWasCalled) {
      s32768IsrWasCalled = false;
      s32Counter++;
      if (s32Counter == 1024) {
        s32Counter = 0;
        // 32Hz
      }

      s1Counter++;
      if (s1Counter == 32768) {
        s1Counter = 0;
        // 1Hz
      }
  }
}

```

Update 24.10.2022 I wrote my first timer 1 setup code. Will this run 32 times per second, indefinitely?

```
// ATmega328P 3.3V 8MHz, Timer 1 & DS3231 32768 Hz
void setupTimer1() {
    // Disables all interrupts
    cli();
    // Reset bits
    TCCR1A = 0;
    TCCR1B = 0;
    // Enable Timer 1 overflow interrupt (TOIE1)
    TIMSK1 = (1 << TOIE1);
    // PWM mode. Mode #7 (fast PWM, top is fixed at 10 bits = 1024)
    TCCR1A |= _BV(WGM10) | _BV(WGM11);
    TCCR1B |= _BV(WGM12);
    // External clock on T1 pin, on falling edge (DS3231 32768Hz pin)
    TCCR1B |= (1 << CS11) | (1 << CS12);
    // Enables interrupts
    sei();
    // pinMode(T1_pin, INPUT_PULLUP); ?
}

void loop() {
    // So get 1 Hz from 32 Hz?
    // There will be no data races here?
    if((pulse_counter % 32) == 0) {
        callback1Hz();
    }

    if((pulse_counter % 2) == 0) {
        callback16Hz();
    }
}

volatile uint8_t pulse_counter;
// Timer 1 Overflow (32 Hz)
ISR(TIMER1_OVF_vect) {
    pulse_counter++;
}

```

Thank you!

# Answer
I did not test your program but, just by looking at it, I would expect it to work... provided you do not add more code! Obviously you will need to add more code in order to do something useful with those signals, and then thinks might break.

The problem with this approach is that the interrupt rate is pretty high: the program gets interrupted every 30.5 µs. You may miss an interrupt if either:

1. it fires while there is already an interrupt (or other critical section) being processed, and that interrupt (maybe combined with some other pending interrupt) takes more than 30.5 µs to complete
2. you add more code to `loop()` and that function ends up taking more than 30.5 µs.

The first condition should be obvious, but I would assume the risk is quite low, as only a very poorly written ISR would take that long to complete. Beware however of library code, as that might bring surprises.

The second condition is a bigger risk, although maybe less obvious. The problem is that this `loop()` assumes the code within `if (s32768IsrWasCalled)` is going to be called exactly once per interrupt. This may not be the case: if the program gets bigger, you may miss interrupts, and get the frequencies wrong.

A simple way to avoid the issue number 2 is to count the pulses within the ISR, as PMF suggests in a comment. I would use a single counter for this, and make it unsigned in order to guarantee that it wraps around reliably:

```
volatile uint16_t pulse_counter;
void s32768Isr() {
    pulse_counter++;
}

void loop() {
    int signal_32Hz = (pulse_counter >> 9) & 1;
    int signal_1Hz = (pulse_counter >> 14) & 1;
}

```

Note that this is one of the few cases when you can access the volatile multi-byte variable without disabling interrupts: since you only ever care about one bit, there is no data race.

A better option, though, would be to use a hardware timer for this job. I would suggest using Timer 1 in “counter” mode (external clock source on pin T1). Using mode 7 (fast PWM, 10-bit) you get the 32 Hz signal entirely generated by the hardware. And then you can use the timer overflow interrupt to generate 1 Hz. The interrupt rate is now 1024 times lower. I let you check the datasheet for the details.
> 2 votes

---
Tags: c++, atmega328, timers, rtc
---


title: Can't get MMC3416xPJ to work

text:
# Question
Title: Can't get MMC3416xPJ to work
I needed a magnetometer with a high Output Data Rate (ODR). This is because I wanted to measure AC magnetic fields of around 20-80 Hz. So I decided to go with the MMC3416xPJ prototyping board which has an ODR of 800 Hz (https://au.mouser.com/new/memsic/memsic-mmc3416xpj-sensors/). I have never written an I2C interface for a sensor myself so I probably messed up. The datasheet for my sensor can be found here. I can get the product ID from the sensor correctly so that means the wiring is correct and some of the code is correct. But when I print out the measurements, they give me overflow values instead of the Earth's magnetic field. BTW I am developing this on Arduino board. Any help would be appreciated. My code can be seen below -

Magnetometer.h

```
#ifndef MAGNETOMETER_H
#define MAGNETOMETER_H

#include "General.h"
#include <Wire.h>

#define MAGNETOMETER_I2C_ADDRESS 0x30
#define X_OUT_LOW 0x00
#define X_OUT_HIGH 0x01
#define Y_OUT_LOW 0x02
#define Y_OUT_HIGH 0x03
#define Z_OUT_LOW 0x04
#define Z_OUT_HIGH 0x05
#define STATUS 0x06
#define INTERNAL_CONTROL_0 0x07
#define INTERNAL_CONTROL_1 0x08
#define RO 0x1b
#define R1 0x1c
#define R2 0x1d
#define R3 0x1e
#define R4 0x1f
#define PRODUCT_ID 0x20

class Magnetometer
{
  public:
    Magnetometer();
    void Setup();
    void Test();
  private:
    void TestConnnection();
    void ReadRawData();
};

#endif

```

Magnetometer.cpp

```
#include "Magnetometer.h"

Magnetometer::Magnetometer()
{

}

void Magnetometer::Setup()
{
    Wire.begin(SDA, SCL);
    TestConnnection();

    Wire.beginTransmission(MAGNETOMETER_I2C_ADDRESS);
    Wire.write(INTERNAL_CONTROL_1);
    Wire.write(0x00);
    Wire.endTransmission();

    Serial.println("Magnetometer Setup");
}

void Magnetometer::Test()
{
    ReadRawData();
    Serial.println("Magnetometer Test");
    delay(1000);
}

void Magnetometer::ReadRawData()
{
    int16_t RawMx, RawMy, RawMz;
    byte status = -1;

    // 1-3
    Wire.beginTransmission(MAGNETOMETER_I2C_ADDRESS);
    Wire.write(INTERNAL_CONTROL_0);
    Wire.write(0x01);
    Wire.endTransmission();

    // 4-7
    Wire.beginTransmission(MAGNETOMETER_I2C_ADDRESS);
    Wire.write(STATUS);
    Wire.requestFrom(MAGNETOMETER_I2C_ADDRESS, 1);
    status = Wire.read();
    Serial.print("status = "); Serial.println(status);
    while ((status%2) != 1)
    {
        status = Wire.read();
        Serial.println("Data not ready");
    }
    Serial.println("Data ready");
    Wire.endTransmission();

    // 8-17
    Wire.beginTransmission(MAGNETOMETER_I2C_ADDRESS);
    Wire.write(X_OUT_LOW);
    Wire.endTransmission();
    Wire.requestFrom(MAGNETOMETER_I2C_ADDRESS, 6);
    RawMx = Wire.read();
    RawMx |= Wire.read()<<8;
    RawMy = Wire.read();
    RawMy |= Wire.read()<<8;
    RawMz = Wire.read();
    RawMz |= Wire.read()<<8;

    Serial.print("RawMx: "); Serial.print(RawMx);
    Serial.print(" RawMy: "); Serial.print(RawMy);
    Serial.print(" RawMz: "); Serial.println(RawMz);

    float scaleFactor = 2048;
    float convertToMircoTelsa = 100;
    float Mx, My, Mz;

    Mx = (float) RawMx / scaleFactor * convertToMircoTelsa;
    My = (float) RawMy / scaleFactor * convertToMircoTelsa;
    Mz = (float) RawMz / scaleFactor * convertToMircoTelsa;

    Serial.print("Mx: "); Serial.print(Mx);
    Serial.print(" My: "); Serial.print(My);
    Serial.print(" Mz: "); Serial.println(Mz);

    // Serial.print("Wire.ava = "); Serial.println(Wire.available());
}

void Magnetometer::TestConnnection()
{
    byte id = -1;
    while (id != 6)
    {
        Wire.beginTransmission(MAGNETOMETER_I2C_ADDRESS);
        Wire.write(PRODUCT_ID);
        Wire.requestFrom(MAGNETOMETER_I2C_ADDRESS, 1);
        id = Wire.read();
        Wire.endTransmission();

        if (id != -1)
        {
            Serial.println("Cannot connect to Magnetometer");
        }
    }
    Serial.println("Magnetometer TestConnnection Success");
}

```

If you guys suggest me any other magnetometers that have a high ODR (at least above 300 Hz), it would be really appreciated.

# Answer
> -1 votes
Perhaps a set/reset before configuring the device helps:

```
writeRegister(MMC34160PJ_CTRL0, 0x80);          // refill cap
delay(50);
writeRegister(MMC34160PJ_CTRL0, 0x20);          // set
//delay(10);
writeRegister(MMC34160PJ_CTRL0, 0x80);          // refill cap
delay(50);
writeRegister(MMC34160PJ_CTRL0, 0x40);          // reset
//delay(10);

```

---
Tags: arduino-ide, i2c, wire-library, magnetometer
---


title: Library files multiple users

text:
# Question
Title: Library files multiple users
I want to place all of my libraries on the server. Currently the sketches work fine and as far as I know the libraries are coming from the individual linux mint machines using cinnamon, releases vary depending on machine. I can move the libraries etc but what do I do to the IDE 1.8.18 and 1.8.19? to make it follow that path.

# Answer
Arduino IDE can use libraries only from 3 locations.

1. libraries folder in sketchbook folder
2. libraries folder of selected board's platform
3. libraries folder in IDE installation folder (only IDE 1, not IDE 2)

There is no option to configure other paths and absolute or relative paths don't work in `#include` directive with the Arduino build process.

The only way to use libraries from a different location is to link with means of the operating system the folder with the library into one of the searched locations.
> 1 votes

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


title: Arduino Board with Microphone

text:
# Question
Title: Arduino Board with Microphone
I have this microphone (http://www.digikey.com/product-detail/en/CMA-4544PF-W/102-1721-ND/1869981) and an Arduino Uno board. I'm trying to read audio values off of my microphone (to test the noise of something (in dB)). I'm very new at this kind of stuff so keeping it simple would really help me out! I have a bunch of different capacitors, LM386N op amps, a bread board, and many resistors. Could someone provide a code and schematic that could help me get data off of my mic? I've tried using this schematic: http://wiring.org.co/learning/basics/microphone.html but couldn't get the code to download onto a Wiring S board due to a "timeout" error and it not being able to "connect with the programmer".

Any and all help would be much appreciated!!

# Answer
> 1 votes
You can use Maxim MAX4466 op-amp which works very well with Arduino. There is a breakout available for the same for arduino at Adafruit here. The chip has a select-able gain from 25x-125x. This amplifies works very well to get a nice waveform for audible noise. There are a couple of libraries available for the waveform that you record and can translate it to frequencies. You can also use it to distort or change the voice. Here is a schematic of the circuit if you want to make one yourself.

# Answer
> 0 votes
Very interesting stuff. As you are new to this kind of stuff i can suggest you, instead of explaining ( because videos are cool), to watch this video that explains very clearly how to use the lm386 with some filters. That video is a project about controlling the arduino through whistling. Hope that helped.

# Answer
> 0 votes
The LM386 is an amplifier that is meant to drive a speaker. What you're looking for is a preamplifier, like the TL072 (cheap) for example, which is meant to amplify a microphone.

Most decent preamps require more than 5V. The OPA2134 is a more expensive opamp that can run off 5V. There are others but not all readily available and cheap.

Now if it's just for fun there is no need to be too fussy. Probably that's why in the arduino world you'll find many examples of people using LM358 and LM386 as microphone preamps.

What you probably don't want to hear is to look in the manuals. But actually in those manuals you find example schematics for all the different use cases. And you'll find the amplifier use case in there too for lm386: on page 11 and 12. That's what you are looking for. To start.

Next you need to bias the output to +2.5V. You do this with a voltage divider. Two registers of say 100k back to back from your arduino 5V vcc output to GND. They 'divide the 5V between them' giving you 2.5V in the middle. That's where you connect the output of your opamp and also one of the analog input pins, say A0.

Be aware that you should start with a small(er) amplification factor. Because amplifying your microphone voltage above 5V peek to peek would fry your arduino pin.

---
Tags: audio
---


# Question
Title: Arduino: How does digitalRead read a value? And what is this value?
I have a Arduino Uno with 14 digital pins. I believe they have an output of 5V. But they can also *input* values. I'm not sure of what exactly it reads when it does that (amperage, voltage ...). Also, *how* do they read it? How can such a tiny thing possibly know what it's receiving?

Just to provide a little more context to the reading part of this question, here's an example circuit. I have a 5V battery connected to an LED and a 220 Ohm resistor. Next thing in the circuit is a wire, which exits the main circuit and connects to a digital pin on the Arduino Uno (here it reads the value). Then the main circuit closes by connecting to ground.

Hope my question is clear enough :)

# Answer
Modern digital electronics is made from many tiny electronic components called MOSFETs (a type of transistor). They can be switched on and off using a voltage, and a very small amount of current. They use the majority of the power when they are switching on and off; the rest of the time they use virtually no power. It this very low-power capability which allows us to make complex digital electronics.

Electronically, a MOSFET looks like a tiny capacitor, which triggers a very low-power switch, on and off. Once there is charge on the MOSFETs capacitor, the switch will stay on or off.

A modern large-scale processor, for example the type of device Intel makes, contains billions of MOSFETs, but requires less than 100W, and switches billions of times/second. So we can be confident that a MOSFET can be switched using much less than 1/10,000,000W. At 5V, that means 1/50,000,000A, or 0.000,000,02A, i.e. 0.02µA.

So, the input circuit, connected to an Arduino's pin has some protection, to protect the MOSFETs from static electricity (which could damage or destroy the capacitor), then a complementary pair of MOSFETs (called N-Chanel and P-Chanel). The input voltage switches one on, and the other off. It typically requires less than a micro-amp of current, but at a voltage close to ground or 5V. See pjc50's diagram.

So an Arduino input pin, connected to the 5V end of the resistor and LED will take a tiny amount of current, for a short time, to switch on.

If that pin is connected between the LED and resistor, at some voltage less than 5V, but more than 0V, then it might not switch fully. It might not give a reliable value of digital 0 or digital 1, and might switch high and low rapidly influenced by electrical noise in the environment.
> 2 votes

# Answer
**It measures voltage**.

The input circuit is conceptually similar to this:

* Voltages close to 5V will turn the lower transistor on and the upper one off.
* Voltages close to 0V will turn the upper one on and the lower one off.
* Voltages in the middle will turn both on to some extent, which is not recommended, and may be read as either 0 or 1 with a threshold in the middle.

"Such a tiny thing" contains tens or hundreds of thousands of transistors.
> 2 votes

# Answer
If somebody(like me) is looking for a explanation in terms of registers, the voltage at a pin when it's a digital input can be accessed with the `PINx` register, with a bit being used per a pin. Based on the value in the specific bit of the `DDRx` register, if it's `0` (an input), the voltage at the pin is represented by the bit in the `PINx`. When it's `1` (an output), the bit at the `PINx` register will be the value in the `PORTx` register for the specific bit(the value written). If the bit in the `DDRx` register for the pin is `0`(an input), the bit in the `PORTx` register represents whether the internal pull-up resistor should be connected to the pin. `x` is used to mark the port (`A`,`B`, for example).

Edit: I've started working with the ATtiny10 for a specific, but most likely just-on-paper project. It has the separate `PUEx` register for the internal pull-ups. It has only 6 pins, with 4 or those being accessible as GPIOs. The pins have specific modes where every pin requires slightly different flag changes for changing the mode.
> 0 votes

---
Tags: pins
---


title: TM1638 making high pitch sound?

text:
# Question
Title: TM1638 making high pitch sound?
I have a TM1638 board with 8 seven-segment displays, 8 LEDS, and 8 buttons. Each time multiples leds are on, the board makes an annoying high pitch sound.

I'm controlling it with an Arduino Uno.

Should I worry about the sound and is it normal?

This is my board :

# Answer
This thread is getting old but this LED&KEY device seems to still be fairly popular so this may still help someone else. I'm using one to control a radio receiver and the constant buzz can get pretty loud.

I found this article (A second look at the TM1638 LED & key controller) which mentions the same issue which was solved by inserting a 100Ω resistor between VCC and the VCC pin. I also added a 1000μF electrolytic capacitor across the VCC and GND pins (well, fairly close to them anyway). This quieted down the buzz a lot though it's still there. The resistor is key though the capacitor helps a bit.

I also tried moving the breadboard connections to a separate, smaller breadboard, away from the MCU and radio receiver chip and was able to use lower values (10Ω and 47μF). I was no longer able to hear the buzz at all.
> 1 votes

---
Tags: arduino-uno, sound
---


# Question
Title: Voltage drop when power from AA batteries
I am using a **Arduino MKR 1010 Wifi** board to control **4 servo** (PS-1109MG). All the circuit is powered by **4 AA rechargeable batteries** (1.2V * 4). Arduino is powered through the **Vin port**.

Below is a circuit just to show how they are connected (board type and other details is not correct).

When all the servos move, the arduino's LED oscillates in intensity. I deduced that the servos have a high instantaneous current consumption and the voltage of the batteries drops too much. I measured this with an oscilloscope.

The voltage drops to around 4V when the servos try to move. When the Arduino MKR is powered from the usb port and the servos from the batteries, everything works fine.

How can I reduce the voltage drop on the batteries, to use them as the only power source? Could I use some electrolytic capacitors to reduce the voltage drop?

# Answer
> 1 votes
You have a 1V drop from about 5V or a 25% load regulation error you know that you have excessive load and for active servos this is a result of the DC coil resistance of the motors that are active.

* If you knew the motor coil resistance then for a transient servo seek, the surge voltage drop can be predicted from the ratio of the load to total resistance (Load+Rs of batteries)
* the main Rule of Thumb to learn is the series resistance adds with batteries in series and reduces with batteries in parallel and thus larger capacity. So you expect the product or Rs and Ah to be constant within some family of same chemistry and brand name.

But there may be sources of deviations to test results so the method must be specified or the same to compare.

* the Rs of batteries rises sharply as state of charge SoC drops below 10% and gradually with repeated sweep tests but lowers gradually with rising temperature.

Let's compare different brands of NiMH (AA vs C) and see how close this is. You can try your own plots to measure the slope of bulk resistance from the VI plots ΔV / ΔI = Rs \[Ω\]

1. https://eneloop101.com/batteries/eneloop-test-results/
2. https://lygte-info.dk/review/batteries2012/Enesense%20C%204300mAh%20%28White%29%20UK.html
3. http://lygte-info.dk/review/batteries2012/Eneloop%20AA%20BK-3MCCE%201900mAh%20(White)%20UK.html

This means changing these products from AA to C results in 31% Rs which equates to a voltage drop and 226% of the AA's Ah capacity.

Eneloop is known to be a reliable high-performance NiMH brand. Your batteries may have less performance. You can measure your motor resistance and see if upgrading size or quality and/or cost of batteries to get the performance you need.

The LED fluctuation is a different problem from not using a constant current driver.

# Answer
> 0 votes
Consider several options:

1. Larger batteries. The type of battery was not specified. For comparison a NiMH AA is on average about 800 mAh where a NiMH D is on average about 6600 mAh.
2. Use two sets of batteries. Connect both battery grounds, all the servo grounds and the Arduino ground together. Only connect the positive of one set of batteries to the Arduino. Only connect the positive of the other set of batteries to the servos. Do not connect the positive Arduino terminal with the positive servo terminals!
3. Using software, only operate one servo at a time. Some (most) servos will stop moving if the position pulse is not seen by the servo.

# Answer
> 0 votes
Welcome! You picked a good place to connect the batteries when fully charged but it is the wrong place. You can use the Vin pin to Power your Arduino with an regulated or unregulated 7 to 12-volt power source. Like several AA batteries in series or a wall adapter that is in the range of 7 to 12 volts. Alternatively, you can power your Arduino through the 5V pin with an external regulated 5V power supply. Leave the 9V batteries for the smoke detectors they do not work very well.

---
Tags: power, servo, battery, voltage, arduino-mkr
---


# Question
Title: Generate a sine wave with a predefined frequency and amplitude via DAC0 or DAC1 with Arduino Due
Good Morning to everyone, I am a PhD Student in experimental fluid mechanics at the University of Naples "Federico II", Italy. I am working on Arduino Due card and i am novel in applications using it. First, I need to generate a sine wave with variable frequency and amplitude. I tried to download several codes which are able to generate sine waves with a pre-defined frequency, but I would like to change this value of frequency at the beginning of the execution of the code. How could i do this ? Second, I would like to change, in real-time, the output voltage of Arduino DAC0 or DAC1 at high speed to generate an arbitrary waveshape.. Is it possible? Thank you in advance for your answers.

Dr. Alessandro Scala

# Answer
The formula commonly used to represent a sinusoidal signal is

V = A cos(ωt)

where A is the amplitude and ω is the angular frequency. This formula should cope well with a variable amplitude. It is, however, not suitable for a signal with variable frequency, because a discontinuity of the frequency is not supposed to create a discontinuity in the signal.

The correct formula for a signal where both the amplitude and the frequency can vary is

V = A(t) cos(φ(t))

where the phase is computed as

φ(t) = ∫ ω(t)dt

In terms of code, this means you need a static variable to keep track of the current phase, and you have to update it periodically in order to perform the numerical integration.

Here is a tentative implementation. I have qualified some variables as `extern` only to hint that you are responsible for managing them. You can remove the qualifier if you integrate this into your own code:

```
// Defined and updated elsewhere.
extern const uint8_t output_channel;
extern float angular_frequency;  // in rad/us
extern float amplitude, offset;  // in ADC steps

// Call this as often as practical.
void update_output()
{
    // Compute the time delta.
    static uint32_t time_of_last_update;
    uint32_t now = micros();
    uint32_t dt = now - time_of_last_update;
    time_of_last_update = now;

    // Update the phase.
    static float phase;
    phase += angular_frequency * dt;
    while (phase >= 2 * M_PI) phase -= 2 * M_PI;  // unwrap

    // Output the signal.
    float output = offset + amplitude * cos(phase);
    analogWrite(output_channel, round(output));
}

```

Regarding the second part of the question (about arbitrary waveshapes), it is, of course, feasible. You just have to pass arbitrary values to `analogWrite()`.
> 1 votes

---
Tags: arduino-due, voltage, frequency, dac, sine-wave
---


# Question
Title: Call functions of one class from another class - Callback
I am new to C++ & I need to call functions of one class from another class. And so that the classes do not know anything about each other. How to do it in Arduino environment?

```
class Encoder {
  using CallBack2 = void( * )(const int, const int);
  using CallBack0 = void( * )();
  private:
    CallBack2 callbackUpDown;
    CallBack0 callbackTab;
    CallBack0 callbackLongPress;
  public:
    Encoder() {}

  void Setup(CallBack2 updown, CallBack0 tab, CallBack0 cbLongPress) {
    callbackUpDown = updown;
    callbackTab = tab;
    callbackLongPress = cbLongPress;
  }

  void Loop() {
    if (true) {
      callbackUpDown(-1, 300);
      callbackTab();
      callbackLongPress();
    }
  }
};

class Menu {
  public:
    void UpDown(const int direction,
      const int count) {}
      void Tab() {}
};

class RTC {
  public:
    void Setup() {}
    void Toggle() {}
};

class Display {
  public:
    void Toggle() {}
};

Encoder encoder = Encoder();
RTC rtc = RTC();
Menu menu = Menu();
Display display = Display();

void setup() {
  rtc.Setup();
  encoder.Setup(menu.UpDown, menu.Tab, []{display.Toggle();rtc.Toggle();});
}

void loop() {
  encoder.Loop();
}

```

Output:

```
In file included from sun.ino:47:0:
callback.h: In function 'void setup()':
callback.h:52:75: error: invalid use of non-static member function 'void Menu::UpDown(int, int)'
   encoder.Setup(menu.UpDown, menu.Tab, []{display.Toggle(); rtc.Toggle();});
                                                                           ^
callback.h:28:7: note: declared here
  void UpDown(const int direction, const int count) {}
       ^~~~~~

```

Thank you!

# Answer
What you are doing here

```
encoder.Setup(menu.UpDown, menu.Tab, []{display.Toggle();rtc.Toggle();});

```

is not only passing a function pointer. You are passing a member function pointer. This is 2 levels more difficult than function pointers on their own.

1. The syntax of declaring a member function pointer is different. You need to include the class name in the function pointer declaration. It would look like

```
using CallBack2 = void( Menu::* )(const int, const int);

```
2. When calling a member function pointer, you need an object to call the function on.

Unfortunately, this is so hard that I can't turn your code into a working example. If you want to be able to read your code in 3 months or if you want others to be able to read your code, stick to normal function pointers. They are hard enough.

Suggestion: implement free functions that do what you want:

```
void menuUpDown(const int dir, const int count)
{
  menu.UpDown(dir, count);
}
void menuTab()
{
  menu.Tab();
}

void setup() {
  rtc.Setup();
  encoder.Setup(menuUpDown, menuTab, []{display.Toggle();rtc.Toggle();});
}

```

Or, since you're already using lambdas (are you aware of that?), you can also

```
void setup() {
  rtc.Setup();
  encoder.Setup(
    [](const int dir, const int count){menu.UpDown(dir, count);},
    []{menu.Tab();},
    []{display.Toggle();rtc.Toggle();}
  );
}

```

Note that pupils and students might not have been introduced to the concept of lambdas. If you publish such code online, people might not be able to change it themselves because they don't understand it.
> 1 votes

# Answer
Also, Using Static Methods Or Non-Member Functions (C-Style)

```
class MyClass {
  public:
    static void onMsg(int num1, int num2) {
      // NOTE: Can't call any non-static method functions here!
    }
};

class LibraryClass {
  using CallBack = void( * )(int, int);
  private:
    CallBack callBack;
  public:
    void Setup(CallBack callBackFunc) {
      callBack = callBackFunc;
    }
    void Loop() {
      callBack(1, 2);
    }
};

MyClass myClass;
LibraryClass libraryClass;

void setup() {
  libraryClass.Setup(&myClass.onMsg); // Provide the instance and function to call
}

void loop() {
  libraryClass.Loop();
}

```
> 0 votes

---
Tags: arduino-ide, c++, atmega328, class, callbacks
---