# Question
Title: MAX30100 and ESP8266 NodeMCU Serial Errors
This is my final year project and for some reason, the max30100 sensor defaults to static values once the HTTP post request has been performed.

```
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <SimpleTimer.h>

#define REPORTING_PERIOD_MS 1000

const char* ssid = "SDsouza";
const char* password = "dsouza@8104045917";
const char* serverName = "http://10.0.0.13/post-sensor-data.php";

String systolic_pressure;
String diastolic_pressure;
String pulse_rate;
String temperature_body;
String BPM;
String SpO2;

PulseOximeter pox;
uint32_t tsLastReport = 0;

SimpleTimer timer;

String sensor_data;
bool Sr;
String machineid = "MR1";
String room_number= "A1";
String bed_number= "1";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(16,OUTPUT);
  WiFi.begin(ssid , password);
  Serial.print("Connecting to SSID:");
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("Connected Successfully!!");
  Serial.println(WiFi.localIP());

  if(!pox.begin())
  {
    Serial.println("Failed");
    for(;;);
  }
  else
  {
    Serial.println("Pox Success");
  }
  pox.setOnBeatDetectedCallback(onBeatDetected);
  //pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  timer.setInterval(1000L , getsendata);
}

void loop() {
  // put your main code here, to run repeatedly:
  pox.update();
  if(millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    BPM = pox.getHeartRate();
    SpO2 = pox.getSpO2();
    Serial.print("Bpm: ");
    Serial.println(BPM);
    Serial.print("SpO2: ");
    Serial.println(SpO2);
    tsLastReport = millis();
  }
  timer.run();
}

void onBeatDetected()
{
  Serial.println("Beat Detected");
}

void getsendata()
{
  while (Serial.available())
  {
    sensor_data = Serial.readString();
    Sr = true;

    int firstcommaindex = sensor_data.indexOf(",");
    int secondcommaindex = sensor_data.indexOf(",", firstcommaindex + 1);
    int thirdcommaindex = sensor_data.indexOf(",", secondcommaindex + 1);
    int fourthcommaindex = sensor_data.indexOf(",", thirdcommaindex + 1);

    systolic_pressure = sensor_data.substring(0, firstcommaindex);
    diastolic_pressure = sensor_data.substring(firstcommaindex + 1, secondcommaindex);
    pulse_rate = sensor_data.substring(secondcommaindex + 1, thirdcommaindex);
    temperature_body = sensor_data.substring(thirdcommaindex + 1);

    HTTPClient http;
    http.begin(serverName);
    http.addHeader("Content-Type" , "application/x-www-form-urlencoded");
    String httpRequestData = "machine_identifier=" + machineid + "&temp=" + temperature_body + "&hr=" + pulse_rate + "&sys_pressure=" + systolic_pressure + "&dias_pressure=" + diastolic_pressure + "&oxy_lvl=" + SpO2 + "&room_number=" + room_number + "&bed_number=" + bed_number + "";
    Serial.print("HTTP Request Data: ");
    Serial.println(httpRequestData);
    int httpResponseCode = http.POST(httpRequestData);

    if(httpResponseCode > 0)
    {
      Serial.print("HTTP Response Code: ");
      Serial.println(httpResponseCode);
    }
    else
    {
      Serial.print("Error Code: ");
      Serial.println(httpResponseCode);
    }
    http.end();

  }
}

```

The arduino mega is sending a string with the variable values set to 0 at startup. The MAX30100 sensor is doing its job of taking the readings however, as soon as the HTTP Post Request is done, the oximeter then defaults to it's static values and refuses to detect further readings.

Output: This is output before HTTP Post

Output after HTTP Post

Once the http post request on arduino startup is done, or if i am taking readings from arduino after startup, the max30100 oximeter stops working and refuses to take further readings or update the values further.

The data is sent to mysql db where i will bbe fetching it on the website using php js and html css. This issue of the oximeter has been bothering me since so many days now and my final year project is nearing. Could anyone please guide me as to how to solve this problem?

Here is the library im using for the MAX30100: https://github.com/oxullo/Arduino-MAX30100

# Answer
Well. Finally. Figured it out. After countless hours of googling and reading the issues on the github library, i just had to insert one line. resetFifo to reset the module after http post and re enable it to take readings normally. Updated code:

```
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Wire.h>
#include "MAX30100.h"
#include "MAX30100_PulseOximeter.h"

#define REPORTING_PERIOD_MS 1000

MAX30100 maxim;
PulseOximeter pox;

const char* ssid = "SDsouza";
const char* password = "dsouza@8104045917";
const char* serverName = "http://10.0.0.13/post-sensor-data.php";

String systolic_pressure;
String diastolic_pressure;
String pulse_rate;
String temperature_body;
String BPM;
String SpO2;

uint32_t tsLastReport = 0;

String sensor_data;
bool Sr;
String machineid = "MR1";
String room_number= "A1";
String bed_number= "1";

HTTPClient http;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(16,OUTPUT);
  WiFi.begin(ssid , password);
  Serial.print("Connecting to SSID:");
  Serial.print(ssid);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("Connected Successfully!!");
  Serial.println(WiFi.localIP());
  if(!pox.begin())
  {
    Serial.print("Failed");
    for(;;);
  }
  else
  {
    Serial.println("Success");
  }
  pox.setIRLedCurrent(MAX30100_LED_CURR_50MA);
  http.begin(serverName);
}

void loop() {
  // put your main code here, to run repeatedly:
    pox.update();
    if(millis() - tsLastReport > REPORTING_PERIOD_MS)
    {
      BPM = pox.getHeartRate();
      SpO2 = pox.getSpO2();
      Serial.print("Bpm: ");
      Serial.println(BPM);
      Serial.print("SpO2: ");
      Serial.println(SpO2);
      tsLastReport = millis();
    }
    while (Serial.available())
    {
      sensor_data = Serial.readString();
      Sr = true;

      int firstcommaindex = sensor_data.indexOf(",");
      int secondcommaindex = sensor_data.indexOf(",", firstcommaindex + 1);
      int thirdcommaindex = sensor_data.indexOf(",", secondcommaindex + 1);
      int fourthcommaindex = sensor_data.indexOf(",", thirdcommaindex + 1);

      systolic_pressure = sensor_data.substring(0, firstcommaindex);
      diastolic_pressure = sensor_data.substring(firstcommaindex + 1, secondcommaindex);
      pulse_rate = sensor_data.substring(secondcommaindex + 1, thirdcommaindex);
      temperature_body = sensor_data.substring(thirdcommaindex + 1);

      String httpRequestData = "machine_identifier=" + machineid + "&temp=" + temperature_body + "&hr=" + pulse_rate + "&sys_pressure=" + systolic_pressure + "&dias_pressure=" + diastolic_pressure + "&oxy_lvl=" + SpO2 + "&room_number=" + room_number + "&bed_number=" + bed_number + "";
      Serial.println(httpRequestData);
      http.addHeader("Content-Type" , "application/x-www-form-urlencoded");
      Serial.print("HTTP Request Data: ");
      Serial.println(httpRequestData);
      http.POST(httpRequestData);

      maxim.resetFifo();
    }
}

```

This code works flawlessly and i can now serial read from arduino, read from the oximeter and http post it to the database normally and again repeat these steps without any errors.
> 3 votes

---
Tags: serial, arduino-mega, nodemcu, http, project
---


# Question
Title: Issue understanding timestamp generated using millis() function
I have this code uploaded to an Arduino Uno which is connected to a gyroscope and storing the data on an SD card. The code is from the OEM.

The delay() function was set to 500 by default but this was changed to 10 in order to get an output frequency of 100Hz.

The millis() function was added to observe whether the 100Hz frequency was being maintained.

```
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
File myFile;

#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
int Addr = 105; // I2C address of gyro
int x, y, z;

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

Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

 writeI2C(CTRL_REG1, 0x1F); // Turn on all axes, disable power down
 writeI2C(CTRL_REG3, 0x08); // Enable control ready signal
 writeI2C(CTRL_REG4, 0x80); // Set scale (500 deg/sec)
 delay(100); // Wait to synchronize
}
void loop(){
 myFile = SD.open("test.txt", FILE_WRITE);

 getGyroValues(); // Get new values
 // In following Dividing by 114 reduces noise
 Serial.print(millis());
 Serial.print(" Raw X:"); Serial.print(x / 114);
 Serial.print(" Raw Y:"); Serial.print(y / 114);
 Serial.print(" Raw Z:"); Serial.println(z / 114);

 myFile.print(millis());
 myFile.print(" Raw X:"); myFile.print(x / 114);
 myFile.print(" Raw Y:"); myFile.print(y / 114);
 myFile.print(" Raw Z:"); myFile.println(z / 114);

myFile.close();

 delay(10); // Short delay between reads
}
void getGyroValues () {
 byte MSB, LSB;
 MSB = readI2C(0x29);
 LSB = readI2C(0x28);
 x = ((MSB << 8) | LSB);
 MSB = readI2C(0x2B);
 LSB = readI2C(0x2A);
 y = ((MSB << 8) | LSB);
 MSB = readI2C(0x2D);
 LSB = readI2C(0x2C);
 z = ((MSB << 8) | LSB);
}
int readI2C (byte regAddr) {
 Wire.beginTransmission(Addr);
 Wire.write(regAddr); // Register address to read
 Wire.endTransmission(); // Terminate request
 Wire.requestFrom(Addr, 1); // Read a byte
 while(!Wire.available()) { }; // Wait for receipt
 return(Wire.read()); // Get result
}
void writeI2C (byte regAddr, byte val) {
 Wire.beginTransmission(Addr);
 Wire.write(regAddr);
 Wire.write(val);
 Wire.endTransmission();
}

```

However, these are the first few values that were saved onto the "test.txt" file:

This shows a change in time of approximately 0.03s between values and therefore a frequency of 33.3Hz. Does anyone know why this is the case?

# Answer
> 2 votes
The delay just adds time to the overall runtime of the `loop()` function. So you would have a frequency of 100Hz only if all the other code would take zero time. And what you are doing there does take a significant amount of time (communicating over I2C and SPI, writing to the SD card). Thus your overall runtime of one `loop()` iteration is considerably longer. From your data we can even say how much longer it took. You measured a 30ms interval between the samples. 10ms of that is the delay. So the rest of the code took 20ms to execute. That also means, that with your current code you can get only up to 50Hz (by removing the `delay()`).

First to explain how to go with a timing situation like this lets assume the targeted frequency is possible with your code:

You have 2 options to go with timing:

* Make the `delay()` smaller. With trail and error find a value that results in a 100Hz sampling frequency.
* Use `millis()` directly for the timing. That way it is not important how long your code took to execute (as long as it was shorter than your sampling interval). For this you can basically copying the code from the `BlinkWithoutDelay` example, which uses `millis()` to blink an LED. You can use it to instead collect data samples and write them to the SD card.

The second option is superior and also a very important concept to understand in programming for Arduinos (or any microcontroller).

---

Now lets have a look at the problem with 100Hz. As explained above your current code takes too long to execute, so that you cannot reach a sample rate of 100Hz. You should use `millis()` to also check, which part of the code does take the most time.

I suspect that its the file writing. One way to speed this up is to only open and close the file once, instead of in every `loop()` iteration (as Edgar Bonet mentioned in the comments). After that I don't think you can speed this up further. A technique, that is often used in such situation, is to first collect a defined number of samples at the wanted frequency - temporarily saving them in an array - and then stop the sampling for writing to the SD card. That can give you short bursts of faster sampling at the cost of needing to wait for writing after that. It depends on your application if that is OK for you.

For the I2C you might be able to speed it up a bit. If your gyroscope is supporting that you can set the I2C clock signal to a higher frequency, for example 400kHz instead of 100kHz, via `Wire.setClock()`. Note that only specific values are allowed with this function and if a value works depends on your microcontroller. I think the Uno supports up to 400kHz.

You need to test by yourself if you can get the execution time below 10ms per `loop()` iteration.

# Answer
> 1 votes
Your loop() function takes many milliseconds to execute because reading gyroscope, opening file on SD, and writing on serial are *slow* and blocking operations. On top of this, you add delay(10), so your final frequency will always be lower than 100Hz.

You should use the *while-millis* pattern, a standard and simple solution to overcome this issue. Here a complete explanation about it.

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


title: FastLED fill_solid array

text:
# Question
Title: FastLED fill_solid array
I'm having trouble in the fill\_solid function with arrays. can you help give color to row3.

```
int row3[]={1,2,3};
uint8_t sizerow3 = sizeof(row3)/sizeof(row3[0]);

void solid(){
  fill_solid(leds[row3[3]], sizerow3, CRGB :: Red);
  LEDS. show();
}

```

This is my complete program.

Thank you

# Answer
`leds[row3[3]]` is not what you think it is. That is selecting one single LED depending on what is in element 4 (index 3) of the 3-element array `row3`. Since there is no index 3 in a 3 element array (only indexes 0, 1 and 2) the value it returns to use as an index to the `leds[]` array is unknown.

`fill_solid` is designed to fill a single uninterrupted string of LEDs starting at LED `n` and progressing for a number of LEDs after that. To set random LEDs all to the same colour you should simply loop through your list of target LEDs and set the colours individually. Something like:

```
for (int i = 0; i < sizerow3; i++) {
    leds[row3[i]] = CRGB::Red;
}
LEDS.show();

```
> 1 votes

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


# Question
Title: Arduino to run and LED strip of up to 100m
I am working on a project to run an RGB strip around a large room and have the colour change driven by an Arduino Uno. I have encountered a number of issues and am looking for clarification.

The first strip I used was a 12V strip at 1A/m. This would work fine except the power requirement is slightly ridiculous and it seems I need to put my array of MOSFETs in at every power injection point.

This was when I decided to experiment with a 5V addressable strip to do it. Working with a 5V system gave me more ease as the power requirements are lower and the parts list is also minimal, but after some research, it seems that the signal line will degrade significantly on that many WS2812B's / line length.

I suppose I could but a transistor inline every n-number of 5m strips (similar to the power injectors), however I would like to ask for some opinions from the community around other issues I may encounter, and whether or not this is the right solution for the job.

The scope of the project is to hold a colour for a number of seconds then switch colour based on a predefined program. This program is defined on an external device that uses the Arduino's serial port to communicate the desired colour. The implementation itself is very simple.

The main issues I can see are the power requirements (I think I have this sorted for the 5V version but not the 12V version) and getting the signal to the final LED. On a 60 LED/m strip this could be in the order of around 6000 LED's and that seems like a lot.

What are your views/recommendations?

Cheers!

# Answer
> 1 votes
**Signal degradation:** This is pretty much not a problem, as long as you just send the signal through the LED strip. Each WS2812B chip has circuitry to ensure, that the output signal is shaped correctly. As long as you don't have long runs of pure cable for the signal in between you will be good.

**Power requirements:** Using WS2812Bs lets you ditch your own MOSFET driving circuits, though the overall power will be in the same range. When you drive the LEDs at full intensity white (R, G and B full intensity) each LED will draw about 60mA. With 60 LEDs/m and 100m length you have 6000 LEDs, which equates to a max current of 360A. Thats a lot. You will probably need multiple power supplies. I think you can get 5V power supplies with like 70A from typical retailers. Of course there are also some which, provide more, but you will also want to reduce the max length of cable the current will flow (putting each power supply near the strip part, that it is powering).

Also you should inject power to the strip every 1 to 1.5m to stay safe. Above that you can see degradation after some time (I injected every 2.5m once and the LEDs still work, but you can see the degradation on the strip material and it gets hot when being on).

IMPORTANT: When you buy the typical brick power supplies, they often use a barrel connector. But with these currents you shouldn't use them. In one of my own projects I currently have to replace those with better connectors, because the barrel connectors started to melt from the heat and smoked. I know use small banana connectors, which are also used for drone motors. They can handle way more current without getting hot. Also your cable should be thick enough to handle the current without getting hot.

**Controller:**

As you already know you will get into the memory limit with the Uno. Your assessment of the needed memory for using the FastLED library (or the NeoPixel library) is correct. You will need 18kB only for the buffer (not including the rest of the programs variables).

Now you can either

* change to a microcontroller with enough RAM to handle that buffer
* or send the data out on demand instead of first filling it into a buffer.

The first option will definitely be easier with programming. The second option will require you to do some handwork. The libraries that I know of all use a buffer. Though I've once read this article about the timing on WS2812B LEDs. In the end the author also links to his working code, which puts out the data directly without using a buffer. You might wanna have a look at it. Also you could look at the code of the FastLED or Neopixel library. They of course also have the code to send the data and you might be able to copy and adapt that code for your case.

---
Tags: arduino-uno, rgb-led, led-strip, ws2812
---


# Question
Title: Arduino Nano Atmega328P not sleeping with either <LowPower> or <avt/sleep.h>
I'm working on a battery powered Arduino Nano project. I really need it to save power for hours on end, so I turned to Arduino LowPower Library and avr/sleep.h to do the job.

However, whatever I do, it doesn't look like the board isn't going to sleep. I have a sample sketch that tries to put the board to sleep and then toggles a relay when it wakes up, but it always toggles the relay instantly after booting, so that means it hasn't gone to sleep.

I also measured the current going into the board, and it's drawing 14mA consistently. I would expect to see a much lower draw whilst it's asleep.

Here are the two pieces of code that I've tried, one with LowPower and the other one with avr/sleep.h

```
void setup(){
    pinMode(relayPin, OUTPUT);
}

void loop(){
    // This call doesn't seem to do anything
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    toggleRelay(); //This gets executed continuously, with no indication of sleep time
}

```

Here's the other one with LowPower

```
void setup(){
        pinMode(relayPin, OUTPUT);
    }

    void loop(){
        // This call doesn't seem to do anything
        LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

        //This gets executed continuously, with no indication of sleep time.
        //I would expect it to see it toggle only every 8s
        toggleRelay();
    }

```

I'm probably doing something stupid, but I can't figure out what... Any help? Thanks a lot!

# Answer
> 5 votes
I don't know about the LowPower library. However, four your avr-libc-based test, you forgot to actually put the device in sleep mode with `sleep_mode()`:

```
void loop() {
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // select a deep sleep mode
    sleep_mode();   // now go to sleep
    toggleRelay();  // executed at wake up
}

```

Beware that, if you haven't enabled a wakeup source that is active in the mode you selected, the microcontroller may sleep until it is power-cycled or receives an external reset.

---
Tags: arduino-nano, atmega328, sleep
---


# Question
Title: Can an MCP2515 CANBUS controller be used for two-way communication?
I tried searching code for an MCP2515 with Arduino on Arduino Forums, Instructables, Electronics Hub, YouTube, etc.

All of them showed code for a transmitter node and a receiver node, sensors on one node, and result on the other end.

Can we connect two Arduinos using an MCP2515 and communicate TWO WAY?

# Answer
I never used CAN bus myself, but what you could do is one of the following:

* Letting the transmitter send a specific (short) message to the receiver. In case the receiver has something to transmit, it sends a specific reply back, so the transmitter can request the receiver to send the actual message to be sent. The disadvantage is that polling is needed.
* If you want the receiver to be able to send its message as fast as possible, add a separate wire next to the CAN bus communication. If that line is LOW or HIGH (decide yourself), then the transmitter can 'immediately' send a message to have the receiver send its actual message.
> 0 votes

# Answer
---Yes--- It should work nicely. They operate only in simplex mode (sending or receiving) to the outside world. Internally they also monitor what they are sending for error checking etc. From the user point they would appear to be bidirectional because they can switch between send and receive messages rapidly, message by message. Of course the bus speed helps. You can get upto 1 Meg with these. I use Cory Fowler's "mcp\_can.h". You can get it at: "https://github.com/coryjfowler/MCP\_CAN\_lib". The library has both send and receive .ino files, get them to work first. Since CAN is priority Based NDA Non Destructive Arbitration the higher priority message will prevail regardless of who else is on the bus or is sending a message.

Do not forget to put jumpers on the module to terminate the bus. Note the bus gets terminated only at the physical ends. The bus design impedance is 60 Ohm, the termination resistors are 120 ohms.

You simply combine the send and receive sections of code in your module, nothing special to do. You initialize both send and receive at the same time with basically the same information. You will find the information for this in the setup() section of the code. Be sure to check crystal frequencies, I have seen both 8 and 16 Mhz crystals on these boards.

Per the Bosch specification, which is readily available, The CAN bus does arbitration automatically by a defined priority on a bit by bit basis. To send a message with the MPC2515 you load it and when the bus becomes available it will transmit it, if there is an error it will retry many times (internal counter) and if it fails you will know. When a message is sent it must receive an ACK in a specified part of the can frame. This can be generated by any node. Your internal protocol needs to determine if the right node got the message. By the time your external logic can determine it wants to send a message and send a signal it will have already been sent in a standard CAN setup. Any number of modules can start transmitting but the arbitration will weed them out and the highest priority message will get through. Every node will receive every message, depending on its filtering etc it may accept it or ignore it. You can pole or take an interrupt any time it receives a message etc.
> 0 votes

---
Tags: can-bus
---


# Question
Title: ESP32 Wifi not working when powered by battery
I'm quite new to ESP32 development. I've been using this devkit for a few small projects and everything was going smoothly until I decided to run it on battery. In particular, the ESP32 devkit I'm using, when connected to a battery, seems to have issues when trying to connect to the Wifi.

I'm using a 9V battery connected to a MB-V2 power supply to convert the output voltage to 3.3.V. The power supply board has the following specifics:

* Input voltage: 6.5-9v (DC) via 5.5mm x 2.1mm plug
* Output voltage: 3.3V/5v
* Maximum output current: 700 mA
* Independent control rail output: 0v, 3.3v, 5v to breadboard

As you can see in the picture, my multimeter measures an output voltage of about 3.3V

I built a sample project for debugging, here's the schematics:

The battery is connected to the power supply which outputs 3.3V and powers the ESP32 through its **3.3V pin**. I don't have a schematic for this specific devkit I'm using so the devkit used in the schematics is the DOIT one, hence all of the pins are off. The code is quite simple, though, so it hopefully can clear things a bit:

```
#include <WiFi.h>

const int uS_TO_S_FACTOR = 1000000;
const int TIME_TO_SLEEP = 3;
const int RED_LED_PIN = 32;
const int BLUE_LED_PIN = 25;
const int YELLOW_LED_PIN = 26;
const char SSID[] = "SSID";
const char PASS[] = "PASS";

void startupSequence(){
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(BLUE_LED_PIN, LOW);
  digitalWrite(YELLOW_LED_PIN, LOW);
  // Sequence
  digitalWrite(RED_LED_PIN, HIGH);
  digitalWrite(BLUE_LED_PIN, HIGH);
  digitalWrite(YELLOW_LED_PIN, HIGH);
  delay(1000);
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(BLUE_LED_PIN, LOW);
  digitalWrite(YELLOW_LED_PIN, LOW);
  delay(500);
}

void setup(){
  Serial.begin(115200);
  while(!Serial){}
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(BLUE_LED_PIN, OUTPUT);
  pinMode(YELLOW_LED_PIN, OUTPUT);
  startupSequence();
  delay(500);
  digitalWrite(RED_LED_PIN, HIGH);
  delay(1000);
  Serial.print("Connecting to ");
  Serial.println(SSID);
  WiFi.begin(SSID, PASS);
  while ((WiFi.status() != WL_CONNECTED) && (millis()<10000)) {
      Serial.print(".");
      delay(500);
  }
  Serial.print("Connected. IP: ");
  Serial.println(WiFi.localIP());
  digitalWrite(RED_LED_PIN, LOW);
  if(WiFi.status() == WL_CONNECTED) //Run this only the first time
  {
    Serial.println("Connected");
    digitalWrite(YELLOW_LED_PIN, HIGH);
  } else
  {
    Serial.println("Not connected");
    digitalWrite(BLUE_LED_PIN, HIGH);
  }
  delay(3000);
  digitalWrite(BLUE_LED_PIN, LOW);
  digitalWrite(YELLOW_LED_PIN, LOW);
  Serial.println("Going to sleep");
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}

void loop(){}

```

In the code, the ESP32 first lights up all LEDs, then it lights up the red LED while it tries to connect to the Wifi. After at most 10 secs, it lights up the yellow LED if it successfully connected, otherwise it lights up the blue LED. Also, as a last thing I send the ESP32 into deep sleep, as my intention was to measure its power consumption during sleep.

When connected to the PC, everything runs smoothly, while when connected to the battery the ESP32 (apparently) never exits the while loop and the red LED stays always on. The RED led then starts flickering and the power LED start blinking. Resetting it throught the RST button on the devkit causes the power LED to start blinking and the red LED never lights up. This continues until I cut off the power, then the code seems to start again from the beginning (i.e. the startup sequence) and the this behavior repeats.

I've read a few posts about similar issues with ESP32 devkits, but the problem was always about batteries not having high enough voltage, which doesn't seem to be my case. What could be causing the issue?

# Answer
> 3 votes
I agree with chrisl, the battery does not have a low enough impedance to operate your project. What you are not taking into account is the transmitter current when it is transmitting to the wifi. I have been finding that when it wakes up it draws upwards of 500mA for a short time, measured with a scope and current probe. This appears during the " WiFi.scanNetworks()" function. Add on top of that all the LEDs and other electronics What do you think it will draw. The fact that it operates on the USB also helps confirm this. Try with 6 bigger batteries in series, I expect it to work properly. Check this link out from:Expressif, the manufacturer of the chip at https://esp32.com/viewtopic.php?t=2662

---
Tags: esp32, wifi, battery
---


# Question
Title: How can I use both ultrasonic and IR sensor and ultrasonic sensor at ones with Arduino
I want to use both the ultrasonic sensor and IR sensor with Arduino + motors for a car project. Will I have to do any kind of multithreading on Arduino, or is it something else

# Answer
> 1 votes
While it is completely possible to hook two or more sensors to Arduino, once you talk about multithreading, you need to think about RTOS support. You can achieve parallel processing by creating 2 diffenent tasks using xTaskCreate in freeRTOS. Latest development support in Arduino allow to create such tasks.

https://github.com/feilipu/Arduino\_FreeRTOS\_Library

While the concepts of RTOS are vast, you can quickstart with Arduino freeRTOS library and check whether it meets your requirements. I used to do such project for obstable avoider bot and faced lot of challenges if there is no parallel processing. I am sure you'll be able to acheive much better results with multithreading.

Regarding sensor, make sure ultrasonic sensor is giving reliable data for every readings and don't use IR sensor under sunlight conditions otherwise it'll give erratic results. All the best with your project!

# Answer
> 0 votes
Arduinos don't do multithreading. There are a number of attempts at implementing such things, but they're a waste of time and resources.

Instead you need to get into the habit of two things:

1. Write non-blocking code
2. Make use of the internal hardware peripherals when possible

The motors, using the hardware PWM, are very much "fire and forget" - set them going and you can forget about them until you want to change their speed or direction.

Ultrasonic sensors can be made both more accurate and more "in the background" by using the Input Capture peripheral of the Arduino.

IR sensors (I assume you mean proximity sensors) are usually either just like a button or a potentiometer - you just read them when you want to know what it's doing.

It's your task to learn how to fit all that together into a single program that reacts to the inputs in the way you want and control the motors in the right way.

---
Tags: arduino-uno, sensors, threads
---


# Question
Title: How to pass non-static class member to callback on avr platforms?
I am using the PubSubClient library in my own Arduino library. I'm having trouble with trying to assign a class member as the client library setCallback callback function.

MyClass.cpp:

```
#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"
#include "MyClass.h"

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

void MyClass::connect(String host, int port) {
  mqttClient.begin(host, port, "/");
  mqttClient.setCallback(incomingEventHandler);
}

void MyClass::loop() {
  mqttClient.loop();
}

void MyClass::incomingEventHandler(char* type, byte *payload, unsigned int length) {
  // do stuff with incoming data
  // need to access other member functions and class variables
}

```

MyClass.h:

```
#ifndef MyClass_h
#define MyClass_h

#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"

class MyClass {
  public:
    void connect(String host, int port);
    void loop();
    void incomingEventHandler(WStype_t type, uint8_t *payload, size_t length);
};

#endif

```

Error I see is:

```
sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:14:47: error: no matching function for call to 'PubSubClient::setCallback()'
mqttClient.setCallback(incomingEventHandler);

```

If I move the incomingEventHandler function outside the class definition, it works as expected, however then I can't call other class members or access class properties in the same scope.

In arduino c++ how can I pass non-static class member properties as a callback? Is there a better way to approach this?

P.S. This code is only to show the intent. It might not be compile too. There was a similar question like this at: How to pass non-static class member to callback?

but this is for esp-8266 and this is for avrmega4809 based board.

# Answer
> 2 votes
You can't. On the AVR platform, `PubSubClient::setCallback()` expects a raw function pointer as a callback, and that is what you have to provide. A static method is equivalent to a raw function, a non-static method is not, and neither are a functor or an `std::function`.

If you need more that one `MyClass` object, one solution might be to modify the pubsubclient library in order for it to store a pointer to your `MyClass` instance, and pass this pointer to your callback. If you never have to instances of `MyClass` subscribe to the same topic, a better solution might be to statically store a map from topics to `MyClass` instances and, within the callback, use this map to find the appropriate instance.

---
Tags: arduino-mega, c++, avr, avrdude, avr-gcc
---


# Question
Title: Why is there a cutoff on these accelerometer measurement values? - ADXL375
I'm using a Teensy 3.2 to read data from an ADXL375 using SPI. In general the communication is going just fine and I can activate settings etc. However, when I try to read X, Y or Z data it seems like some part of the measurement values are missing.

I'm performing measurements with the ADXL375 and writing the LSB values straight to an SD card, so no conversion to g or anything like that. The accelerometer range goes to +/- 200g, so that should give a max LSB value of about 200\*20(scale factor) = +/- 4000 LSB.
During some tests I was swinging the accelerometer with my hand, and tapping it directly with a pen, which gives a momentary high impact. The swinging values are represented well and look credible to me, however the pen tapping values seem to be cut off at precisely 511 LSB, see graphs. That seems incorrect. So why is that?

N.B. The range of the ADXL is fixed to 200 g, so no choice to be made there.

My thinking is that something is going wrong with the conversion of the two ADXL registers (two's complement) to form a single number. This is the conversion I'm doing (i.e. I'm reading out the FIFO in one go):

```
void ADXL375::saveFIFO(){
    int fifo_index;
    int16_t x, y, z;
    fifo_index=0;
//    readFrom(DEVICE,ADXL375_INT_SOURCE_REG,1,buff);

    for(int i=0;i<32;i++){
        multiByteReadSPI(ADXL375_DATAX0_REG, 6, bufferSPI); //read the acceleration data from the ADXL375
        x = (((uint16_t)bufferSPI[1]) << 8) | (uint16_t)bufferSPI[0];
        y = (((uint16_t)bufferSPI[3]) << 8) | (uint16_t)bufferSPI[2];
        z = (((uint16_t)bufferSPI[5]) << 8) | (uint16_t)bufferSPI[4];

        // Serial.print(bufferSPI[5], BIN); Serial.println(bufferSPI[4], BIN); // z
        // Serial.print(bufferSPI[1], BIN); Serial.print(","); Serial.println(bufferSPI[0], BIN);  // x

        if (x & 0x8000){ // Check if the binary number is negative, by checking whether left most bit is 1 or not.
            // If negative, then perform not operation and add one to get magnitude
            x = ~x + 1;
            x = - x;
        }
        if (y & 0x8000){ // Check if the binary number is negative, by checking whether left most bit is 1 or not.
            // If negative, then perform not operation and add one to get magnitude
            y = ~y + 1;
            y = - y;
        }
        if (z & 0x8000){ // Check if the binary number is negative, by checking whether left most bit is 1 or not.
            // If negative, then perform not operation and add one to get magnitude
            z = ~z + 1;
            z = - z;
        }

        lastFiFo[fifo_index]    =   newistFiFo[fifo_index];
        newistFiFo[fifo_index]  =   x;
        fifo_index++;
        lastFiFo[fifo_index]    =   newistFiFo[fifo_index];
        newistFiFo[fifo_index]  =   y;
        fifo_index++;
        lastFiFo[fifo_index]    =   newistFiFo[fifo_index];
        newistFiFo[fifo_index]  =   z;
        fifo_index++;
        // debugPrint(x); // debugPrintln(", Saving fifo");

                // x = (((int16_t)bufferSPI[1]) << 8) | bufferSPI[0];
        // y = (((int16_t)bufferSPI[3])<< 8) | bufferSPI[2];
        // z = (((int16_t)bufferSPI[5]) << 8) | bufferSPI[4];
        // scaleXYZ(&x,&y,&z);

    }

 }

```

This is the SPI Multibyte Read function I'm using:

```
void ADXL375::multiByteReadSPI(uint8_t regAddr, uint8_t numberOfBytes, uint8_t *dataBuffer){

    SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE3));

    digitalWrite(_chipSelectPin,LOW);

    uint8_t readMBaddr;

    if (numberOfBytes > 1){ // for an actual multibyte read
        readMBaddr = 0b11000000 | regAddr; //  From left to right: read (1),  yes multibyte (1), and then a bunch of zeros
    }
    else{ // for single byte read
        readMBaddr = 0b10000000 | regAddr; //  From left to right: read (1),  not multibyte (0), and then a bunch of zeros
    }

    SPI.transfer(readMBaddr);

    for (uint8_t k = 0; k < numberOfBytes; k++ ){
      dataBuffer[k] = SPI.transfer(SPI_DUMMY_VALUE);
    }

    digitalWrite(_chipSelectPin,HIGH);

    SPI.endTransaction();

}

```

I also had a look whether the SPI transfers are okay. The image shows one multibyte read, consisting of a command byte on the far left, and then 6 read bytes after that. Nothing out of the ordinary there.

# Answer
> 2 votes
I found the answer. Turns out the datasheet of the ADXL375 is wrong, and the user can actually change the range themselves (even though the datasheet says you can't). In my case, the range was unintentionally set to 25 g (instead of 200 g). See below the full explanation by bvn123 \- which was posted in 2017, yet Analog Devices has still not updated the datasheet.

> I use ADXL345 and ADXL375 under a uC software, which was written for ADXL345.
>
> The Datasheet for ADXL345 says about ±2g/±4g/±8g/±16g ranges and corresponding to these ranges 10/11/12/13bits resolutions.
>
> The Datasheet for ADXL375 shows only one range ±200g and 13bits resolution. .
>
> Inspite of the ADXL375 Datasheet's info, that Register 0x31 only state for bits D3:D2:D1:D0 is 1n11 (D3 is the Full resolution bit, D1:D0 are the Range bits), the ADXL375 reacts for D1:D0 and D3 change in the Register 0x31 the same way, as the ADXL345,
>
> So, in reality ADXL375 also provides 4 ranges (±25g/±50g/±100g/±200g).

---
Tags: spi, teensy, bit
---


# Question
Title: Is the a low memory alternative to SoftwareSerial?
I'm running a program on a ATtiny85 and running into problems because of a lack of available RAM. When I ran `avr-nm` on my ELF file I found that SoftwareSerial was taking up a lot of RAM even though I'm just using it to set the data transfer rate with `mySerial.begin(9600);` and nowhere else.

So I'm wondering if there is another way of doing this without using so much memory:

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(0,1);

mySerial.begin(9600);

```

# Answer
Simplest thing would probably be to edit your copy of SoftwareSerial.h and replace `#define _SS_MAX_RX_BUFF 64` on line 42 by something smaller. If your `loop()` runs fast enough (no delays, no blocking code) you could probably get away with buffering only a very few bytes.

Or you could rewrite the library so that, instead of buffering the incoming bytes, it handles them to you for processing. See for example this receive-only UART code based on the USI port for an illustration of the approach.
> 6 votes

# Answer
My ESP8266 was randomly crashing any time I used `SoftwareSerial` from framework-arduinoespressif8266 or https://github.com/plerup/espsoftwareserial, due to too low memory.

https://github.com/CrazyRobMiles/Esp8266EdgeSoftwareSerial fixed this problem. I still receive data from the sensor via `SoftwareSerial`, and there is 4000 bytes more RAM compared to the alternative implementations.
> -1 votes

---
Tags: softwareserial, attiny, memory-usage, memory
---


# Question
Title: Can I flash hoodloader2 or HEX files on Arduino Simulators?
I want to make a HID Keyboard out of Arduino UNO, in UNO board the script runs perfectly fine, but the UNO board requires me to flash it every-time I want to put in a new script in it, so can I do the same on an Arduino Simulator? can I Flash Hoodloader2 on Arduino simulators by shorting the ICSP pins on UNO Board on a Simulator? if yes, please suggest the name of the application/ website.

# Answer
> 0 votes
Only Arduino boards with ATmega16u2 as USB adapter can use Hoodloader. So not even all Uno clones can use it.

I doubt the simulator is so precise that it would simulate the second MCU on Uno to allow flashing it over its ICSP heeader (ICSP2). I guess it doesn't even support flashing the main MCU over ICSP.

If the simulator supports Arduino Lenonardo, then you can maybe use the HID library. Leonardo has ATmega32u4 which has native USB support.

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


# Question
Title: How to connect a LiFePO4 battery directly to an esp32?
If I want to connect a LiFePO4 battery (as the power supply) directly to an esp32 - would this be the correct way: the plus of the battery to the 3.3 volt pin and the minus to a ground pin?

# Answer
No. Absolutely not.

A LiFePO4 battery is 4.2V when fully charged. The absolute maximum voltage of an ESP32 is 3.6V.

You **will** kill the ESP32.

Instead you need to have a voltage regulator with a very low dropout. Ideally a switching ("buck") regulator with a zero-dropout "pass" mode to give the maximum life from your battery.

Even better is a "buck/boost" battery regulator that will boost the voltage up to a stable 3.3V once the battery voltage drops too low.

If all this is beyond you then you're better off using a powerbank to do the regulation to 5V for you then convert that back down to 3.3V with a simple buck regulator.
> 1 votes

# Answer
I know this question is two years old but it still pops up on research. I just wanted to add something from my experience with this: If you take an Enerpower HTCFR18650 for example datasheet you see that the maximum voltage isn't 4.2V but 3.65V +/- 0.05V. While this technically is a little bit above the absolute maximum rating of the ESP32 (3.6V), in a non critical environment you can absolutely use the battery without voltage regulator. Just keep in mind that you also will not have any undervoltage protection in this case.

I'm not a fan of this negativity ("**you will fry**", "*you kill you ESP*", "***Everyone will die***"). An ESP32 costs $1. Just try it and if it works its great (it does) and if it doesn't, don't blame me ;)
> 3 votes

---
Tags: esp32, battery
---


# Question
Title: Is there a good reference for Arduino Due memory architecture and usage?
It's been harder than I expected to find a reference source or usage guide.

There's a number of sources I've looked at along the road to this question:

* The Due is listed here and here as having 512KB flash memory, 96KB SRAM and zero EEPROM.
* The arduino foundation tutorial notes that Due memory architecture is different but doesn't expand further.
* @Majenko's answer to this previous question notes, "*There is no PROGMEM required on ARM. There is no memory bus separation between Flash and RAM*"
* The SAM3x datasheet block diagrams show a unified bus (i.e. Von Neumann architecture (not Harvard architecture like the AVR boards))
* This answer on the Arduino Forum suggests (regarding allocating constants to flash), "*\[...\] all you have to do is use "const" in the variable declaration. \[...\] Everything that's "const" gets put into flash without consuming any RAM. PROGMEM, pgm\_read\_byte() and the other AVR names are defined only so code designed for AVR can compile. But they do absolutely nothing on \[SAM3X MCUs\]* "
* The `F()` macro seems to still work.

So my question is searching for links to a reference or guide for memory usage on the Arduino Due. I hope a guide (or your answers) might explain the differences caused by the change to a Von Neumann architecture bus, what is stored where, highlighting which memory handling techniques developed for Harvard architecture AVR MCUs remain relevant on the Due.

If there is no guide I'm hoping this question and your answers may become a good reference point. Thanks for reading!

# Answer
So (review feedback welcomed) in the **Arduino Due SAM3x memory architecture** compared to the AVR architecture:

**Non-volatile flash memory**

*contains:*

* program instruction code (same as AVR)
* bootloader (same as AVR)
* all runtime C++ constants including incode string literals (different to AVR)

*is accessed by:*

* C++ const data definition code and incode literals (different to AVR)
* C++ instruction code (same as AVR)
* `PROGMEM`, `PSTR()`, `F()`, pgmspace library `*_P` functions are *not* required and compile for platform compatibility only (different to AVR).

**Volatile SRAM memory**

*contains:*

* variable dynamic storage, organised in a stack and heap structure (same as AVR)
* *no* static/constant storage, which now stays in flash (different to AVR)

*is accessed by:*

* C++ data definition code (same as AVR)

**Usage**

* Heap fragmentation remains an issue to be managed. Preferencing local to global allocation, and avoiding dynamic heap allocation remains relevant to Arduino Due (e.g., Arduino strings)
* Techniques to move constants to flash memory are not relevant for Due, but may be relevant for multi-board compatiblity.
> 1 votes

# Answer
Yes, the Arduino Due uses a flat memory model with a single address space for Flash and RAM. Therefore all constant data sits in flash and does not need to be copied to RAM at startup, like the AVR-based arduinos do. The `progmem` stuff for the AVR-based CPUs is required because they need to use different instructions to read data from flash than from RAM. This is no longer the case on the Due (nor most other 32-bit MCUs, such as the ESP32), and a string address in an instruction works just the same whether its in RAM or in Flash (as long as it's not written to, of course).

The `F()` macro is available for convenience, so that you can more easily write code that works for all Arduino boards. On the Due, it is basically implemented as no-op.

When you're working on the memory model of the Due, I might point to this question, showing that there's a bug in the memory management implementation of the Due, allowing unlimited memory allocation.
> 2 votes

---
Tags: arduino-due, memory-usage, flash, progmem, sam3x
---


title: I2S pins don't output audio in ESP8266

text:
# Question
Title: I2S pins don't output audio in ESP8266
I am trying to use the `ESP8266` to output some audio, but I'm having trouble making it work. I downloaded the library `ESP8266Audio` and am testing one of the examples they have in the repo, namely streaming MP3 from HTTP, (link). There is nothing however outputted from the I2S pins, D1 and D2, but only from RX pin. I have a dual amplifier, so I need the analog signals, not the digital. So I want to ask if there is something extra I need to add in the program, or if I'm using the wrong pins. Any help is appreciated :)

# Answer
> 2 votes
There might be a built-in I2S module, but an I2S module does not output an analog signal. The ESPs have no DAC, so you definitely need additional hardware in form of a I2C-DAC/codec IC. There's no software solution.

---
Tags: esp8266, audio
---


# Question
Title: Can I improve EEPROM lifetime by not changing bits?
In my current project I need to store the current elapsed time in hours to retrieve it in case of power loss. Since I am using a Arduino Nano I would ideally like to use the built in EEPROM without additional hardware.

The written values and their order will always be:

0 -\> 1 -\> 2 -\> 3 -\> 4 -\> 5 -\> 6 -\> 0 -\> ....

If I write that on EEPROM per 0-\>0 full cycle the last bit will change 7 times and the other bits are pretty much idle. That's why I thought of distributing the changes more evenly by using instead the sequence

0 -\> 1 -\> 3 -\> 7 -\> 15 -\> 31 -\> 63 -\> 0 -\> ....

This would change every bit only once during a full 0-\>0 cycle. Does this improve EEPROM life expectancy or is the life expectancy linked to updating full bytes rather than individual bits?

edit: Since the question was closed for being off-topic, I altered the introduction a little bit. I am sorry if some of the comments are no longer fully valid. Since I don't fully understand why the question was closed (especially since there is EEPROM-tag), I would be grateful for a tip where on stackexchange the question would be best suited.

# Answer
> 2 votes
On your next design consider using FRAM, it is non volatile and supports almost unlimited (10 - 14th) read write cycles. The library I use or EEPROM supports the update function where it reads the memory first and does not write to it if it is to remain unchanged.

# Answer
> 1 votes
It is possible to write to ATmega EEPROM address without clearing its previous value. The write mode is set with the EEPMx bits in the EECR register.

The avr-libc eeprom.h write functions only use the erase and write mode and the Arduino EEPROM library only uses avr-libc eeprom.h write function.

I modified the `EEPROM_write` example function from the datasheet to write without erase.

```
#include <EEPROM.h>

void setup() {

  Serial.begin(115200);

  int address = 0;

  EEPROM.write(address, 0b11111111);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111110);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111101);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11101111);
  Serial.println(EEPROM.read(address), BIN);

}

void loop() {

}

void EEPROM_write_no_erase(unsigned int uiAddress, unsigned char ucData) {
  /* Wait for completion of previous write */
  while (EECR & (1 << EEPE))
    ;
  /* Set up address and Data Registers */
  EEAR = uiAddress;
  EEDR = ucData;
  /* Write only */
  EECR |= (1 << EEPM1);
  EECR &= ~(1 << EEPM0);
  /* Write logical one to EEMPE */
  EECR |= (1 << EEMPE);
  /* Start eeprom write by setting EEPE */
  EECR |= (1 << EEPE);
}

```

the output is as expected:

```
11111111
11111110
11111100
11101100

```

I don't know if use of this feature improves the lifetime of the ATmega EEPROM.

---
Tags: eeprom
---


# Question
Title: Does anyone have code that successfully calculates velocity from an accelerometer
I'm trying to calculate the speed of a rocket for my project. I've been given the task of calculating this with an adxl3xxx accelerometer sensor. I'm not sure how to go about this as an accelerometer takes gravity acceleration into account. Can someone provide some form of code to help me understand. I've heard some theory like caliculatong yaw, pitch and roll then using trig to factor out gravity. Not sure how that works. I've also heard about quartenions not sure what they are. If someone could help me out that would be great thx

# Answer
> 3 votes
Calculating velocity from acceleration is not easy. Simply put, velocity is derived by calculating the integral of acceleration with respect to time. In practice, however, this leads to accumulated errors which generally render the process impractical for any but the shortest amount of time.

For further reading, this Wikipedia Kinematics page does a good job at relating acceleration, velocity and position using math.

> … calculating yaw, pitch and roll then using trig to factor out gravity …

Essentially, this is the first of two steps in coding up a tilt compass (the type you find in your cell phone). You need the yaw, pitch and roll information before you can make sense of the magnetometer data. Consider reading the first half of a tilt compass description to understand how to calculate yaw, pitch and roll. Like this one.

> I've also heard about quartenions not sure what they are.

Quaternion are an alternative to using trigonometry to derive (in this case) yaw, pitch and roll. There are two advantages (in this case). First, Quaternions are easier for a computer to calculate. Second, Quaternion yaw, pitch and roll calculations do not go to infinity for certain situations. In the real world using physical gyroscopes this is commonly known as Gimbal lock.

Added later...

> How would i go about using trig?

Trigonometry is not necessary if it is physically arranged such that all acceleration to gain the velocity of interest occurs only in 1 of the X, Y or Z directions of the accelerometer. Then all that is need is to integrate the accelerometer readings in that direction with respect to time.

If this happens to be in the same direction as earth's gravity, simply subtract 9.8m/s2 out.

If you can't physically arrange it, then you need to read all 3 (X, Y & Z) accelerometer values. From this data pitch and roll can be calculated. The trigonometry equations for this is on page 21 of the "tilt compass description" link above.

That said we notice on that same page an equation to calculate the magnitude of acceleration.

So it may be possible that we can calculate the velocity due to the magnitude of the overall acceleration by sampling the accelerometer X,Y & Z sensors over time. And avoid trigonometry entirely.

However there is a problem. We have not accounted for gravity. Again, if we assume gravity is in the same direction as travel we can subtract it it out. But if travel is, say, 45 degrees off from the gravity vector, we would only want to subtract cos(45) * 9.8m/s2. Consider only knowing the overall acceleration magnitude does not supply enough information to determine the angle between the acceleration due to gravity and acceleration due to a change of velocity from zero to an unknown velocity with respect to earth.

At this point decisions need to be made regarding how to account for gravity. 9.8m/s2 may be trivial when compared to the vehicle's acceleration and therefor can be ignored. Or it may be so critical that extreme measures like tracking where the sun is in the sky become a feasible way to find the actual pitch and roll of the vehicle.

---
Tags: accelerometer
---


# Question
Title: Undefined reference to function in custom library
Hello I am making a private Arduino library but am having trouble understanding how it is linked. Why does this h file work, but when I move the definition of board\_led to a matching c file, it throws an error at compilation: `In function loop: undefined reference to board_led(bool)`.

I am using the following board manager to compile in the Arduino IDE: https://raw.githubusercontent.com/maximintegratedmicros/arduino-collateral/master/package\_maxim\_index.json

I am using the following board target: `MAXIM ARM 32bit boards > MAX32630FTHR`

```
#pragma once

#include "Arduino.h"
#include <stdbool.h>
#include <gpio.h>

extern const gpio_cfg_t s_board_led;

extern void board_led(bool on) {
     GPIO_OutPut( &s_board_led, on ? 0 : ~0 );
}

```

# Answer
> 5 votes
I suspect you're compiling from C++ code, and including that header.

When C++ links to C code, the C++ code needs to see `extern "C"` on the declaration, or surrounding the declaration (via `extern "C" { /* function declarations */ }`)

If you are compiling C++ code against the C code (and linking them together), try making sure `extern "C"` is used, for example like this:

```
// arduino_lib.h
#pragma once

#include "Arduino.h"
#include <stdbool.h>
#include <gpio.h>

extern const gpio_cfg_t s_board_led;

extern "C" void board_led(bool on);

```

While nothing changes in the .c file

```
// arduino_lib.c
#include "arduino_lib.h"

const gpio_cfg_t s_board_led = /* some value */;

void board_leb(bool on) {
     GPIO_OutPut( &s_board_led, on ? 0 : ~0 );
}

```

# Answer
> 3 votes
To complement Bob's answer it is good practice to add header guards for detecting C++ specifically:

```
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

// your function definitions here

#ifdef __cplusplus
}
#endif // __cplusplus

```

That way the `extern "C"` is only applied if the header file is included into a c++ file but not if it's included into a c file.

---
Tags: library, linker
---


# Question
Title: Ways to detect if a ball has reached the wall?
I'm building a kind of pin ball machine, and I need to detect when the ball has hit the wall with the sensor attached.

The ball will hit the wall with a small impact, not large enough to push a button probably. What sensor would be the best to use in this case?

I thought about ultrasonic but I'm not a fan of the constant chirping. Can a light sensor be used here? Eg if there's 10% light left, we assume the ball has reached the wall.

# Answer
> 3 votes
> The ball will hit the wall with a small impact...

Consider using the well proven pinball bumper design omitting the hammer feature:

In many pinball machines a "rubber ring" is stretched in front of one or more "leaf switches". When the ball hits the "rubber ring" one or more of the "leaf switches" closes (or opens depending on if the "leaf switch" is N.O. or N.C.). There are many example for connecting switches to an Arduino.

---
Tags: arduino-uno, hc-sr04
---


title: Which thermometer for home brewing

text:
# Question
Title: Which thermometer for home brewing
**Hello,**

I have an Arduino Yun and I brew beer.

I would like to log the temperature of the beer at all time during the fermentation process (final stage). This means the thermometer would have to remain in the beer during this time (10 days). The temperature would be \< 40 degrees Celsius (probably around the 20 degree mark).

**Question: What temperature sensor would be best suited to this task?**

It must be:

* Food grade
* Can be used in alcohol for extended periods
* Can be hooked up to Arduino (i.e. add a library and ready to go)

**Thanks, Dan.**

# Answer
> 1 votes
I am not a brewmaster but from what I understand the temperature will change slowly. Your problem is not to contaminate the beer, you can use a stainless possibly even a plastic tube that is sealed on the immersion side and use a DS1820B sensor commonly used on Arduinos as well as other platforms. The response will be slower then if the sensor is inserted directly but since the change is slow it should work AOK. This keeps it simple and probably something you have done before.

# Answer
> 0 votes
You are looking for a thermocouple.

They need some specific chip to be read, so you'll probably want to spend a bit more and get a chip with a digital interface, there are some witch has arduino library, like MAX6675 (output at 1Hz, 0.25° precision).

As this chip read "C type" thermocouple, you just have to find the right probe for your needing, with probably can be found in many specialized store.

You may even buy a normal k probe, and then wrap it up in some protective case. Obviously that case should be designed to let the heat flow easily, but without short circuiting the probe; a food plastic bag;

or just spend a little more money and buy a stainless steel probe

---
Tags: wifi, arduino-yun, temperature-sensor, datalogging
---


# Question
Title: Guru meditation error load prohibited, esp32s. While using Fastled
I am encountering a Guru meditation error, Load prohibited on my current sketch for the esp32s.

Here is the code:

```
#include <FastLED.h>

#define NUM_LEDS 120
#define LED_PIN 3
CRGB leds[NUM_LEDS];

int H1[12][10] = {
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
  {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
  {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
  {30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
  {40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
  {50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
  {60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
  {70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
  {80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
  {90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
  {100, 101, 102, 103, 104, 105, 106, 107, 108, 109},
  {110, 111, 112, 113, 114, 115, 116, 117, 118, 119}

};

int connections[7][6] = { // dont forget to change 7 to the number of hubs
  {2,3,4,5,6,7},
  {1,7,3,0,0,0},
  {1,2,4,0,0,0},
  {1,3,5,0,0,0},
  {1,4,6,0,0,0},
  {1,5,7,0,0,0},
  {1,2,6,0,0,0}
};

int const life = 3;
int numHubs = 7;

void setup() {
}

void loop() {
  path_taker(path_picker(numHubs, connections), H1);
  delay(500);
}

int* path_picker(int numHubs,int connections[7][6]){ // dont forget to change 7 to the number of hubs!
  int hub = random(1,numHubs)-1;
  int i = 1;
  int path[life];
  int a = 0;
  path[0] = hub;

  while (i <= life){
    a = connections[hub][random(0,6)];
    if (a != 0){
      path[i] = a;
      hub = a;

      i = i+1;
    }

  }
  return path;
}

void path_taker(int path[life], int H1[12][10]){
    int ini = 0;
    int fin = 0;
    int rod[10];
    for (int i = 0; i < sizeof(path) - 1; i++){
      ini = path[i];
      fin = path[i+1];
      switch (ini){
        case 1:
        switch (fin){
          case 2:
          lightup(arrayBuilder(0, H1, false));
          break;

          case 3:
          lightup(arrayBuilder(4, H1, false));
          break;

          case 4:
          lightup(arrayBuilder(3, H1, true));
          break;

          case 5:
          lightup(arrayBuilder(5, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(8, H1, true));
          break;

          case 7:
          lightup(arrayBuilder(9, H1, false));
          break;
        }
        break;

        case 2:
        switch (fin){
          case 1:
          lightup(arrayBuilder(0, H1, true));
          break;

          case 3:
          lightup(arrayBuilder(1, H1, false));
          break;

          case 7:
          lightup(arrayBuilder(11, H1, true));
          break;
        }
        break;

        case 3:
        switch (fin){
          case 1:
          lightup(arrayBuilder(4, H1, true));
          break;

          case 2:
          lightup(arrayBuilder(1, H1, true));
          break;

          case 4:
          lightup(arrayBuilder(2, H1, false));
          break;
        }
        break;

        case 4:
        switch (fin){
          case 1:
          lightup(arrayBuilder(3, H1, false));
          break;

          case 3:
          lightup(arrayBuilder(2, H1, true));
          break;

          case 5:
          lightup(arrayBuilder(6, H1, true));
          break;
        }
        break;

        case 5:
        switch (fin){
          case 1:
          lightup(arrayBuilder(5, H1, true));
          break;

          case 4:
          lightup(arrayBuilder(6, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(7, H1, false));
          break;
        }
        break;

        case 6:
        switch (fin){
          case 1:
          lightup(arrayBuilder(8, H1, false));
          break;

          case 5:
          lightup(arrayBuilder(7, H1, true));
          break;

          case 7:
          lightup(arrayBuilder(10, H1, true));
          break;
        }
        break;

        case 7:
        switch (fin){
          case 1:
          lightup(arrayBuilder(9, H1, true));
          break;

          case 2:
          lightup(arrayBuilder(11, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(10, H1, false));
          break;
        }
        break;
      }
    }
  }

int* arrayBuilder(int row, int hexigon[12][10], bool reverse){
  int rod[10];
  if (reverse){
    for (int i=9; i>=0;i--){
      rod[i] = hexigon[row][i];
    }
  }else{
    for (int i=0; i<10;i++){
      rod[i] = hexigon[row][i];
    }
  }
  return rod;
}

void lightup(int rod[10]){
  int i = 0;
  while (i<10){
    EVERY_N_MILLISECONDS(50){
      leds[rod[i]] = leds[i] = CHSV(255, 255, 255);
      fadeToBlackBy( leds, NUM_LEDS, 10);
    }
  }

  FastLED.show();
}

```

Here is the decoded exception from Exception Decoder:

```
 EXCVADDR: 0x00000000 Decoding stack results 0x400d0cc7:
path_taker(int*, int (*) [10]) at C:\Users\****\Documents\Arduino\Wall_Art_MKI/Wall_Art_MKI.ino line 75

0x400d0d3e: loop() at C:\Users\****\Documents\Arduino\Wall_Art_MKI/Wall_Art_MKI.ino line 44

0x400d1315: loopTask(void*) at C:\Users\*****\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.6\cores\esp32\main.cpp line 23

0x40085d81: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

```

I posted this on Reddit, and a user suggested that the error was occuring on line 201. The issue being that I am attempting to return a pointer to a local variable within the function, arrayBuilder.

I have been doing research on the topic, but I still can't figure out how to resolve the error.

I would greatly appreciate any advice!

# Answer
Instead of trying to return a pointer to a local variable (which is always doomed to fail, since you end up with a pointer to rubbish) you should create your array outside the function and pass a pointer to it as a parameter, then fill that array through the pointer:

```
void arrayBuilder(int row, int hexigon[12][10], bool reverse, int *rod){
  if (reverse){
    for (int i=9; i>=0;i--){
      rod[i] = hexigon[row][i];
    }
  }else{
    for (int i=0; i<10;i++){
      rod[i] = hexigon[row][i];
    }
  }
}

```

Then...

```
int rod[10];
arrayBuilder(rownum, myhex, false, rod);

```
> 0 votes

---
Tags: esp32
---


# Question
Title: arduino suddenly shows “avrdude: ser_open(): can't open device ”\\.\COM3" after last upload
I am using arduino uno to make a sound detector. I uploaded a program, found error in the code that it returns unintended numbers unreasonably big. I also think I used wrong code for the module, but it was connected in the way that can work properly with the proper code.

The code I uploaded was:

```
const int ledPin =13;
const int middleValue = 512;
const int numberOfSamples =128;

int sample;
long signal;
long averageReading;

long runningAverage = 0;
const int averagedOver = 16;

const int threshold=400;

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

void loop(){
    long sumOfSquares = 0;
    for (int i=0; i<numberOfSamples; i++){
        sample = analogRead(0);
        signal = (sample - middleValue);
        signal *= signal;
        sumOfSquares += signal;
    }
    averageReading = sumOfSquares/numberOfSamples;
    runningAverage=(((averagedOver -1 )*runningAverage)+averageReading)/averagedOver;

    if(runningAverage>threshold){
        digitalWrite(ledPin, HIGH);
    }else{
        digitalWrite(ledPin, LOW);
    }
    Serial.println(runningAverage);
}

```

When the arduino suddenly stopped sending serial numbers, I pressed reset button and uploaded the default code:

```
void setup() {
}

void loop() {
}

```

but now it shows that it cannot connect to COM3 (arduino) and cant find the device, When I can see arduino uno successfully connected to PC using device manager (windows 8.1). The led light of arduino also turns on when I connect it to power source or usb.

it shows "port not found" when I click to see the serial output

Did I just fry Arduino? How should I fix this?

Also, i checked the led pin 13 blinking three times when i plug in the usb. I just cant upload anything

# Answer
I ran into such a problem when I was accessing my Arduino board from two different windows applications like Arduino IDE and eclipse. or Eclipse and some serial monitor windows application. Make sure you close any application that programs or communicates with the Arduino board, and make sure you configure the COM you are using in Arduino IDE and try again. Also try disconnecting any wire that is connected to RX and TX pins when you are programming the Arduino.
> 1 votes

# Answer
You might have your serial monitor open at COM3 somewhere which is why AVRdude is failing to open the port again. Make sure the serial monitor is closed.

if you are opening serial ports on Python or your own developed applications, you have to explicitly close the port on exiting the program, otherwise, the port remains open and you come across such errors.
> 1 votes

# Answer
my arduino revived the next day.... don't know why but it works!
> 0 votes

---
Tags: arduino-uno, serial, sensors
---


# Question
Title: Wired Teensy 3.5 AudioShield and RFID RC-522
I received a set of wired Teensy 3.5 AudioShield and RFID RC-522. The audio shield is mounted on the Teensy but I cannot connect the MFRC522 Using MFR222 library. Pins are set to 0 and 31:

```
#define RST_PIN         0          // Configurable, see typical pin layout above
#define SS_PIN          31         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

```

Getting:

```
Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
Scan PICC to see UID, SAK, type, and data blocks..

```

Tried any other combination I can think of. Checked all soldered points. I did not find any guide on how to connect teensy 3.5 with RC522. only older versions. Do I need to tell the library where to find the other pins (MISO, MOSI...) Any help will be appreciated. Thanks Yehuda

# Answer
> -1 votes
The answer is (as far as I understand) that when both audio shield and rfid are mounted, they have protocol collision (same protocol for both). So if you want them to work. You need to wire rfid to different pins.

---
Tags: rfid, teensy
---


# Question
Title: Different meanings of pid and vid in boards.txt
Let's see the `leonardo` section in `boards.txt`:

```
leonardo.name=Arduino Leonardo
leonardo.vid.0=0x2341
leonardo.pid.0=0x0036
leonardo.vid.1=0x2341
leonardo.pid.1=0x8036
leonardo.vid.2=0x2A03
leonardo.pid.2=0x0036
leonardo.vid.3=0x2A03
leonardo.pid.3=0x8036

leonardo.upload.tool=avrdude
leonardo.upload.protocol=avr109
leonardo.upload.maximum_size=28672
leonardo.upload.maximum_data_size=2560
leonardo.upload.speed=57600
leonardo.upload.disable_flushing=true
leonardo.upload.use_1200bps_touch=true
leonardo.upload.wait_for_upload_port=true

leonardo.bootloader.tool=avrdude
leonardo.bootloader.low_fuses=0xff
leonardo.bootloader.high_fuses=0xd8
leonardo.bootloader.extended_fuses=0xcb
leonardo.bootloader.file=caterina/Caterina-Leonardo.hex
leonardo.bootloader.unlock_bits=0x3F
leonardo.bootloader.lock_bits=0x2F

leonardo.build.mcu=atmega32u4
leonardo.build.f_cpu=16000000L
leonardo.build.vid=0x2341
leonardo.build.pid=0x8036
leonardo.build.usb_product="Arduino Leonardo"
leonardo.build.board=AVR_LEONARDO
leonardo.build.core=arduino
leonardo.build.variant=leonardo
leonardo.build.extra_flags={build.usb_flags}

```

What are the meanings of the `leonardo.vid|pid.*` and of the `leonardo.build.vid|pid`? Perhaps the first are for the USB serial device at runtime and the second for the bootloader?

# Answer
The build ones are used when compiling the Arduino core. The others are used to identify the board when it resets into the bootloader so it can find the right com port to upload to
> 1 votes

---
Tags: usb, arduino-leonardo, board
---


title: NeoPixel Ring Usage Without Arduino

text:
# Question
Title: NeoPixel Ring Usage Without Arduino
I am looking at purchasing a NeoPixel Ring for a project, but need it to work without an Arduino. Once the NeoPixel has been programmed by the Arduino, will it function when powered without the Arduino? I am not looking at changing colors or anything, I want to set the LEDs to solid red and not change.

I have found in the Adafruit website that it says "NeoPixels don’t just light up on their own; they require a microcontroller (such as Arduino) and some programming." But is this only to get them working initially, or do they require an microcontroller permanently?

# Answer
> 1 votes
No, the settings for the colors are stored in RAM on the individual devices so they need to be reprogrammed every time they are powered on.

On the other hand, it is possible to use a much smaller device such as a surface-mount ATtiny85 to program them, and light\_ws2812 runs on said device just fine. And once they have been programmed it is possible to put the MCU in deep sleep so that it consumes almost no power.

# Answer
> 1 votes
I recently completed a project using one of these LED rings. I knew these were normally used with an arduino for control, but at the time I was still testing things, so I decided to buy one and mess with it.

I soldered a standard 3-pin ARGB cable to the 5v, GRN, and Data In to the ring and connected it to one of the argb headers on my PC. The results were as follows:

1. The ring did light up and stayed illuminated with the PC.
2. The ARGB header was connected to a splitter which came from a ASUS motherboard header.
3. Armoury Crate (ASUS’s argb software) was already set up on my computer and this software was what was sending signal to the ring via a splitter.
4. There were SOME LEDs on the ring that behaved as expected based on the colors and pattern set up in Armoury Crate. However, some LEDs although we’re illuminated, we’re flashing various colors that didn’t match to how it was set up in Armoury Crate.

Take aways: These NeoPixel rings DO work without an arduino in terms in terms of receiving voltage and lighting up. However, because of how these are programmed they may not behave as expected or intended if connected to a non-arduino controller.

For my application, the multi-color pattern ended up looking nice, so I decided to keep it as is.

---
Tags: led, adafruit, neopixel
---


title: Do passive buzzers require a PWM pin?

text:
# Question
Title: Do passive buzzers require a PWM pin?
This guide Shows how to wire a passive buzzer to be used with tone(). I notice they have it wired to D9, which is a PWM pin. But is it required to use a PWM capable digital output pin to play tones from a passive buzzer?

# Answer
No, it doesn't need to be a PWM pin. `tone()` uses a timer and an interrupt to generate the audio signal and can work with any IO pin.
> 2 votes

---
Tags: buzzer
---


title: Milliseconds using square wave RTC

text:
# Question
Title: Milliseconds using square wave RTC
i am trying to make a code that prints the time hh:mm:ss:ms using RTC,i have made it using millis() but it is not accurate +/-2 milliseconds

ho can i make it using sq wave and intterupt

here is the code that i have used

```
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;      // This is the DS1307 hardware RTC
RTC_Millis SoftRTC;   // This is the millis()-based software RTC
long startMS;  // This will hold the start time in milliseconds

void setup ()
{
    Wire.begin();
    RTC.begin();                       // Connect to the DS1307
    SoftRTC.begin(RTC.now());  // Initialize SoftRTC to the current time
    startMS = millis();  // get the current millisecond count
}

void loop()
{
    DateTime now = SoftRTC.now();
    long nowMS = millis();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.print(':');
    Serial.print((nowMS - startMS)%1000, DEC);  // print milliseconds
    Serial.println();

```

i tried to put this code that is based on ISR but with no luck

```
volatile time_t isrUTC;         // ISR's copy of current time in UTC
volatile time_t millisecondsFromISR;         // ISR's copy of current time millisecond offset

void incrementTime()
{
    millisecondsFromISR = millis();  //do first to get most accuracy
    ++isrUTC;
}

int getMilliseconds() {
    // need to make an atomic copy:
    nointerrupts();
    unsigned long t = millisecondsFromISR;
    interrupts();

    return millis() - t;
}

```

# Answer
> 1 votes
All you have to do is record the number of milliseconds at the moment the square wave toggles on its 1 second cycle. Then your milliseconds is the difference between that and the current.

In short: update `startMS` when triggered by the RTC's output.

---
Tags: rtc, millis
---


# Question
Title: Problems in running two solenoid together at the same time
I am trying to activate two solenoids (12V/350mA, connected to a 12V/1A adaptor) at the same time using the TIP120 NPN-transistor and 1kohm resistor using the UNO board. Using a simple program,

```
void loop()
{
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(5000);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(2000);
}

```

if I am using a big LED on the pin of the board, I am able to easily blink them but the solenoid is not working?

for powering the Arduino board, I am either using USB or a 12V/1A adaptor, and both result in the same output.

the schematic of the simple connections can be found here https://www.arrow.com/en/research-and-events/articles/arduino-solenoid-project-control-solenoid-with-arduino-board

can someone please suggest what can I do to start two solenoids at the same time?

I have tried increasing the voltage and current as well from an externally powered source as well. but it did not actuated two valves together

# Answer
> 0 votes
It will not work as you have it pictured. The ground of the 12V must be connected to the ground of the Arduino. You can put both resistors on the same pin of the Arduino, the one that is working (probably pin 13). Staying with what you have coded would be better. Since each of the solenoids require 1A each your power supply must supply at least 2 amps.

In your code setup() you need to define each pin you will use as an output, (int ledPin = 4; int ledPin = 5;) There are other ways but that follows the example. then use the pinmode to declare them as an output, pinMode(led1, OUTPUT); for each pin you want to drive the transistor. Then your code will work. Look at this link for an example: https://www.arduino.cc/en/Reference.digitalWrite. I used pins 4 and 5, no reason other then 13 blinks with the on board led when it is booting. It is pre defined as an output in the Arduino start code (you normally do not have access to that), that is why it worked.

If you elect to use a MOSFET TheSource becomes the emitter, The Drain becomes the collector and the gate becomes the gate. You would need to pick an avalanche rated one that can

---
Tags: arduino-uno, transistor
---


# Question
Title: Choosing Right Power Supply for Arduino - ESP8266 - HC-SR04
If I make connections like you see in picture below, will it work? Will I damage ESP or HC-SR04?

As I know;

HC-SR04 (VCC) -\> 5V

ESP8266 (VCC) -\> 3.6V

ESP8266 (RX/TX) -\> has 5V tolerance ?

I have not taken into account the currents that will each pin draw. So, is everything OK?

I'm not good at this stuff, so I'll appreciate it if you guys give me advice

Image

Most of you suggest to use voltage regulator instead of external AA batteries. However, I have already ordered one but it takes too much time (nearly week) to get, due to delivery-shipping issues. So, I want to work on the coding part of my project.

# Answer
1. GND seems dangling.
2. If you are going to use multiple power sources, make sure that all the minus/GND are connected together.
3. Whether the ESP8266 can use 5V or not should be checked against the actual unit you have. There are many variants and some might be more tolerant than others.
4. You do not show the power source for 5V - what is it?
5. By just typing on google HC-SR04 5V, you get a link to the manual, which has a section "4.0 PRODUCT SPECIFICATION AND LIMITATIONS": Min:4.5V Typ:5V Max:5.5V. You should at least give it a try and report your findings, asking for clarifications, if you need any, rather than just ask here for something that google can provide.
> 1 votes

# Answer
When you get the wiring sorted out, remove the batteries and plug in the USB, that should power it up and allow you to start writing your code.
> 1 votes

---
Tags: arduino-uno, voltage-level, esp8266
---


title: Real Time clock module error-DS3231

text:
# Question
Title: Real Time clock module error-DS3231
This is not a code error I have been using DS3231 RTC module with battery. When I bought this module It worked perfectly now when I get it to use, The time is running perfectly. when I set the current time of my location, it has been running along with that time but the problem is when I unplug the power of my Arduino Nano and again when I give the power I can see the time is running from its start, I could not see any current time value my location but I have attached CR2032 battery along with DS3231 module? what is the problem with this? I changed another battery too but It shows same problem my DS32321 haven't kept the time when I unplug and re-plug the power

This is the code I'm using for set the time

```
#include <DS3231.h>

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(115200);
  // Uncomment the next line if you are using an Arduino Leonardo
  //while (!Serial) {}

  // Initialize the rtc object
  rtc.begin();

  // The following lines can be uncommented to set the date and time
  rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");

  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());

  // Wait one second before repeating :)
  delay (1000);
}

```

This is the code I'm using to make Interrupt

```
 #include <DS3231.h>

int Relay = 4;

DS3231  rtc(SDA, SCL);
Time t;

const int OnHour = 21;
const int OnMin = 46;
const int OffHour = 21;
const int OffMin = 48;

const int On2Hour = 14;
const int On2Min = 54;
const int Off2Hour = 21;
const int Off2Min = 48;

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

void loop() {
  Serial.println("Time:  ");
  Serial.print(rtc.getTimeStr());
  Serial.print('\n');

  Serial.println("Date: ");
  Serial.print(rtc.getDateStr());
  Serial.print('\n');

  t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);
  //can be set lcd display alspo
  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

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

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

```

# Answer
I am posting a code please try it may be it can help you

```
    #include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

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

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
     rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
    DateTime now = rtc.now();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");

    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));

    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();

    Serial.print("Temperature: ");
    Serial.print(rtc.getTemperature());
    Serial.println(" C");

    Serial.println();
    delay(3000);
}

```

Upload the above code and then upload the same code just comment the following part

```
if (rtc.lostPower()) {
        Serial.println("RTC lost power, let's set the time!");
        // When time needs to be set on a new device, or after a power loss, the
        // following line sets the RTC to the date & time this sketch was compiled
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        // This line sets the RTC with an explicit date & time, for example to set
        // January 21, 2014 at 3am you would call:
         rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
      }

```

This will work and even if you plug and unplug it from power the RTC time will not reset
> 1 votes

# Answer
I will take a SWAG as I do not know what module you are having problems. Remove the battery, power it up and measure the voltage at the battery terminals. If you have about 3.2V the module is designed to charge the battery (thought you might like to know). Power down the module insert the battery, do not power it up, and measure the battery voltage at the chip. Be sure to also check the ground side. I believe you will find the same thing I did, the solder connection to the battery holder was open, just added some solder and that solved it. I also found the SCL line was broken on the board so if I connected the other side it would not work. I added a jumper to fix it. I purchased several from azon but only the first one was bad.
> 1 votes

---
Tags: arduino-uno, arduino-nano, hardware, rtc, ds3231-alarms
---


# Question
Title: esp8266 + octocoupler relay: WDT reset when using AC current
I'm trying to switch on bulb via 4 channel 5V optocoupler relay controller from ESP8266 using WIFI Access point. All my connections looking fine and i can able to connect WIFI SoftAP and send signal to ESP8266 01. Even i can able to switch the Relay from NO to NC or other way around. Only when a connect 240V AC current to relay for powering the bulb, i'm getting following error from ESP

```
21:11:34.312 ->  ets Jan  8 2013,rst cause:4, boot mode:(1,7)
21:11:34.312 ->
21:11:34.312 -> wdt reset

```

If i use 12V DC power to light the led via relay its working fine. if again use 240V power to relay to light bulb i'm get same error again.

I have already tried using ceramic capacitor for decoupling to avoid noise from AC. Still no luck. Please advice. I'm very new and naive at handling electronics.

Adding the circuit as well.

Update: After further testing, I can see following behaviour, If i connect AC bulb to relay and turn it on. Then by provide a long gap before turning it off makes the ESP stable for longer time.

Even better, if i turn off/on my mobile wifi between each time i turn on or off the AC bulb then ESP is always stable.

Adding my code as well.

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

/* Set these to your desired credentials. */
const char *ssid = "*****";
const char *password = "*********";

ESP8266WebServer server(80);

const int led = 2;  //GPIO2

/* Just a little test message.  Go to http://192.168.4.1 in a web browser
 * connected to this access point to see it.
 */
void handleRoot() {

  int size=1000;
  char temp[size];

  int sec = millis() / 1000;
  int min = sec / 60;
  int hr = min / 60;

  snprintf ( temp, size,

"<body>\
    <p>Status: Light ON</h1></p>\
    <p><a href=\"http://192.168.4.1/on\"><h1>Turn ON</h1></a></p>\
    <p></p>\
    <p><a href=\"http://192.168.4.1/off\"><h1>Turn OFF</h1></a></p>\
  </body>\
  ",

    hr, min % 60, sec % 60
  );
  server.send ( 200, "text/html", temp );

}

void setup() {
    delay(1000);
    Serial.begin(115200);
    Serial.println();
    Serial.print("Configuring access point...");

    /* You can remove the password parameter if you want the AP to be open. */
    WiFi.softAP(ssid, password);

    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);

  pinMode(led, OUTPUT);
  digitalWrite ( led, HIGH );

  //URLs available to query
    server.on("/", handleRoot);
  server.on ( "/on", turnON );
  server.on ( "/off", turnOFF );
    server.begin();
    Serial.println("HTTP server started");

}

void turnON(){

  digitalWrite ( led, HIGH );

  int size=1000;
  char temp[size];

  int sec = millis() / 1000;
  int min = sec / 60;
  int hr = min / 60;

  snprintf ( temp, size,

"<body><p><a href=\"http://192.168.4.1/off\"><h1>Turn OFF</h1></a></p></body>",

    hr, min % 60, sec % 60
  );

  server.send ( 200, "text/html", temp);

}

void turnOFF(){

  digitalWrite ( led, LOW );

  int size=1000;
  char temp[size];

  int sec = millis() / 1000;
  int min = sec / 60;
  int hr = min / 60;

  snprintf ( temp, size,

"<body><p><a href=\"http://192.168.4.1/on\"><h1>Turn ON</h1></a></p></body>",

    hr, min % 60, sec % 60
  );

  server.send ( 200, "text/html", temp);

}

void loop() {
    server.handleClient();
}

```

# Answer
> 0 votes
Before running to dark magic of EMI problems - let's try isolate all our parameters that can cause or affect (and perhaps is is not only one):

1. make a **test code** as simple as possible for switching a relay periodically on/off. At start make a 5 second delay between changing states, and down to 500 millis- This way you check both EMI interference and power issues inside you circuit (sometimes the relay consumes power more that the MCU can give, and that can cause resets. Problem can be MCU's power issue or Relay, mechanical or electrical issues).
2. **Components** \- try to replace with others, especially MCUs, and relays, to make sure it is not a malfunctioned or degraded components. For example - a Wemos mini with is Relay shield can easily isolate any "EMI"- related issue.
3. From you diagram (and in contrast to your question's title) - an Uno is used for switching ? and not the ESP-01' right? did you make sure that the relay's vcc is correct for its MCU? (you said 5v relay, which is not correct for ESP8266).
4. **Load** \- make sure to choose a simple resistive load (AC light bulb), rather that an AC motor (which cause a massive EMI interference).
5. **EMI** \- if all above did not help (I doubt) or it solved for that "bulb case" only, EMI affect are distance related. Try to use a long AC wires that will take you MCUs and relay far from that source. 1m will be enough.

To sum up, I will be very surprised to know that it is EMI (and I dealt with AC motors with WEMOS and a dual relay module successfully).

Please update.

Guy

---
Tags: arduino-uno, esp8266, relay
---


title: Simple ESP32 MCP2515 CAN code to VP230

text:
# Question
Title: Simple ESP32 MCP2515 CAN code to VP230
I have a working code that uses MCP2515 CAN module. Wanted to minimize the size of required modules, so I went with VP230 CAN transceiver and I'm having trouble relaying the same data through different libraries. All it has to do is log in with the first ''payload1'' and send voltage instruction with ''setdefaultvolt''. Any help is greatly appreciated.

**MCP2515** code:

```
#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include <SPI.h>
#include <Wire.h>

//pins:
#define CAN_INT 17                                                                         // Set INT to pin 2
MCP_CAN CAN(5);                                                                         // Set CS to pin 4 (D2)

void setup()
{
  Serial.begin(115200);
  delay(100);
  pinMode(17, INPUT);                                                                       //Setting pin 2 for /INT input

START_INIT:
  if(CAN_OK == CAN.begin(MCP_ANY, CAN_125KBPS, MCP_8MHZ))
  {
  }
  else
  {
    delay(100);
    goto START_INIT;
  }
  CAN.setMode(MCP_NORMAL);                                                        //set operation mode to normal so the MCP2515 sends acks to received data.
  unsigned char payload1[8] = {0x16, 0x50, 0x71, 0x07, 0x97, 0x089, 0x00, 0x00};  //login data with serial number
  CAN.sendMsgBuf(0x05004804, 1, 8, payload1);                                     //send login data

  unsigned char setdefaultvolt[5] = {0x29, 0x15, 0x00, 0xFE, 0x10};              //this is the command for setting the default output voltage (Last two bytes, LSB first). 16 80 is the maximum voltage of 57.6 V
  CAN.sendMsgBuf(0x05019C00, 1, 5, setdefaultvolt);                              //send setup data
}

void loop()
{
}

```

**VP230** code:

```
#include <CAN_config.h>
#include <ESP32CAN.h>

CAN_device_t CAN_cfg;

#include <SPI.h>
#include <Wire.h>

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

  CAN_cfg.speed=CAN_SPEED_1000KBPS;
  CAN_cfg.tx_pin_id = GPIO_NUM_19;
  CAN_cfg.rx_pin_id = GPIO_NUM_23;

  CAN_frame_t my_frame;
  CAN_frame_t my_frame2;

  ESP32Can.CANInit();

  my_frame.FIR.B.FF = CAN_frame_ext;
  my_frame.MsgID = 0x05004804;
  my_frame.FIR.B.DLC = 8;

  my_frame.data = {0x16, 0x50, 0x71, 0x07, 0x97, 0x089, 0x00, 0x00};

  ESP32Can.CANWriteFrame(&my_frame);

  my_frame.FIR.B.FF = CAN_frame_ext;
  my_frame.MsgID = 0x05019C00;
  my_frame.FIR.B.DLC = 5;

  my_frame2.data = {0x29, 0x15, 0x00, 0xFE, 0x10};

  ESP32Can.CANWriteFrame(&my_frame2);

}

void loop()
{
}

```

# Answer
> 3 votes
Just spotted this, but if any one else finds it: You have one CAN speed set to 125kb on MCP2515 the other to 100kb on the VP230.

That's why you won't get anything!

Mark

# Answer
> 1 votes
from datasheet ...CAN controller at speeds up to 1 Mbps.

On the SN65HVD230 and SN65HVD231, pin 8 provides three different modes of operation: high-speed, slope control, and low-power modes. The high-speed mode of operation is selected by connecting pin 8 to ground, allowing the transmitter output transistors to switch on and off as fast as possible with no limitation on the rise and fall slopes.

---
Tags: esp32, can-bus
---


title: `time.h` vs `TimeLib.h` on AVR boards

text:
# Question
Title: `time.h` vs `TimeLib.h` on AVR boards
Why do I get wrong result when using `time.h` library when using AVR boards, such Nano/Uno/Pro Micro (while when using `TimeLib.h`).

OUTPUT (for given Epoch ):

`TimeLib`: 2022-04-02 16:11:20

`time.h`: 0152-03-01 16:11:20

CODE:

```
#define CASE 1

#if CASE == 1
#include <time.h>
#elif CASE == 2
#include <TimeLib.h>
#endif

time_t bootTime = 1648915880;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("\nStart!");
  delay(1000);

  char clk2[40];

#if CASE == 1
  struct tm *tm = localtime(&bootTime);
  sprintf(clk2, "%04d-%02d-%02d %02d:%02d:%02d", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);

#elif CASE == 2
  sprintf(clk2, "%04d-%02d-%02d %02d:%02d:%02d", year(bootTime), month(bootTime), day(bootTime), hour(bootTime), minute(bootTime), second(bootTime));
#endif
  Serial.println(clk2);
}

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

```

# Answer
> 2 votes
You are assuming the avr-libc "epoch" is the same as the UNIX "epoch". It isn't. According to the manual:

> Though not specified in the standard, it is often expected that time\_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. **This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000.** The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX\_OFFSET and NTP\_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.

So you need to subtract the `UNIX_OFFSET` from your time value before passing it to any avr-libc functions.

Also you should initialize the time system with `set_zone()` and similar functions.

---
Tags: time
---