title: Can't sync with programmer Arduino Uno

text:
# Question
Title: Can't sync with programmer Arduino Uno
I have a weird problem, and it's probably because I'm doing something wrong. I'm quite new to Arduino.

My Uno R3 (Elegoo) has been working fine for a month. It has been sitting on a bench for the past week, unused though. Last night I tried to push a sketch from the IDE: v1.8.14 on Windows 10 Pro (fully updated), board: Arduino Uno, Com port 5. I got this error:

```
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xe6

```

So, I googled it and tried to fix it. No luck. And, the code changes frequently (right now it's 0x3a). So, I tried

* Using the blink sketch
* Rebooting my laptop
* Using a different USB port
* Using a different USB cable
* Using different settings in the IDE (Mega 2560 with the ATMega2560 processor)
* Using a different operating system (Ubuntu) on a different laptop with a different version of the IDE (1.8.13)
* Using a different Arduino (A Freenove Uno r3 from a robot kit)

Using a different board on windows does work! So, my original board is bricked maybe?

I got the same result, more or less. The only difference was that the response code changed. On Ubuntu, the response code is always 0x00 so I suspect the changing code is down to some problem in windows (I trust Linux a lot more than windows). I used the default blink sketch for all these attempts.

Note: I do have a green 'on' led and the L is orange and does the 3xflash on powerup and reset. This is the only USB port in use, so there's only one to choose in the IDE (happens to be com5) and it's clearly shown as Arduino. When I push the sketch, the orange L led stays solid orange and there is no flashing of the rx or tx leds.

Update: I have read, with interest: Have I bricked my Arduino Uno? Problems with uploading to board

Because of this I have now checked the power rail with a multimeter and found 5v and 3.3v respectively on USB, and with a 9v battery I have 3.3v and 7.8v respectively. The L led flashes 3 times as expected on power up and reset.

Also, I have nothing attached to the board at all.

When I tried the loopback test the board would not power-on with reset connected to ground, so I don't know how to proceed with that.

I have just tried the Atmega16U2 chip test, and it failed. I'm pretty sure the wiring is correct (though it's hard to tell -- I can't find a dot indicating pin 1 on the good board so I'm guessing it's close to the 'n' in 'on' as mentioned in the post).

How could I have damaged this? What could I have possibly done to break that? I was only driving leds.

# Answer
Sometimes boards can glitch depending on wear and tear or on how well they have been manufactured. Personally I always buy boards direct from the Arduino store and I have never had this issue. One thing that could help is placing a 0.1 uF capacitor between the +5V pin and ground and another between AVcc and ground. There will be some on the PCB already but this can help in some cases. Another thing that can help is pressing the reset buttom just after pressing upload on your PC.

Unfortunately, when out of sync errors occur it can be heavily luck based as to what works and how long it takes. Hopefully one of these tricks will work! But like you say, if other boards are working fine then it could just be bricked
> 1 votes

# Answer
A few things to make sure:

* Disconnect your Arduino from any sensor or module
* Closely look at the Arduino to see any signs of worn-out solder or damage
* Make sure that the programming USB cable is plugged in all the way on the Arduino and the computer
* Check the temperature of the ATMEGA chip, as well as, the voltage regulator

If everything looks normal there, you can try reflashing the bootloader on it. You can only do this if you have another Arduino Uno. Here is a good guide: https://www.instructables.com/How-to-Upload-Bootloader-to-Any-Arduino-/. Try that and then comment on what worked and what did not.
> 0 votes

---
Tags: arduino-uno, avrdude, programmer, error
---


# Question
Title: Compiling Assembly Script in External EEPROM to Arduino Code
I'm working on a simple game console, and I'm planning to use a cartridge system using an EEPROM. I know that you can read and write data from an EEPROM, but can you compile the data into executable Arduino code, and vice versa? If the Arduino can do it, we can probably too, right?

Thanks in advance!

# Answer
> 1 votes
I would suggest you investigate a different micro with external addressing or one that loads its code from an external memory such as flash like the ESP32s do.

---
Tags: arduino-nano, eeprom
---


title: Driving 5V relay with ESP-01

text:
# Question
Title: Driving 5V relay with ESP-01
I'm trying to drive a **5V relay** with **3.3V ESP-01** with schematic below. I programmed the ESP to start a portal through which I can derive the relay by triggering **GPIO-0** & **GPIO-2**. However when I power on the circuit I encounter the following scenarios:

1. IF wire is plugged in to **GPIO-2**

* **ESP blue led** turned on forever
* **Relay** started buzzing sound forever
* No WIFI network appears thus not working

2. IF wire is plugged in to **GPIO-0**

* No WIFI network appears thus not working

3. IF I only plug the wire after powering on the circuit then it works just fine as intended.

Would you please explain what is happening and how to fix it

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

const byte DNS_PORT = 53;
IPAddress apIP(172, 217, 28, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);

//int ledPin = 2;
#define ledPin0 0
#define ledPin2 2

int ledStatus0;
int ledStatus2;

void setup() {
//  Serial.begin(9600);         // Start the Serial communication to send messages to the computer
//  delay(10);
//  Serial.println('\n');

  pinMode(ledPin0, OUTPUT);  ledStatus0 = digitalRead(ledPin0);  digitalWrite(ledPin0, HIGH); ledStatus0 = 1;
  pinMode(ledPin2, OUTPUT);  ledStatus2 = digitalRead(ledPin2);  digitalWrite(ledPin2, HIGH); ledStatus2 = 1;

  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("Toggle Portal");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  // replay to all requests with same HTML
  webServer.onNotFound([]() {

    if (webServer.hasArg("led0")) {
      String status = webServer.arg("led0");
      if (status == "off") { digitalWrite(ledPin0, LOW); ledStatus0 = 1;  switchRelayOff(); }
      else if (status == "on") { digitalWrite(ledPin0, HIGH); ledStatus0 = 0; switchRelayOn(); }
    }
    if (webServer.hasArg("led2")) {
      String status = webServer.arg("led2");
      if (status == "off") { digitalWrite(ledPin2, LOW); ledStatus2 = 1;  switchRelayOff(); }
      else if (status == "on") { digitalWrite(ledPin2, HIGH); ledStatus2 = 0; switchRelayOn(); }
    }

    String content = "<!DOCTYPE HTML>";
    content += "<html>";
    content += "<head>";
    content += "  <title>ESP Web Server</title>";
    content += "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
    content += "  <link rel=\"icon\" href=\"data:,\">";
    content += "  <style>";
    content += "    html {font-family: Arial; display: inline-block; text-align: center;}";
    content += "    h2 {font-size: 3.0rem;}";
    content += "    p {font-size: 3.0rem;}";
    content += "    body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}";
    content += "    .switch {position: relative; display: inline-block; width: 120px; height: 68px} ";
    content += "    .switch input {display: none}";
    content += "    .slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 6px}";
    content += "    .slider:before {position: absolute; content: \"\"; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 3px}";
    content += "    input:checked+.slider {background-color: #1f9f1b}";
    content += "    input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}";
    content += "  </style>";
    content += "</head>";
    content += "<body>";
    content += "  <h2>ESP Web Server</h2>";

    content += "  <h4>Output - GPIO 0</h4>";
    if ( ledStatus0 == 0 ) {      content += "  <label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"0\" ><span class=\"slider\"></span></label>";
    } else {      content += "  <label class=\"switch\"><input type=\"checkbox\" checked onchange=\"toggleCheckbox(this)\" id=\"0\" ><span class=\"slider\"></span></label>";    }

    content += "  <h4>Output - GPIO 2</h4>";
    if ( ledStatus2 == 0 ) {      content += "  <label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox2(this)\" id=\"2\" ><span class=\"slider\"></span></label>";
    } else {      content += "  <label class=\"switch\"><input type=\"checkbox\" checked onchange=\"toggleCheckbox2(this)\" id=\"2\" ><span class=\"slider\"></span></label>";    }

    content += "<script>function toggleCheckbox(element) {";
    content += "  var xhr = new XMLHttpRequest();";
    content += "  if(element.checked){ xhr.open(\"GET\", \"?led0=on\", true); }";
    content += "  else { xhr.open(\"GET\", \"?led0=off\", true); }";
    content += "  xhr.send();";
    content += "}";

    content += "function toggleCheckbox2(element) {";
    content += "  var xhr = new XMLHttpRequest();";
    content += "  if(element.checked){ xhr.open(\"GET\", \"?led2=on\", true); }";
    content += "  else { xhr.open(\"GET\", \"?led2=off\", true); }";
    content += "  xhr.send();";
    content += "}";

    content += "</script>";
    content += "</body>";
    content += "</html>";
    webServer.send(200, "text/html", content);
  });
  webServer.begin();
}

void loop() {
  dnsServer.processNextRequest();
  webServer.handleClient();
}

```

# Answer
"Boot fails if pulled LOW" \- this applies to both GPIO 0 and 2. The 2N2222 pulls the GPIO down to one diode drop (0.7V) above GND, which actually is LOW. Instead of using a BJT, you need to control the relay module with a mosfet. Its high gate resistance will have negligible effect compared to the internal pullup resistor.

Chances are that the transistor on the relay module itself is a mosfet. If that's the case and if this mosfet works with 3.3V you can get rid of the 2N2222 at all. In general, using two transistors for this task does not make much sense, but in your case a BJT at the GPIO does not work.

You may notice that the onboard led is connected to GPIO 2, which is high at boot. So if you pull down GPIO 0 somehow, booting fails and GPIO 2 gets pulled HIGH (ref) - the onboard led will light up.

"*the question, how to use them?*" - once the ESP has booted into your sketch you should be fine to use the GPIOs like you would normaly do.
> 1 votes

---
Tags: esp8266, relay
---


title: Help with NodeMCU based smart switch

text:
# Question
Title: Help with NodeMCU based smart switch
The project I'm planning is to use a NodeMCU at each electrical board in house to control lights and fans via relays. Each MCU will communicate via MQTT over WiFi to a Raspberry Pi 4 from where I can control all lights and fans in the house. My doubt is:

Can the 3.3V NodeMCU drive a 5V relay like this 1 Channel 5V Relay Module with Optocoupler since I can't find any 3.3 V relays in India. Or must I use a logic level shifter? Or just use an ESP32 board (double price).

# Answer
> 1 votes
The relay I linked to couldn't be operated with 3v3 from the NodeMCU board. I was powering the NodeMCU via a breadboard power supply that had both 3v3 and 5v output (https://www.electronicscomp.com/mb102-breadboard-power-supply-module). I connected the Vcc and GND of relay to 5V supply on that module. the IO pin relay was connected to NoddeMCU. It worked fine and NodeMCU could switch it on and off.

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


title: Message parsing from MQTT server

text:
# Question
Title: Message parsing from MQTT server
I'm making a NodeMCU based home automation. I adapted code I found on internet for controlling a device (say LED) via MQTT broker hosted on a Raspberry Pi. It works fine. But when I try to scale it up for more than one device, I'm hitting a wall.

```
void callback(char* topic, byte* payload, unsigned int length)
{

  const char* t_bedroom_light1 = "/home/bedroom/light1";

  Serial.print("Topic from MQTT broker is : ");
  Serial.print(topic);
  char p = payload[0];

  // if MQTT comes a 0 turn OFF pin D4
  if (topic == "/home/bedroom/light1" && p == '0')
  {
    digitalWrite(LIGHT_PIN, LOW);
    Serial.println(" Turn Light Off! ");
  }

  // if MQTT comes a 1, turn ON pin D4
  if (topic == "/home/bedroom/light1" && p == '1')
  {
    digitalWrite(LIGHT_PIN, HIGH);
    Serial.println(" Turn Light On! " );
  }
}

```

Serial monitor receives and prints the topic correctly from MQTT server. But `topic == "/home/bedroom/light1"` never returns true. If I delete that part then `p =='0'` or `p=='1'` works fine by itself. I've tried comparing the topic with the locally declared char array, tried converting it into String and doing strcmp. Nothing. What am I doing wrong? Here is the Serial monitor output

```
12:43:20.346 -> .......
12:43:24.187 -> WiFi connected
12:43:24.187 -> IP address:
12:43:24.187 -> 192.168.1.5
12:43:24.187 -> Attempting MQTT connection...connected
12:43:30.752 -> Topic from MQTT broker is : /home/bedroom/light1

```

# Answer
> 1 votes
That's not how you compare C strings.

When you write

```
if (topic == "/home/bedroom/light1")

```

you're comparing whether the character pointer `topic` is the same value as the address of the string `"/home/bedroom/light1"`, which of course it is not in this case.

To compare C strings, use the `strcmp()` function, which returns 0 if they're identical.

```
if (strcmp(topic, "/home/bedroom/light1") == 0 && p == '0')

```

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


# Question
Title: Switching time of a multiple input switch
I basically have two switches Both switches will be pressed simultaneously in different order I want to know which switch was pressed first

# Answer
Use External Interrupts is the short answer.

Longer version:

You probably want to make a buzzer system like what in family feud game show. I assume you are using Arduino UNO/MEGA and or having experience with programming.

1/ Use INT0 and INT1 for button 1 and button 2.

When an interrupt is raised, the mcu jumps to a specific address to run the interrupt service routine. INT0 and INT1 vectors are pointing to two distinctive addresses to run 2 different functions. For this, mcu takes the least amount of CPU clock to capture which button press first.

2/ Use PCINT vectors which is PinChange Interrupt. But personally I prefer to call it PortChange Interrupt.

There are 3 PinChange interrupt vectors PCINT0, PCINT1, PCINT2 to run 3 distinctive service routines. But this kind of interrupt doesn't know which pin is changed.

So inside the interrupt service routine, you have to check for that specific pin. You can do this the arduino way `digitalRead(button1)` or capture the whole port register, ie. PORTB, PORTC or PORTD.

In a nutshell, PORTB holds values of digital pin 8 to 13 while port D hold values of digital pin 0 to 7 and PORC for A0 to A7.

You can shave off some CPU clocks (3-10 clocks probably) by put 2 buttons different PCINT vectors. So that each button still triggers distinctive function.

In 3 cpu clocks (or around 180 ns) a lot of things may change and you may not get the correct result.

3/ Polling in main loop() This is the worst way to do it. Nevertheless, it still gives good result.

```
if (digitalRead(button1)==LOW) {
// do something
}

if (digitalRead(button2)==LOW) {
// do something else
}

```
> 1 votes

# Answer
1. The simple version: check continuously for the state of the digital inputs the switches are connected to. When one is `HIGH` that is the switched pressed first.
2. The intermediate version: check the 'blink without delay' example to make sure you don't get too many false positives.
3. The advanced version: use interrupts when one of the two switches gets 'HIGH', using the 'blink without delay' to prevent false positives.

If you want to know if both are pressed at the same time, but one is pressed first, use variables to keep track on it.

like two variables:

```
bool button1Pressed = false;
bool button2Pressed = false;

```

Set them accordingly (depending on which of the 3 possibilities you use). Then when you know a button is changed, you can easily check the booleans to know which was already pressed.

Or you can use an enum that combines the state of both:

```
enum EState { ALL_OFF, BUTTON_1_PRESSED, BUTTON_2_PRESSED, BOTH_BUTTONS_PRESSED };

EState buttonState;

```
> 0 votes

---
Tags: sensors, time, switch
---


# Question
Title: converting an unsigned integer into a const char pointer
I know this is simple basic C stuff, but I can't quite figure it out or find a solution when searching and reading.

I have a method I want to call from a library that wants a const char pointer

```
someclass::send(const char *data)

```

And the value I want to send is actually an unsigned integer:

```
enum messageTypeEnum
{
  REGISTER_CLIENT = 0x04,
  CLIENT_REGISTERED,
  UPDATE_CREDENTIALS,
  ADD_BRICK,
  GAME_FRAME,
  ERROR
};

enum clientTypeEnum
{
  GAMEBOARD = 0x01,
  BRICK_CONTROLLER,
  PLAYER_CONTROLLER,
  TOUCH_CONTROLLER
};

uint16_t message = GAMEBOARD;
message <<= 8;
message += REGISTER_CLIENT;

```

So I want to convert it, but I can't quite figure it out.

I know fundamentally the char pointer is just a pointer to a memory address and that c strings are null terminated, so I should be able to create the pointer, add the enum's underlying bytes to the pointer array, and then add a 0 at the end to terminate it, but I don't know how I would do that exactly.

I tried doing it via casting:

```
const char *data = (char *)&message;

```

So here I'm saying (if I'm thinking about it correctly), is:

* `&message` take the memory address of `message`, our uint16
* \`(char \*) interpret it as a pointer for a character string
* `const char *` store that address in this const pointer

Even typing that out I feel like I'm misunderstanding parts.

This compiles, but it crashes my esp32 and I'm sure it's because I don't have a null terminator at the end, but I'm not sure how to add it (I tried to add it via array index but that failed).

What's the proper way of doing this (I'm sure there's a non-casting way that's probably easier)?

# Update

More detail re: PMF and Edgar's comments.

I definitely want to send the binary numbers behind the enums up. I'm building a websocket based interactive project where "controller" websocket clients can drive interactions on "gameboards". Websockets don't have a concept of differentiating between client types (I know socket.io does, but I'm wanting to write it all with regular websockets), so I built a registration system into the server that looks at the first two bytes of an array buffer or blob message to determine the client and message type (it seems overly complicated, but I'm building this to give a talk on binary operations and I'm doing it give functional examples of data parsing).

So yeah, all of that to say I definitely want to send the underlying number values from the enums.

The library I'm using is ArduinoWebsockets and they do have a client method called `sendBinary` that does have a signature like the `Serial.write`:

Though when I tried this with a non-null terminated c-string my esp32 crashed. That said, I was fumbling around in the code so it may have been something else that caused the crash.

When I follow the method calls down, the library ultimately uses `std::string` to pull the data out of the passed in c string and takes in the length (meaning it doesn't need to be null terminated(?)):

So maybe I can use the casting to turn my two byte number into a c string and pass in the length of 16?

# Answer
# CORRECTED ANSWER

I dug back into my code after a comment from Edgar and figured out some needed adjustments. My original solution was mostly correct, but there were some inaccuracies that I want to correct so I'm not goofing up anyone else in the future that may find this answer useful.

---

So I was overthinking things a bit. I still don't know that this is the best way of handling it, but it is working on the client side.

So, c-strings are just arrays of 8bit values with a null terminator at the end.

I want to end up my enum values, and my enums are define with byte enum-bases:

```
enum messageTypeEnum
{
  REGISTER_CLIENT = 0x04,
  CLIENT_REGISTERED,
  UPDATE_CREDENTIALS,
  ADD_BRICK,
  GAME_FRAME,
  ERROR
};

enum clientTypeEnum
{
  GAMEBOARD = 0x01,
  BRICK_CONTROLLER,
  PLAYER_CONTROLLER,
  TOUCH_CONTROLLER
};

```

So, to send up my bytes, I can just build a character array, set each byte in little endian order, and manually terminate it:

*NOTE: this is the original assembly that was incorrect.* I put the null terminator at the beginning of the buffer thinking "oh, it's little endian so the terminator needs to be at the beginning". Classic sleepy brain mistake :|

void registerAsAGameBoard() { char buffer\[3\] = {0, GAMEBOARD, REGISTER\_CLIENT};

client.sendBinary((const char \*)buffer, 3); }

```
void registerAsAGameBoard()
{
  char data[3] = {GAMEBOARD, REGISTER_CLIENT, 0};

  const char *buffer = data;
  size_t size = strlen(buffer);

  client.sendBinary(buffer, size);
}

```

Now when I call sendBinary with my byte array and the length of the buffer my esp32 doesn't crash (hurray!) and the server receives the buffer correctly!!

I need to make a couple of adjustments on either the client and/or server side to account for the fact that the ESP32 is little endian and the server is already coded to receive payloads in big endian, but that shouldn't be too much of a lift.
> 1 votes

---
Tags: memory, pointer
---


# Question
Title: How to close humidity sensor at specific humidity
I am using dht humidity and temperature sensor on arduino and i would like to add relay and buzzer on the system. What I would like to do is to close it via buzzer and on 65% humidity run buzzer. The code i use is:

```
/* DHT-22 sensor with 12c 16x2 LCD with Arduino uno
   Temperature and humidity sensor displayed in LCD
   based on: http://www.ardumotive.com/how-to-use-dht-22-sensor-en.html and
   https://www.ardumotive.com/i2clcden.html for the i2c LCD library by Michalis Vasilakis
   Recompile by adhitadhitadhit
   Notes: use LCD i2c Library from link above, i'm not sure why but new Liquidcristal library from Francisco Malpartida  isn't working for me
   other thing, check your */

//Libraries
#include <dht.h> // sensor library using lib from https://www.ardumotive.com/how-to-use-dht-22-sensor-en.html
#include <LiquidCrystal_I2C.h> // LCD library using from  https://www.ardumotive.com/i2clcden.html for the i2c LCD library
#include <Wire.h>
dht DHT;

//Constants
#define DHT22_PIN 2     // DHT 22  (AM2302) - pin used for DHT22
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 after finding it from serial monitor (see comment above) for a 16 chars and 2 line display

//Variables
float hum;  //Stores humidity value
float temp; //Stores temperature value

void setup()
{
    Serial.begin(9600);
    lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setBacklight(HIGH);
}

void loop()
{
    int chk = DHT.read22(DHT22_PIN);
    //Read data and store it to variables hum and temp
    hum = DHT.humidity;
    temp= DHT.temperature;
    //Print temp and humidity values to LCD
    lcd.setCursor(0,0);
    lcd.print("Humidity: ");
    lcd.print(hum);
    lcd.print("%");
    if (humidity <= 50)
{
   digitalWrite(ledPin, HIGH);
   digitalWrite(buzzer, HIGH);

 }

 else

 {

 digitalWrite(ledPin, LOW); digitalWrite(buzzer, LOW);

    lcd.setCursor(0,1);
    lcd.print("Temp: ");
    lcd.print(temp);
    lcd.println("Celcius");
    delay(2000); //Delay 2 sec between temperature/humidity check.
}

```

How to add relay and buzzer to close it with buzzer run on 65% humidity value?

# Answer
> 0 votes
In this code:

```
void loop()
{
   sample temp and humidity;
   display temp;
   display humidity;

   if humidity <= 50
      LED on;
      buzzer on;
   else
      display temp
      wait 2 sec
   end

```
* There is a missing '}' to to close the if/else.
* Why do you display temp twice within the loop?
* Where is the logic for the relay and the buzzer at 65%?
* Pin numbers for the LED and the buzzer are undefined.
* The LED and buzzer pins need to be set to OUTPUT mode in your setup() function.

If I understand your description, you probably need somethng like the following, in your loop function:

```
   if humidity <= 50
      LED on;
      buzzer on;
   else if hum >= 65%m
      close relay;
      buzzer on;
   end

```

When I have a problem with program logic that isn't obvious to me, I write it out in pseudo-code as I did above. Once I figure out the logic, then I'll type in C++ with proper syntax. If I haven't understood your intentions in the above pseudo-code, I'd suggest you do the same thing, until you believe what you've written. Only then try to make it into working code.

---
Tags: arduino-uno, relay, buzzer
---


# Question
Title: esp32s: error: 'WDT_TIMEOUT' was not declared in this scope
I am trying to initialize the watchdog timer.

I have installed

```
arduino-esp32-master.zip

```

I have

```
#include <esp_task_wdt.h>

```

set but it is not highlighted red indicating the IDE knows about it.

The error indicates that a major function is not present.

full error:

```
Arduino: 1.8.13 (Linux), TD: 1.53, Board: "ESP32 Dev Module, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 115200, None"

/home/brad/Documents/bradcode/Arduino/esp32s-infrared-ac-wifi-server-v4/esp32s-infrared-ac-wifi-server-v4.ino: In function 'void setup()':
esp32s-infrared-ac-wifi-server-v4:229:23: error: 'WDT_TIMEOUT' was not declared in this scope
     esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
                       ^
Multiple libraries were found for "IRremote.h"
 Used: /home/brad/Documents/bradcode/Arduino/libraries/IRremote
 Not used: /home/brad/Documents/bradcode/Arduino/libraries/Arduino-IRremote-master
 Not used: /home/brad/Documents/bradcode/Arduino/libraries/IRremote-2.8.1
Multiple libraries were found for "WiFi.h"
 Used: /home/brad/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WiFi
 Not used: /home/brad/Downloads/arduino-1.8.13/libraries/WiFi
 Not used: /home/brad/Documents/bradcode/Arduino/libraries/WiFiEspAT
exit status 1
'WDT_TIMEOUT' was not declared in this scope

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

What library did I fail to install to get the watchdog timer initialized?

UPDATE:

My additional boards URLs

```
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json,http://arduino.esp8266.com/stable/package_esp8266com_index.json

```

After following recommendations for poster, I got past that error and hit another one right away.

```
Arduino: 1.8.13 (Linux), TD: 1.53, Board: "ESP32 Dev Module, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 115200, None"

In file included from /home/brad/Documents/bradcode/Arduino/esp32s-infrared-ac-wifi-server-v4/esp32s-infrared-ac-wifi-server-v4.ino:24:0:
/home/brad/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WebServer/src/WebServer.h: In member function 'virtual size_t WebServer::_currentClientWrite_P(const char*, size_t)':
/home/brad/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WebServer/src/WebServer.h:144:83: error: 'class WiFiClient' has no member named 'write_P'
   virtual size_t _currentClientWrite_P(PGM_P b, size_t l) { return _currentClient.write_P( b, l ); }
                                                                                ^
/home/brad/Documents/bradcode/Arduino/esp32s-infrared-ac-wifi-server-v4/esp32s-infrared-ac-wifi-server-v4.ino: In function 'void setup()':
esp32s-infrared-ac-wifi-server-v4:246:10: error: 'class WiFiClass' has no member named 'mode'
     WiFi.mode(WIFI_STA);
          ^
esp32s-infrared-ac-wifi-server-v4:246:15: error: 'WIFI_STA' was not declared in this scope
     WiFi.mode(WIFI_STA);
               ^
esp32s-infrared-ac-wifi-server-v4:251:73: error: no matching function for call to 'WiFiClass::config(IPAddress&, IPAddress&, IPAddress&, IPAddress&, IPAddress&)'
     if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
                                                                         ^
In file included from /home/brad/Documents/bradcode/Arduino/esp32s-infrared-ac-wifi-server-v4/esp32s-infrared-ac-wifi-server-v4.ino:22:0:
/home/brad/Documents/bradcode/Arduino/libraries/WiFiEspAT/src/WiFi.h:72:8: note: candidate: bool WiFiClass::config(IPAddress, IPAddress, IPAddress, IPAddress)
   bool config(IPAddress local_ip, IPAddress dns_server = INADDR_NONE, IPAddress gateway = INADDR_NONE, IPAddress subnet = INADDR_NONE);
        ^
/home/brad/Documents/bradcode/Arduino/libraries/WiFiEspAT/src/WiFi.h:72:8: note:   candidate expects 4 arguments, 5 provided
Multiple libraries were found for "IRremote.h"
 Used: /home/brad/Documents/bradcode/Arduino/libraries/IRremote
 Not used: /home/brad/Documents/bradcode/Arduino/libraries/IRremote-2.8.1
 Not used: /home/brad/Documents/bradcode/Arduino/libraries/Arduino-IRremote-master
exit status 1
'class WiFiClass' has no member named 'mode'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

I have some library mixed up still

# Answer
There is no such macro in the ESP32 core. That parameter is just the number of seconds before a timeout occurs. Just pick a reasonable value. 5 seconds seems to be a commonly used (and appears to be used in the core) value.
> 1 votes

---
Tags: esp32, c, watchdog
---


# Question
Title: HobbyTronics UNO PRO Board Definition does not work in newer IDE versions
I have a HobbyTronics UNO PRO that replaces the UNO's 328P in DIP with an ATMega1284 on an adapter board:

I cannot link to the original page since it does not exist anymore. But, it is available through archive.org.

The original board definition, supplied by the distributor, stopped working after 1.8.10 and throws errors in 1.9.

The particular error when trying to compile:

```
recipe.preproc.macros pattern is missing

```

It is not about a particular library or similar; I cannot compile at all (even an empty sketch).

**How can I migrate this board?** I'd really like to use a current version of the compiler & IDE.

# Answer
> 1 votes
## Making your board definition work

What I did was slightly different from their directions, but:

Close any instances of the IDE you have running.

Create the directories along this path:

```
<sketchbook>/hardware/uno_pro/avr/variants/uno_pro

```

Where `<sketchbook>` refers to to where your IDE is saving sketches by default.

Place the following slightly modified `boards.txt` at `<sketchbook>/hardware/uno_pro/avr/boards.txt`:

```
uno_pro.name=Arduino Uno*Pro

uno_pro.upload.tool=avrdude
uno_pro.upload.protocol=arduino
uno_pro.upload.maximum_size=130048
uno_pro.upload.maximum_data_size=16384
uno_pro.upload.speed=115200

uno_pro.bootloader.tool=avrdude
uno_pro.bootloader.low_fuses=0xFF
uno_pro.bootloader.high_fuses=0xDE
uno_pro.bootloader.extended_fuses=0xFD
uno_pro.bootloader.unlock_bits=0x3F
uno_pro.bootloader.lock_bits=0x0F
uno_pro.bootloader.file=optiboot/optiboot_atmega1284p.hex

uno_pro.build.mcu=atmega1284p
uno_pro.build.f_cpu=16000000L
uno_pro.build.board=AVR_UNO_PRO
uno_pro.build.core=arduino:arduino
uno_pro.build.variant=uno_pro

```

This is the original file with one important modification, and that's the addition of `arduino:` in the second to last line reading `uno_pro.build.core=arduino:arduino`

Place the following (unmodified from original) `pins_arduino.h` at `<sketchbook>/hardware/uno_pro/avr/variants/uno_pro/pins_arduino.h`:

```
#ifndef Pins_Arduino_h
#define Pins_Arduino_h

#include <avr/pgmspace.h>

// ATMEL ATMEGA1284 on Hobbytronics UNO*Pro
//
//
// 2014-01-24 - Modified for Software Serial Library to work
//
//   ATMEGA1284 Pin     Arduino Mapping    Features
//     PA0                   D21  A7
//    PA1                   D20  A6
//     PA2                   D19  A5
//    PA3                   D18  A4
//     PA4                   D17  A3
//    PA5                   D16  A2
//     PA6                   D15  A1
//    PA7                   D14  A0
//
//     PB0                   D4
//    PB1                   D5
//     PB2                   D2
//    PB3                   D3               PWM
//     PB4                   D10                    PWM  SS
//    PB5                   D11                   MOSI
//     PB6                   D12              PWM  MISO
//    PB7                   D13              PWM  SCK
//
//     PC0                   D22                   SCL
//    PC1                   D23                   SDA
//     PC2                   D24
//    PC3                   D25
//     PC4                   D26
//    PC5                   D27
//     PC6                   D28
//    PC7                   D29
//
//     PD0                   D0                    RX
//    PD1                   D1                    TX
//     PD2                   D6                    RX1
//    PD3                   D7                    TX1
//     PD4                   D30              PWM
//    PD5                   D8               PWM
//     PD6                   D9               PWM
//    PD7                   D31              PWM
//

static const uint8_t SS   = 10;
static const uint8_t MOSI = 11;
static const uint8_t MISO = 12;
static const uint8_t SCK  = 13;

static const uint8_t SDA = 23;
static const uint8_t SCL = 22;
static const uint8_t LED = 13;

static const uint8_t A0 = 0;
static const uint8_t A1 = 1;
static const uint8_t A2 = 2;
static const uint8_t A3 = 3;
static const uint8_t A4 = 4;
static const uint8_t A5 = 5;
static const uint8_t A6 = 6;
static const uint8_t A7 = 7;

#define NUM_DIGITAL_PINS            32
#define NUM_ANALOG_INPUTS           8

// Macros
#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? (p) + 14 : -1)
#define digitalPinToAnalogPin(p)    ((p) >= 14 && (p) <= 21 ? (p) - 14 : -1 )
#define analogPinToChannel(p)         ((p) < NUM_ANALOG_INPUTS ? NUM_ANALOG_INPUTS - (p) - 1: -1 )
#define digitalPinHasPWM(p)         ((p) == 3 || (p) == 8 || (p) == 9 || (p) == 10 || (p) == 12 || (p) == 13 || (p) == 30 || (p) == 31 )

#define ifpin(p,what,ifnot)     (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (what) : (ifnot))

extern const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS];

#define digitalPinToPCICR(p)    ifpin(p,(&PCICR),(uint8_t *)0)
#define digitalPinToPCICRbit(p) ifpin(p,(digital_pin_to_pcint[p] >> 3),0)
#define digitalPinToPCMSK(p)    (((p) <= 1) ? (&PCMSK3) : (((p) <= 5) ? (&PCMSK1) : (((p) <= 9) ? (&PCMSK3) : (((p) <= 13) ? (&PCMSK1) : (((p) <= 21) ? (&PCMSK0) : (((p) <= 29) ? (&PCMSK2) : (((p) <= 31) ? (&PCMSK3) : ((uint8_t *)0))))))))
#define digitalPinToPCMSKbit(p) ifpin(p,digital_pin_to_pcint[p] & 0x7,0)

#define digitalPinToInterrupt(p)  ((p) == 6 ? 0 : ((p) == 7 ? 1 : ((p) == 2 ? 2 : NOT_AN_INTERRUPT)))

#ifdef ARDUINO_MAIN

#define PA 1
#define PB 2
#define PC 3
#define PD 4

const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS] =
{
  24, // D0  PD0
  25, // D1  PD1 1
  10, // D2  PB2
  11, // D3  PB3
  8,  // D4  PB0
  9,  // D5  PB1 5
  26, // D6  PD2
  27, // D7  PD3
  29, // D8  PD5
  30, // D9  PD6 9
  12, // D10 PB4
  13, // D11 PB5
  14, // D12 PB6
  15, // D13 PB7 13
  7,  // D14 PA7
  6,  // D15 PA6
  5,  // D16 PA5
  4,  // D17 PA4
  3,  // D18 PA3
  2,  // D19 PA2
  1,  // D20 PA1
  0,  // D21 PA0 21
  16, // D22 PC0
  17, // D23 PC1
  18, // D24 PC2
  19, // D25 PC3
  20, // D26 PC4
  21, // D27 PC5
  22, // D28 PC6
  23, // D29 PC7 29
  28, // D30 PD4
  31  // D31 PD7 31
};

// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] =
{
    NOT_A_PORT,
    (uint16_t) &DDRA,
    (uint16_t) &DDRB,
    (uint16_t) &DDRC,
    (uint16_t) &DDRD,
};

const uint16_t PROGMEM port_to_output_PGM[] =
{
    NOT_A_PORT,
    (uint16_t) &PORTA,
    (uint16_t) &PORTB,
    (uint16_t) &PORTC,
    (uint16_t) &PORTD,
};

const uint16_t PROGMEM port_to_input_PGM[] =
{
    NOT_A_PORT,
    (uint16_t) &PINA,
    (uint16_t) &PINB,
    (uint16_t) &PINC,
    (uint16_t) &PIND,
};

const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
  PD, // D0
  PD, // D1
  PB, // D2
  PB, // D3
  PB, // D4
  PB, // D5
  PD, // D6
  PD, // D7
  PD, // D8
  PD, // D9
  PB, // D10
  PB, // D11
  PB, // D12
  PB, // D13
  PA, // D14
  PA, // D15
  PA, // D16
  PA, // D17
  PA, // D18
  PA, // D19
  PA, // D20
  PA, // D21
  PC, // D22
  PC, // D23
  PC, // D24
  PC, // D25
  PC, // D26
  PC, // D27
  PC, // D28
  PC, // D29
  PD, // D30
  PD, // D31
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
  _BV(0), // D0  PD0
  _BV(1), // D1  PD1
  _BV(2), // D2  PB2
  _BV(3), // D3  PB3
  _BV(0), // D4  PB0
  _BV(1), // D5  PB1
  _BV(2), // D6  PD2
  _BV(3), // D7  PD3
  _BV(5), // D8  PD5
  _BV(6), // D9  PD6
  _BV(4), // D10 PB4
  _BV(5), // D11 PB5
  _BV(6), // D12 PB6
  _BV(7), // D13 PB7
  _BV(7), // D14 PA7 (A0)
  _BV(6), // D15 PA6 (A1)
  _BV(5), // D16 PA5 (A2)
  _BV(4), // D17 PA4 (A3)
  _BV(3), // D18 PA3 (A4)
  _BV(2), // D19 PA2 (A5)
  _BV(1), // D20 PA1 (A6)
  _BV(0), // D21 PA0 (A7)
  _BV(0), // D22 PC0
  _BV(1), // D23 PC1
  _BV(2), // D24 PC2
  _BV(3), // D25 PC3
  _BV(4), // D26 PC4
  _BV(5), // D27 PC5
  _BV(6), // D28 PC6
  _BV(7), // D29 PC7
  _BV(4), // D30 PD4
  _BV(7), // D31 PD7
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
  NOT_ON_TIMER, // D0  PD0
  NOT_ON_TIMER, // D1  PD1
  NOT_ON_TIMER, // D3  PB2
  TIMER0A,      // D3  PB3
  NOT_ON_TIMER, // D4  PB0
  NOT_ON_TIMER, // D5  PB1
  NOT_ON_TIMER, // D6  PD2
  NOT_ON_TIMER, // D7  PD3
  TIMER1A,      // D8  PD5
  TIMER2B,      // D9  PD6
  TIMER0B,      // D10 PB4
  NOT_ON_TIMER, // D11 PB5
  TIMER3A,      // D12 PB6
  TIMER3B,      // D13 PB7
  NOT_ON_TIMER, // D14 PA0
  NOT_ON_TIMER, // D15 PA1
  NOT_ON_TIMER, // D16 PA2
  NOT_ON_TIMER, // D17 PA3
  NOT_ON_TIMER, // D18 PA4
  NOT_ON_TIMER, // D19 PA5
  NOT_ON_TIMER, // D20 PA6
  NOT_ON_TIMER, // D21 PA7
  NOT_ON_TIMER, // D22 PC0
  NOT_ON_TIMER, // D23 PC1
  NOT_ON_TIMER, // D24 PC2
  NOT_ON_TIMER, // D25 PC3
  NOT_ON_TIMER, // D26 PC4
  NOT_ON_TIMER, // D27 PC5
  NOT_ON_TIMER, // D28 PC6
  NOT_ON_TIMER, // D29 PC7
  TIMER1B,      // D30 PD4
  TIMER2A,      // D31 PD7
};

#endif // ARDUINO_MAIN

#endif // Pins_Arduino_h
// vim:ai:cin:sts=2 sw=2 ft=cpp

```

Open the IDE and your board should be listed. It should compile with a blank sketch. I did not test further than that.

## MCUDude MightyCore

Your board could also likely be made to work with MCUdude MightyCore. *However*, MightyCore will **not have your pin mapping**. So, although you *could* use it, you would need to ignore the normal UNO pin labeling and instead of work out which pin number used by the chosen MightyCore variant routes to which pin on the UNO headers. It would be annoying to do, but you could do that by comparing entries in your adapter's pins\_arduino.h file with the entries in the chosen variant from the MightCore package. But, the modifications above seem to work fine. So, I don't necessarily suggest that route; I'm just saying it *could* be used that way also.

MightyCore could also be modified, but that works out to the same or more work than just using your board definition, I think.

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


title: Convert a char array to Flash string

text:
# Question
Title: Convert a char array to Flash string
I would like to pass a formatted string to a method that accepts a \__FlashStringHelper. Here is the method signature:

```
void myMethod(const __FlashStringHelper *str);

```

I have been using snprintf to format my string:

```
char cmd[30];
snprintf(cmd, 30, "There are %d seconds in a minute", 60);
myMethod(F(&cmd[0]));

```

Clearly the above doesn't work but how can I format a Flash String?

EDIT: I need to include an integer variable in my flash string. In the example above, '60' is a variable.

```
uint8_t nSeconds = 60;
char cmd[30];
snprintf(cmd, 30, "There are %d seconds in a minute", nSeconds);
myMethod(F(&cmd[0]));

```

# Answer
## Direct answer

`F()` takes *immutable* string literals, that are known at *compile* time, and places them into flash ("PROGMEM") instead of RAM. `snprintf()` creates strings at *runtime* and places them into a *mutable* array. The two things are fundamentally incompatible.

## Limited compile-time concatenation

A *very limited* form of what you're trying to do could probably done like this:

```
#define MY_STRINGIZE(x) #x

myMethod(F("There are " MY_STRINGIZE(60) " seconds in a minute"));

```

This expands to:

```
myMethod(F("There are " "60" " seconds in a minute"));

```

Adjacent string literals are concatenated together, which makes this:

```
myMethod(F("There are 60 seconds in a minute"));

```

All that said, you could just write 60 in there directly. And there's none of `snprintf`'s formatting capabilities possible here.

There is not a compile-time version of `snprintf` available in Arduino. And I don't think the features of the C++ (or C) language are there to support the creation of one either. Odds are there is a better way of achieving what you really want to do.

## Working around this altogether

Often it's not necessary to concatenate strings at all, particularly if you're just to turn around and write them to a `Stream`, or more generally `Print` subclass, e.g. `Serial`, `LCD`, `SDFile`, `SoftwareSerial`, etc. Concatenating things for you is a large part of what these do. It is not necessarily to do it yourself in advance.

If you have a string literal and constant (or variable) and want to keep as much of it out of RAM as possible, using two separate `.print()`/`.println()` helps you do this:

```
printCapableThing.print(F("AT+CIPSTAT="));
printCapableThing.println(index);

```
* `F()` places `"AT+CIPSTAT="` into flash.
* If index is a constant it will also wind not being resident in RAM.

## Side note

I realize you're asking about, getting as much into flash as possible, but I also can't help but point out this same basic technique applies to this otherwise awful idea, for somewhat different reasons:

```
Serial.println(String(F("Key ")) + keyname + " : " + value);

```

This creates a horrific mess of allocations and deallocations and unnecessary copying, where if you just let the Stream/Print object do its job by calling `print()`/`println()` multiple times. The result code is more reliable, smaller, and where not I/O-bound, faster when you do.
> 3 votes

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


# Question
Title: Having trouble with MPU6050 and AFE4404 printing together, potential conflict?
I am having trouble getting the two sensors to work together. There are a total of four sensors connected to the Arduino, and while the MPU and AFE individually work fine with the other two sensors, when the two are put together only the Serial Plotter for the AFE shows up while the MPU stays at zero. I initially assumed that there were address conflicts with the two, but their i2c addresses are different: the AFE at 0x58 and the MPU at 0x68 or 0x69. How can I resolve the issue so that I can get all four sensors' graphs printing? Below is my Arduino code:

```
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"

//int preValue = 0;
String str = "0, 0, 0, 0";
int mic = A0;
MPU6050 mpu;
int16_t ax, ay, az;

//PPG Stuff
#define NUM_REGISTERS       40
/* Pinbelegung */

int RESETZ = 4;
int CLK = 5;
int INT = 6;
//const int ocr1aval = 1; //||0 = 8MHz|| 1 = 4MHz|| 3 = 2MHZ ||7 = 1MHz||
const byte interruptPin = 2;

char LED2 = 0x2A; // LED2 on AFE4404

struct Register {
  uint8_t addr;
  uint32_t val;
};
/* Variablendeklaration */

//float befehl = 0;
bool Ready = 1;
int AFE_ADDR = 0x58;

unsigned long counter = 0;

/* AFE440X registers */

#define AFE_CONTROL0                0x00
#define AFE_LED2STC                 0x01
#define AFE_LED2ENDC                0x02
#define AFE_LED1LEDSTC              0x03
#define AFE_LED1LEDENDC             0x04
#define AFE_ALED2STC                0x05
#define AFE_ALED2ENDC               0x06
#define AFE_LED1STC                 0x07
#define AFE_LED1ENDC                0x08
#define AFE_LED2LEDSTC              0x09
#define AFE_LED2LEDENDC             0x0A
#define AFE_ALED1STC                0x0B
#define AFE_ALED1ENDC               0x0C
#define AFE_LED2CONVST              0x0D
#define AFE_LED2CONVEND             0x0E
#define AFE_ALED2CONVST             0x0F
#define AFE_ALED2CONVEND            0x10
#define AFE_LED1CONVST              0x11
#define AFE_LED1CONVEND             0x12
#define AFE_ALED1CONVST             0x13
#define AFE_ALED1CONVEND            0x14
#define AFE_ADCRSTSTCT0             0x15
#define AFE_ADCRSTENDCT0            0x16
#define AFE_ADCRSTSTCT1             0x17
#define AFE_ADCRSTENDCT1            0x18
#define AFE_ADCRSTSTCT2             0x19
#define AFE_ADCRSTENDCT2            0x1A
#define AFE_ADCRSTSTCT3             0x1B
#define AFE_ADCRSTENDCT3            0x1C
#define AFE_PRPCOUNT                0x1D
#define AFE_CONTROL1                0x1E
#define AFE_TIA_GAIN_SEP            0x20
#define AFE_TIA_GAIN                0x21
#define AFE_LEDCNTRL                0x22
#define AFE_CONTROL2                0x23
#define AFE_ALARM                   0x29
#define AFE_LED2VAL                 0x2A
#define AFE_ALED2VAL                0x2B
#define AFE_LED1VAL                 0x2C
#define AFE_ALED1VAL                0x2D
#define AFE_LED2_ALED2VAL           0x2E
#define AFE_LED1_ALED1VAL           0x2F
#define AFE_CONTROL3                0x31
#define AFE_PDNCYCLESTC             0x32
#define AFE_PDNCYCLEENDC            0x33
#define AFE_PROG_TG_STC             0x34
#define AFE_PROG_TG_ENDC            0x35
#define AFE_LED3LEDSTC              0x36
#define AFE_LED3LEDENDC             0x37
#define AFE_CLKDIV_PRF              0x39
#define AFE_OFFDAC                  0x3A
#define AFE_DEC                     0x3D
#define AFE_AVG_LED2_ALED2VAL       0x3F
#define AFE_AVG_LED1_ALED1VAL       0x40

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

  //ECG
  pinMode(10, INPUT); // Setup for leads off detection LO +
  pinMode(11, INPUT); // Setup for leads off detection LO -

  //PCG
  /*none needed*/

  //PPG
  pinMode(RESETZ, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(INT, INPUT);
  AFE_Init();

  //SCG
  #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
  #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
  #endif
  // initialize device
  mpu.initialize();
}

void PCG_Init()
{
  double micOut;
  const int sampleTime = 50;
  double preValue = 0;
}

void loop() {
  // put your main code here, to run repeatedly:
  String ECG = "0";
  //String SCG = "0";

  int PCG_val;
  String PCG;
  PCG_val = PCG_loop();
  PCG = String(PCG_val);

  int PPG_val;
  String PPG;
  PPG_val = PPG_loop() * -1;
  PPG = String(PPG_val);

//  int ECG_val;
//  String ECG;
//  ECG_val = ECG_loop();
//  ECG = String(ECG_val);

  int SCG_val;
  String SCG;
  SCG_val = SCG_loop();
  SCG = String(SCG_val);

  str = PCG + "," + PPG + "," + ECG + "," + SCG;
  Serial.println(str);
  delay(10);
}

//ECG Loop
int ECG_loop() {
  // put your main code here, to run repeatedly:
  if((digitalRead(10) == 1)||(digitalRead(11) == 1)){
  Serial.println('!');
  }
  else{
  // send the value of analog input 0:
  Serial.println(analogRead(A1));
  }
  //Wait for a bit to keep serial data from saturating
  delay(1);
  //delay (30);
}

//SCG Loop
int SCG_loop() {
    mpu.getAcceleration(&ax, &ay, &az);
    Serial.println(az/(pow(2,9)*1.0));
}

//PCG Loop
int PCG_loop() {
  //switch
  //case 1:
  int returnfill;
   double micOutput = findPTPAmp();
   returnfill = VUMeter(micOutput);
   return returnfill;
}

// Find the Peak-to-Peak Amplitude Function
double findPTPAmp(){
// Time variables to find the peak-to-peak amplitude
   unsigned long startTime= millis();  // Start of sample window
   /*unsigned int*/ double PTPAmp = 0;

// Signal variables to find the peak-to-peak amplitude
   /*unsigned int*/ double maxAmp = 0;
   /*unsigned int*/ double minAmp = 1023;

// Find the max and min of the mic output within the 50 ms timeframe
   while(millis() - startTime < sampleTime)
   {
      micOut = analogRead(mic);
      if( micOut < 1023) //prevent erroneous readings
      {
        if (micOut > maxAmp)
        {
          maxAmp = micOut; //save only the max reading
        }
        else if (micOut < minAmp)
        {
          minAmp = micOut; //save only the min reading
        }
      }
   }

  PTPAmp = maxAmp - minAmp; // (max amp) - (min amp) = peak-to-peak amplitude
  double micOut_Volts = (PTPAmp * 3.3) / 1024; // Convert ADC into voltage
  return PTPAmp;
}

// Volume Unit Meter function: map the PTP amplitude to a volume unit between 0 and 10.
int VUMeter(double micAmp){
  double fill = map(micAmp, 23, 750, 0, 10);
  while(fill != preValue)
  {
    preValue = fill;
  }
  return fill;
}

//PPG Loop
signed long val = 0;
void readADC()
{
  {
    val = AFE_Reg_Read(LED2);
    Ready = 1;
  }
}

int PPG_loop() {
  if (digitalRead(INT))
  {
    val = AFE_Reg_Read(LED2);
  }
  return val;
}

//More PPG Stuff
void AFE_Init()
{
  AFE_RESETZ_Init();
  AFE_Enable_HWPDN();
  AFE_Disable_HWPDN();
  AFE_Trigger_HWReset();
  Wire.begin();
  Wire.beginTransmission (AFE_ADDR);
  Serial.println("Initializing AFE4404...");
  if (Wire.endTransmission () == 0)
  {
    AFE_Enable_Write (); // enable to writting to registers
    AFE_Reg_Init();
    AFE_CLK_Init();
    AFE_Enable_Read ();  // enable to reading from registers
    Serial.println("Initialized Success!");
  }
  else
    Serial.println("Initialized Fail!");

}

/**********************************************************************************************************/
/*                              AFE4404_Registerinitialisierung                                           */
/**********************************************************************************************************/
void AFE_Reg_Init()
{
  //AFE_Reg_Write(34, 0x0033C3);
  AFEinitRegisters();
}

/**********************************************************************************************************/
/*                              AFE4404_Enable_Read                                                       */
/**********************************************************************************************************/
void AFE_Enable_Read ()         //Prohibit writing to registers
{
  byte configData[3];
  configData[0] = 0x00;
  configData[1] = 0x00;
  configData[2] = 0x01;// 0x01
  I2C_write (AFE_ADDR, AFE_CONTROL0, configData, 3);
}

/**********************************************************************************************************/
/*                              AFE4404_Disable_Read                                                      */
/**********************************************************************************************************/
void AFE_Enable_Write ()        //Permitt writing to registers
{
  byte configData[3];
  configData[0] = 0x00;
  configData[1] = 0x00;
  configData[2] = 0x00; //0x00
  I2C_write (AFE_ADDR, AFE_CONTROL0, configData, 3);
}

/**********************************************************************************************************/
/*                  RESETZ des AFE4404 wird Initialisiert                                                 */
/**********************************************************************************************************/
void AFE_RESETZ_Init()
{
  digitalWrite(RESETZ, HIGH);
  delayMicroseconds(30);
}

/**********************************************************************************************************/
/*                  Reset internal registers by setting RESETZ = LOW for 25 - 50 us                       */
/**********************************************************************************************************/
void AFE_Trigger_HWReset()
{
  digitalWrite(RESETZ, LOW);              //Sets Arduino pins 22-29 LOW
  delayMicroseconds(30); //30
  digitalWrite(RESETZ, HIGH);              //Sets Arduino pins 22-29 HIGH
  delay(10); // 10
}

/**********************************************************************************************************/
/*                             AFE4404 Power Down                                                         */
/**********************************************************************************************************/
void  AFE_Enable_HWPDN()
{
  digitalWrite(RESETZ, LOW);                  //Power Down by setting the RESETZ pin to LOW for more than 200 us
  delay(10);
}

/**********************************************************************************************************/
/*                                AFE4404 Power Up                                                        */
/**********************************************************************************************************/
void  AFE_Disable_HWPDN()
{
  digitalWrite(RESETZ, HIGH);                  //Power Up the AFE by setting the RESETZ pin to HIGH
  delay(10);
}

/**********************************************************************************************************/
/*                                AFE4404 Set Clock Mode to Internal                                      */
/**********************************************************************************************************/

void AFE_CLK_Init()
{
  AFE_Reg_Write(35, 0x104218);        //Set CLK Mode to internal clock (default Wert: 124218 mit interner CLK)
  AFE_Reg_Write(41, 0x2);             //Don´t set the internal clock to the CLK pin for outside usage
  AFE_Reg_Write(49, 0x000021);        //Division ratio for external clock mode set to fit the Arduino Mega 16MHz
  AFE_Reg_Write(57, 0);               //Set the lowes sampling rate to 61Hz (~17 ms)
}

/*********************************************************************************************************/
/*                                   AFE4404_Reg_Write                                                   */
/*********************************************************************************************************/
void AFE_Reg_Write (int reg_address, unsigned long data)
{
  byte configData[3];
  configData[0] = (byte)(data >> 16);
  configData[1] = (byte)(((data & 0x00FFFF) >> 8));
  configData[2] = (byte)(((data & 0x0000FF)));
  I2C_write(AFE_ADDR, reg_address, configData, 3);
}

/*********************************************************************************************************/
/*                                   AFE4404_Reg_Read                                                    */
/*********************************************************************************************************/
signed long AFE_Reg_Read(int reg_address)
{
  byte configData[3];
  signed long retVal;
  I2C_read (AFE_ADDR, reg_address, configData, 3);
  retVal = configData[0];
  retVal = (retVal << 8) | configData[1];
  retVal = (retVal << 8) | configData[2];
  if (reg_address >= 0x2A && reg_address <= 0x2F)
  {
    if (retVal & 0x00200000)  // check if the ADC value is positive or negative
    {
      retVal &= 0x003FFFFF;   // convert it to a 22 bit value
      return (retVal ^ 0xFFC00000);
    }
  }
  return retVal;
}

/**********************************************************************************************************/
/*                              Write to AFE on I2C                                                       */
/**********************************************************************************************************/
char I2C_write (int slave_address, int reg_address, byte configData[], int byteCount)
{
  int trans_end = 0;
  signed long retVal;

  Wire.beginTransmission(slave_address);
  Wire.write(reg_address);
  Serial.print(configData[0]);
  Serial.print(",");
  Serial.print(configData[1]);
  Serial.print(",");
  Serial.println(configData[2]);
  retVal = configData[0];
  retVal = (retVal << 8) | configData[1];
  retVal = (retVal << 8) | configData[2];
  Serial.println(retVal);
  Serial.println(reg_address);
  Wire.write(configData, 3);
  Serial.println("test");
  Wire.endTransmission();
  return (trans_end);

  /* while(1)
    {
     if(byteCount == 0)
     {
       Wire.endTransmission();
       Serial.println("test");
       return (trans_end);
     }else{
       //unsigned int reg_data = (unsigned int) *write_data++;
       Wire.write(configData, 3);
       byteCount--;
     }
    }*/
}

/**********************************************************************************************************/
/*                              Read Data of AFE on I2C                                                   */
/**********************************************************************************************************/
char I2C_read(int slave_address, int reg_address, byte *read_Data, int byteCount)
{
  int trans_end = 0;

  Wire.beginTransmission(slave_address);
  Wire.write(reg_address);
  Wire.endTransmission();
  Wire.requestFrom(slave_address, 3);
  while (Wire.available() && (byteCount != 0))
  {
    *read_Data++ = Wire.read();
    byteCount--;
  }
  return (trans_end);
}

void AFEinitRegisters(void) {

  unsigned char i;
  struct Register reg[NUM_REGISTERS];
  reg[0].addr = 0x01; reg[0].val = 0x000050;
  reg[1].addr = 0x02; reg[1].val = 0x00018F;
  reg[2].addr = 0x03; reg[2].val = 0x000320;
  reg[3].addr = 0x04; reg[3].val = 0x0004AF;
  reg[4].addr = 0x05; reg[4].val = 0x0001E0;
  reg[5].addr = 0x06; reg[5].val = 0x00031F;
  reg[6].addr = 0x07; reg[6].val = 0x000370;
  reg[7].addr = 0x08; reg[7].val = 0x0004AF;
  reg[8].addr = 0x09; reg[8].val = 0x000000;
  reg[9].addr = 0x0A; reg[9].val = 0x00018F;
  reg[10].addr = 0x0B; reg[10].val = 0x0004FF;
  reg[11].addr = 0x0C; reg[11].val = 0x00063E;
  reg[12].addr = 0x0D; reg[12].val = 0x000198;
  reg[13].addr = 0x0E; reg[13].val = 0x0005BB;
  reg[14].addr = 0x0F; reg[14].val = 0x0005C4;
  reg[15].addr = 0x10; reg[15].val = 0x0009E7;
  reg[16].addr = 0x11; reg[16].val = 0x0009F0;
  reg[17].addr = 0x12; reg[17].val = 0x000E13;
  reg[18].addr = 0x13; reg[18].val = 0x000E1C;
  reg[19].addr = 0x14; reg[19].val = 0x00123F;
  reg[20].addr = 0x15; reg[20].val = 0x000191;
  reg[21].addr = 0x16; reg[21].val = 0x000197;
  reg[22].addr = 0x17; reg[22].val = 0x0005BD;
  reg[23].addr = 0x18; reg[23].val = 0x0005C3;
  reg[24].addr = 0x19; reg[24].val = 0x0009E9;
  reg[25].addr = 0x1A; reg[25].val = 0x0009EF;
  reg[26].addr = 0x1B; reg[26].val = 0x000E15;
  reg[27].addr = 0x1C; reg[27].val = 0x000E1B;
  reg[28].addr = 0x1D; reg[28].val = 0x009C3F;
  reg[29].addr = 0x1E; reg[29].val = 0x000103;
  reg[30].addr = 0x20; reg[30].val = 0x008025; //0x008003
  reg[31].addr = 0x21; reg[31].val = 0x000125;//0x000003 //bit8: PROG_TG_EN
  reg[32].addr = 0x22; reg[32].val = 0x000100;//ILED2 = 32
  reg[33].addr = 0x23; reg[33].val = 0x000000;
  reg[34].addr = 0x32; reg[34].val = 0x00155F;
  reg[35].addr = 0x33; reg[35].val = 0x00991F;
  reg[36].addr = 0x36; reg[36].val = 0x000190;
  reg[37].addr = 0x37; reg[37].val = 0x00031F;
  reg[38].addr = 0x34; reg[38].val = 0x001563;
  reg[39].addr = 0x35; reg[39].val = 0x00991F;

  for (i = 0; i < NUM_REGISTERS; i++)
    AFE_Reg_Write(reg[i].addr, reg[i].val);

}

```

I am plotting each of the four sensors on LabView. Any help would be much appreciated!

# Answer
Troubleshooting I2C issues can be frustrating. In order to figure out the problem, I recommend you construct the simplest possible Arduino sketch, using just the two sensors that seem to have a problem working together. You should be able to write a very simple program that does nothing but acquire a simple value from each sensor, say 2 times/second.

Once you have the simplest possible program running, you should be able to figure it out. Right now all your program complexity is making it harder than it needs to be.

Good luck!

Frank
> 1 votes

---
Tags: sensors, i2c, mpu6050
---


# Question
Title: RTClib now() within while loop does not update
I ran into this while trying to make a battery monitor and wondered where I went wrong. Using `RTClib` available in the Arduino IDE or from adafruit github, I ran into problems when trying to call `now` within a `while` loop inside of `loop`. Here is a simple example:

```
#include "RTClib.h"

#define ledPIN 13

RTC_PCF8523 rtc;

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPIN, OUTPUT);
  digitalWrite(ledPIN, LOW);
  Serial.begin(9600);
  while(!Serial) {/* wait for Serial */}
  rtc.begin();
  rtc.start();
  digitalWrite(ledPIN, HIGH);
 }

void loop() {
  // put your main code here, to run repeatedly:
  char fmt[] = "YYYY/MM/DD-hh:mm:ss\n";
  while (millis() < 60000){
    Serial.println((rtc.now()).toString(fmt));
    delay(5000);
  }
  Serial.println("Finished");
  digitalWrite(ledPIN, LOW);
  while(1) { /* do nothing forever */ }
}

```

The output of this little test will be the same time repeated every 5ish seconds. If it matters I am using a Feather M0 with the FeatherLogger that has an RTC on it. Changing this `loop` function to this:

```
void loop() {
  // put your main code here, to run repeatedly:
  char fmt[] = "YYYY/MM/DD-hh:mm:ss\n";
  if (millis() < 60000){
    Serial.println((rtc.now()).toString(fmt));
    delay(5000);
  } else {
    Serial.println("Finished");
    digitalWrite(ledPIN, LOW);
    while(1) { /* do nothing forever */ }
  }
}

```

shows that `now` does in fact update the time every 5ish seconds. I looked at the code for `now` and it appears to do very basic i2c commands to get the time and report it back. The only thing I can think of is that the compiler created a (not so) temporary `DateTime` object for me within the `while` loop and the RTC library does not provide a convenient constructor or operator to overwrite the existing object.

I tested my theory with this

```
void loop() {
  // put your main code here, to run repeatedly:
  char fmt[] = "YYYY/MM/DD-hh:mm:ss\n";
  while (millis() < 60000){
    DateTime t1 = rtc.now();
    Serial.println(t1.toString(fmt));
    delay(5000);
  }
  Serial.println("Finished");
  digitalWrite(ledPIN, LOW);
  while(1) { /* do nothing forever */ }
}

```

But again, the time did not change so clearly I don't understand what's happening here. Why doesn't the rtc `now` function work as intended within a `while` loop inside the `loop` function?

# Answer
> 3 votes
See the documentation of `DateTime::toString()`:

> The *buffer* parameter should be initialized by the caller with a string specifying the requested format. This format string may contain any of the following specifiers: \[...\] The specifiers within *buffer* will be overwritten with the appropriate values from the `DateTime`. Any characters not belonging to one of the above specifiers are left as-is.

The important thing to realize is that the `buffer` parameter is used **both** as input (for the format description) and as output (for the formatted date and time). You initialize it with a format description (`"YYYY/MM/DD-hh:mm:ss\n"`). Then, after the first call to `toString()`, the same buffer contains the formatted date and time. It does **not** contain the format description anymore. On the second call to `toString()`, as per the rule “*Any characters not belonging to one of the above specifiers are left as-is*”, the buffer is not modified.

**Solution**: Put the buffer initialization within the same `while` loop as the call to `toString()`.

---
Tags: rtc
---


# Question
Title: ILI9341 backlight flickers when using USB power from Laptop
I've developed a project using am ILI9341, ESP12F and Arduino. Everything works fine except a very annoying issue. The LCD flickers when I use the laptop's USB. But when I use a USB charger it's much better.

I use https://github.com/Bodmer/TFT\_eSPI library for SPI driver and AMS1117 as regulator (with 1uf in the input, and 10uf in output).

I don't think the software has a problem because I don't refresh anything on the display (just draw something in the setup function, not in loop) and also it changes with different power sources. The problem is the backlight.

When I move the USB cable it goes crazier sometimes. I've checked it with many different cables and computers. Is this because of noise or something from the USB port? How can I fix this?

It's very important for me to be able to use the USB port as the power source.

# Update

When I'm uploading the code to the ESP8266 (using TXD & RXI), the LCD doesn't flicker event a little bit! And immediately after finishing the upload, the LCD brightness decreases and starts flickering!

The circuit is pretty simple and LCD pins are connected directly as listed here

# Answer
That happens because not all USB ports can supply more than 500mA of current. When you use a charger's USB port, it is designed to provide more than 500mA of current(ex. 1-2amps in most chargers). Try using a USB port that can provide more than 500mA of current. Most PCs and Laptops will only supply 500mA at maximum unless specified so.

More information regarding USB power can be read here on Wikipedia.

Cheers!
> 3 votes

# Answer
I solve the problem controlling the frecuency of refresh with the led pin. With a timer of 10ms disappears flickering
> 1 votes

# Answer
I fixed this issue finally. The USB could supply both ESP and ILI9341, but the regulator could not. AMS1117 is not able to handle both EPS and ILI9341, we could connect ILI9341 directly to v5 (which it's not good and it would be hot!) or we can use another cheap regulator like XC6206P332MR just for the LCD.
> 0 votes

---
Tags: esp8266, tft
---


title: Stepper motor won't change directions!

text:
# Question
Title: Stepper motor won't change directions!
I am driving a bipolar stepper motor with an a4988 driver using the AccelStepper library. My goal is to press a button and the motor moves CW, then another button for CCW.

I have looked at another post with a very similar issue, but the solution does not seem to apply well to the AccelStepper library, which I would really like to use given its versatility.

Currently, whichever button I press, the motor moves CCW. Any help would be greatly appreciated!

```
#include <AccelStepper.h>
AccelStepper stepperX(1, 3, 2);

void setup() {
  pinMode(8, INPUT)
  pinMode(9, INPUT);

  stepperX.setMaxSpeed(100.0);
  stepperX.setAcceleration(100.0);
}

int moveRight = 1000;              //arbitrarily high number
int moveLeft = -1000;              //arbitrarily low number

void loop() {
  while (digitalRead(8) == HIGH) { //when d8 button is pressed move left
    stepperX.moveTo(moveLeft);     //set move
    if (digitalRead(8) == LOW) {   //if not pressed, kill loop
      stepperX.stop();
      break;
    }
    stepperX.run();
  }

  while (digitalRead(9) == HIGH) { //when d9 button is pressed move right
    stepperX.moveTo(moveRight);    //set move
    if (digitalRead(9) == LOW) {   //if not pressed, kill loop
      stepperX.stop();
      break;
    }
    stepperX.run();
  }
}

```

# Answer
You work with accelleration and absolute positions. Are you aware of that? This Library is not made for running permanently in the same direction. It let you define a position where the movement should end, an acceleration or speed and the controller moves the motor to that position.

The run method must be called permanently, It triggers the steps. So, I put it directly into the `loop()` method.

The following prog should hopefully move the motor towards position 1000 if you press the 8-button, towards position -1000 if you press the 9-button and stops if both buttons are off. I have not the hardware available at the moment, you it's just blind programming. Use it as an idea.

```
#include <AccelStepper.h>
AccelStepper stepperX(1, 3, 2);

void setup()
{
  pinMode(8, INPUT)
  pinMode(9, INPUT);

  stepperX.setMaxSpeed(100.0);
  stepperX.setAcceleration(3.0);
}

int positivePosition = 1000;
int negativePosition = -1000;

void loop()
{
  if ( digitalRead(8) == HIGH )
  {
    stepperX.moveTo(positivePosition);
  }
  else if (digitalRead(9) == HIGH)
  {
    stepperX.moveTo(negativePosition);
  }
  else
  {
    stepperX.stop();
  }
  stepperX.run();
}

```
> 1 votes

---
Tags: motor, button, stepper, stepper-motor
---


# Question
Title: changing bitrate of audio recording and taking samples from audio in arduino
I am looking to make a baby cry detection module that is a part of a bigger project i.e. IOT based baby monitoring system. Using AI, i have a dataset (of baby crying and not crying) to train model using binary classification through logistic regression. The problem is that the dataset has a 10kbps sample rate. and arduino records audio on 192kbps probably. so i need the arduino recorded audio to be 10kbps. secondly i need 100 weights or samples from the arduino recorded audio. so lets say the audio is of 5 seconds, so i need a sample after every 50ms so that the total samples would be 100. the main problem is i don't know how to take samples from an audio being recorded or a prerecorded audio using arduino. The 100 samples would then be multiplied by the 100 samples from the trained model and then added and then sigmoid function will be used so that at the end we can know whether the baby is crying or not. All the deployment of the model will be done in arduino. Any help regarding taking the samples or bitrate, would be much appreciated. Thanks in advance! :)

# Answer
First of all, I am pretty sure your idea of using discrete ADC samples as predictors for your model is hopelessly naive. As explained by Majenko, you cannot expect anything meaningful from a sound recording taken at 20 samples per second. You may have more luck using spectral intensities as predictors. I suggest you start by doing some time–frequency analysis on your training data, just to get some ideas on what predictors may be worth trying. In any case, I strongly suggest you train **and test** your model on your computer, before committing any code to the Arduino.

That being said, sampling a signal at 20 Hz is quite easy: wait for 50 ms (or 50,000 µs for better accuracy), take one sample, repeat. The only caveat is that you have to use `millis()` or `micros()` rather than `delay()` or `delayMicroseconds()`, otherwise the sampling period will be longer than expected because of the time needed to execute the code.

Applying the sigmoid function just to compare the result to 0.5 makes little sense. You know the sigmoid is larger than 0.5 only when its argument is positive, so you can trivially save yourself expensive floating point operations.

Here is a tentative implementation of (my understanding of) the idea you suggest:

```
const uint8_t mic_pin = A0;
const size_t sample_count = 100;
const uint32_t sample_period = 50000;  // 50,000 us = 50 ms
const int weights[sample_count] = { 12, -42, 23 /* etc... */};

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

void loop() {
    // Record the samples.
    int samples[sample_count];
    uint32_t last_sample = micros();
    for (size_t i = 0; i < sample_count; i++) {
        while (micros() - last_sample < sample_period) { /* wait */ }
        samples[i] = analogRead(mic_pin);
        last_sample += sample_period;
    }

    // Compute the weighted sum.
    long sum = 0;
    for (size_t i = 0; i < sample_count; i++) {
        sum += (long) samples[i] * weights[i];
    }

    // Predict.
    if (sum >= 0) {
        Serial.println("The baby is crying!");
    }
}

```
> 1 votes

---
Tags: audio
---


title: Arduino send commands fast

text:
# Question
Title: Arduino send commands fast
I need cnc machine to run as smooth as possible.

It receives commands like this "M\_XY 10.233 20.123".

If i send command by command there is a slight delay between commands and its noticeable. I set serial timeout to 5 ms.

I tried to send n commands and store them on arduino, but arduino cant store much in ram. There is a huge delay while sending n commands.

I was thinking about converting letters (machine writes letters) to bezier and sending arc by arc or letter by letter in arcs. Can atmega328p interpolate bezier fast enough?

Would it be faster if i send numbers in bytes instead of strings? That would be 4 bytes per float and merge with union on arduino.

Is there any better way of doing this i don't know of?

Edit: This is how string commands are processed.

```
void addCommByte(const byte b){
  if(commID == MAX_COMM+1){
    commID = 0;
    Serial.println("TOO LONG COMMAND");
    Serial.flush();
    return;
  }

  if(b == '\n'){
    comm[commID] = '\n';
    commID = 0;

    processCommand();
  }
  else if(b == '\r')
  {
    commID = 0;
  }
  else
  {
    comm[commID++] = b;
  }
}

void loop() {
  Serial.flush();
  while(Serial.available() > 0) {
    addCommByte(Serial.read());
  }
}

```

Edit. Way better way.

C# side. Check for endianness in c#. Arduino is little endian.

```
        public void MOV_X(float mm)
            {
                SendCharAsByte("q"[0]);
                SendFloatAsBytes(mm);
            }
        public void SendFloatAsBytes(float f)
        {
            byte[] vOut = BitConverter.GetBytes(f);
            serialPort.Write(vOut, 0, 4);
        }

        public void SendShortAsBytes(short f)
        {
            byte[] vOut = BitConverter.GetBytes(f);
            serialPort.Write(vOut, 0, 2);
        }

        public void SendCharAsByte(char c)
        {
            byte[] aaa = new byte[1];
            aaa[0] = (byte)c;
            serialPort.Write(aaa, 0, 1);
        }

```

Arduino side.

```
void loop() {
  while(Serial.available() > 0) {
    processV2(Serial.read());
  }
}
// from processV2
if(byt == 'q'){   // mov x
    float mm = readFloat();
    if(X_DIR == 1) mm *= -1.0;

    stepperXY.moveXForMMSync(mm);
    Serial.println("p");
    return;
  }
// merge bytes
union u_tag {
   byte b[4];
   float fval;
} u;

float readFloat(){
  Serial.readBytes(u.b, 4);
  return u.fval;
}

```

There is no need to flush serial.

# Answer
> 1 votes
If you have an existing CNC, you may have to abide by its comm protocol. Otherwise, if the Arduino is part of a CNC you are building, and it is supposed to accept commands from a host computer, the first thing to do is make sure your baud rate is set higher than the default. I have found 115200 to be a good choice for stability. Next, you should avoid sending TTY-type text strings, and send binary values instead. You'd send an initial byte or word to specify the command type, followed by the data. In my open-source DaqPort sketch for high-speed data acquisition https://www.daqarta.com/dw\_rraa.htm I use the high nybble of the command to specify the general type, and the low nybble to specify more detail like channel number. The sketch uses a big loop with if(Serial.available() \> 0) to read the first byte, and a switch/case to determine what to do. The the specific command reads the proper number of bytes and does whatever. This is *way* faster than having to parse text and convert to binary.

---
Tags: arduino-uno
---


# Question
Title: How to flash a NodeMCU (ESP8266) with an external FTDI programmer?
Hi my USB to UART bridge (CP2102) seems to be broken on one of my NodeMCU Dev Boards with ESP8266.

It seems to be just that specific board since all other boards that I have can be flashed without problems. I have a FTDI Programmer like this one: FTDI Programmer

Now I would like to flash the Nodemcu using the FTDI programmer but I'm not sure how to wire it up. I know that those programmers cant power up the ESP8266 by itself thats why I would use a micro USB cable that doesnt have a data wire to power up the nodemcu.

This is how I would wire everything up:

Is this the correct way to wire up the programmer with the nodemcu? I want to be sure that nothing is going to mess up with the nodemcu or the programmer.

NodeMCU FTDI GND ----\> GND RX ----\> TX TX ----\> RX

# Answer
> 1 votes
Assuming your FTDI Basic is the 3.3V version, then yeah that will work fine provided you that manually reset the board yourself and enter the boot-loader using the buttons.

If you're independently powering the boards you may want to insert some series resistance in the RX and TX connections in case your signal receiving end is not powered while the sending side is. In short you don't want the TX signal from one of your devices (boards) trying to power the receiving device (board) through its protection/clamp diodes.

In regard to comment about resistor value: The value of the resistor depends on what you can get away with in terms of its effect on the signal and how much current is allowed through the clamp diodes on the other board. A couple of Kbyte is probably sufficient, better than nothing in any case. Use a bit more if you can and still get a reliable signal through. If you have the boards both powered before you connect them and you're careful about connecting them, then there's no opportunity for that. It may also just be that they're robust enough that you don't need them at all. I usually put some in though. The second reason which I didn't state above is just that it protects you from being outright stupid and accidentally connecting them to the wrong thing; wrong signal, or to VCC or GND on the other side.

---
Tags: esp8266, nodemcu, ftdi, programmer
---


title: Problem with my usb plug

text:
# Question
Title: Problem with my usb plug
First of all, we connected our usb plug to arduino board (starter kit). After that, we completed Project 1 successfully (circuit with led and switch.) We tried unplug the usb cable, but it was very difficult, we had to pull very hard, but we couldn't unplug it. Finally, I managed to take it away with the help of my partner. I was pulling the usb and my partner was keeping the arduino board stable. The result wasn't very nice, we probably broke the usb cable. You can see what I mean in these images, the metallic coating part of the cable is still stuck on the board.

https://ibb.co/6wtf02J

https://ibb.co/4pZg2w0

https://ibb.co/WPchtgN

https://ibb.co/gPHZYnt

Nevertheless, we put the remaining cable back where it was, and the board seems to be working normally.

My question is if it safe to use it. Is there any chance of electrical damage or something like that?

Thank you!

P.S. In addition, we are planning to buy a new arduino starter kit. How can we avoid this problem with the new board?

# Answer
Without the center part of the USB plug, it should be possible to make some deformations of that shield without damaging rest of the usb connector and pull it out. Aim for the weakest spot - seam (usually in the middle of bottom).

But even if you damage on board connector, it can be replaced (but it might be better to give it to someone with soldering experience - at least for unsoldering it)

And as noted in comments, even without working usb connector it can be programmed either by connecting USB-TTL serial converter to D0/D1 (but without auto-reset, unless you provide 100nF capacitor between reset and RTS), or it can be programmed by another Arduino as SPI (it needs bit more wires, and by default it doesn't burn bootloader, so if you fix USB, you'll have to burn bootloader). Easier might be swapping Atmega328p between boards, however it needs some practice, so you won't bend or rip pins)
> 1 votes

---
Tags: usb
---


title: Reading bits from a const char pointer

text:
# Question
Title: Reading bits from a const char pointer
I'm getting a bit tripped up on const char pointers lately.

I'm getting a message from a server that comes through as either a c style string, a standard library string, or a WString:

I'm sending down a buffer of 32bit values from my server that aren't ascii or utf text, they're just bit values I want to parse and read on the esp32 side:

I thought "oh, I'll just mask the bit values 32 bits at a time and right shift the data to get the message (in reverse order, but still I can work with that). The problem that I'm running into is that I can shift numbers but not strings or byte arrays.

I wrote out a function to allow me to grab a piece of the string 32 bits at a time and convert that into a number while using an offset:

```
uint_fast32_t get32BitInt(const char *data, int offset = 0)
{

  uint32_t payload = 0;
  for (uint8_t i = 0; i < 8; i++)
  {
    payload <<= 0;
    payload += data[i + offset];
  }
  return payload;
}

```

But when I try to grab the first couple of 32 bit chunks the data isn't what I expected:

```
void handleGameFrame(const char *data, uint32_t length)
{

  uint8_t phaseAndColission = get32BitInt(data, 32);
  uint8_t player = getByte(data, 32 * 2);

  Serial.print("data: ");
  Serial.println(data);
  Serial.print("phaseAndColission: ");
  Serial.println(phaseAndColission, DEC);
  Serial.print("player: ");
  Serial.println(player, DEC);

}

```

yields:

I know the `Serial.println(data);` isn't going to output anything b/c it's a c-string of non-printable values, but the other chunk grabbing isn't giving me the same output from my server. It's hard to verify everything without being able to see all of the bits in the overall `data` pointer and I think I tied myself in (another) knot.

Is there a good way to parse 32 bit values out of a const c-string?

# Answer
You wrote:

> I wrote out a function to allow me to grab a piece of the string 32 bits at a time and convert that into a number while using an offset

This function is almost correct. Try this:

```
uint_fast32_t get32BitInt(const char *data, int offset = 0)
{

  uint32_t payload = 0;
  for (uint8_t i = 0; i < 4; i++)
  {
    payload <<= 8;
    payload |= data[i + offset];
  }
  return payload;
}

```

Compared to your version, the differences are:

* It reads 4 bytes instead of 8, as 32 bits are four bytes.
* For each byte being read, it shifts the payload by 8 bits (i.e. one byte) instead of zero. Shifting by zero has no effect.
* It uses `|=` instead of `+=`: just a micro-optimization for the sake of 8-bit MCUs. It shouldn't make much if a difference on a 32-bit micro.
> 1 votes

---
Tags: c-string
---


title: Arduino MKR GMS alternative

text:
# Question
Title: Arduino MKR GMS alternative
I’m starting on a project about monitoring the soil in the agriculture field and also to visualise the data remotely. The aim of this project is collect the atmospheric data as well as the soil related parameters and then send them to cloud where they’ll be presented on the dashboard. I decide to use Arduino as my development board and Arduino MKR GMS 1400 would be perfect for this project. However this board is quite expensive. So just wondering that are there any alternative I can use for this project

Thank you

# Answer
> 2 votes
There are multiple options for this project as you just want to send/ upload data on the cloud server rather than using Arduino MKR 1400 you can use any of the following.

1. Arduino UNO with GSM module: As per your requirement you can use Arduino UNO to read the data from the sensor and the GSM module will be used to upload the same on the cloud server. There are various GSM modules available in the market which are cheap also and good. You can also use SIM800 one of the GSM module.

Other GSM modules which you could use can be,

SIM900, Quectel EC-20, Quectel M95. You can also visit SIMCONN website where you can find multiple GSM module options.

2. You can also use ESP8266 or ESP32 which are Wi-Fi modules but in this case you will require a internet/ Wi-Fi connection near the controller. ESP8266/ ESP32 will read data from the sensors and can also upload the same to the cloud servers. But as you said you are using them to monitor agriculture field it won't be possible to have a Wi-Fi which will cover such long range.
3. One of the possible solutions to the problem is to use RF-link to transmit data and collect it at a base-station and from the base station you can upload/ send them to the server.
4. You can also make use of the LoRa Network to communicate along the fields and then receive data from the whole field at a base station and then upload them to the server. But this could be a more expensive solution.

---
Tags: iot, data
---


# Question
Title: Convert fuel level sender resistance ranges - good Arduino project?
I've noodled around with Arduino a bit, worked some tutorials. I have an engineering & programming background, but electronics isn't my first language. So apologies if this is a dumb question.

Here's the problem. I've swapped a 2007 GM engine into an older Toyota Land Cruiser. I need to make it compliant with the emissions equipment that was originally on the 2007 vehicle. Most of that is pretty straight forward - catalytic converters, O2 sensors, charcoal canister, purge & vent solenoid valves, a pressure sensor. The one bit I haven't figured out yet is fuel level. The evaporative emissions system requires a fuel level input to the PCM (Powertrain Control Module) so it can figure out when & how to run the fuel system pressure test - the one that turns on your check engine light if your gas cap isn't on tight enough.

One solution would be to put in a GM fuel level sender ... but that involves draining the tank, dropping it, maybe cutting new holes, more wiring, etc. I'm hoping I can fix this in software :)

The GM fuel level sending unit reads 0 ohms empty and 90 ohms full. The existing Toyota sending unit should be 110 ohm empty and 3 ohm full.

So ... is it a feasible thing to build an Arduino based project that reads the resistance from the Toyota sender (without interfering with the Toyota gauge) and translates that to the range expected by the GM PCM?

I'm thinking something like this is the core of it: https://www.arduino.cc/en/Tutorial/LibraryExamples/DigitalPotControl But I don't know what I don't know.

Thanks folks - additional information based on responses:

The Toyota sender is definitely a 12V two terminal unit. Car electrical systems are nominally 12V, but typically are about 13.3V in operation.

The GM sensor is two terminal also. According to the wiring diagram, one terminal goes to a low reference pin on the PCM and the other goes to a pin on the PCM labeled fuel level signal.

But it doesn't tell you the voltage they're applying on that pin - could be just 5V, other stuff coming out of the PCM is. I couldn't find a test procedure either. I'll pin that connector and see what I can measure next time I'm out there.

The fuel level signal is used for two things in the evaporative emissions (evap) system.

1. The evap vacuum test can only run when the tank is between approximately 1/3 to 2/3 full.
2. The vacuum test is calibrated against how full the tank is - lower fuel level means more air space in the tank means the pressure will change more slowly then compared to a fuller tank.

# Answer
The Toyota sensor may be using 12V instead of 5V, which would mean you'd need to use a voltage divider to get it down to the range that the Arduino analog inputs can read.

You will need to find a digital potentiometer that can handle the voltage range that the GM controller wants to see. This may be 0-12V, which would be a problem since the AD5206 is only good for 5V.

However, as dandavis implies with his RC filter comment, you may be able to simulate the full 0-12V range with PWM, where the Arduino pin drives a transistor to chop up the 12V, and an RC filter smooths the result for the GM control unit. That's probably your best approach.

Alternatively, if the GM controller is only looking for a go/no-go level, you can use the transistor to switch in a simple voltage divider to get the right voltage from 12V.

The sensors are (presumably) just variable resistors (2-terminal) not full 3-terminal potentioneters. They will most likely be using a series resistor to make a voltage divider, and the control unit (or gage in the Toyota) will reading the resulting voltage. You will want to either find out the value of the series resistor or measure the voltage that the gage sees. It might already be in the 0-5V range. The GM control unit may have the series resistor built in (or be using a current source), in which case you should measure the voltage its sensor input sees when you give it the max and min resistance. This will be good to know when you are trying to drive it with your own circuit,
> 1 votes

---
Tags: sensors
---


title: I2C Devices Interference

text:
# Question
Title: I2C Devices Interference
I am currently trying to connect 3 I2C Devices to an Arduino Mega, as detailed in the fritzing sketch. The Sensors are: Max86150 PPG Sensor on a breakout board (5v), MLX90614 IR Temperature Sensor (3.3V) and a SM9336 Pressure Sensor(3.3V). Essentially I can connect all devices and read off the sensors using individual sketches, but when I combine the sketches the values are not consistent and then the sketch crashes after only a few seconds.

Weirdly enough, when I combine a sketch with either the Temperature sensor and the Pressure sensor or the Temperature Sensor and PPG Sensor, it will work. But Pressure and PPG do not work together.

Does anyone have any idea what could be happening? I did have it working for a small while with some different wires, could this have anything to do with it? But even still some results I was reading from the sensor were the error values (e.g. the value you get when there is nothing connected, but it wasn't crashing). For reference I am using 30 AWG wires and strip board instead of the breadboard in the Fritzing.

```
//PPG
#include "max86150.h"
MAX86150 max86150Sensor;
uint16_t ppgunsigned16;
uint16_t irdata;

// Pressure Sensor
#include <Wire.h>

#define PressureSensor_Data 0x30 // Pressure Register address
#define TemperatureSensor_Data 0x2E // Pressure Temp Sensor Address

int P0,T0,P1,T1;
int SMD993Address = 0x6C; // Device Address

//Timing
#define INTERVAL 10 //10 milliseconds per sample for 100 Hz, change this for different sampling rates.
uint32_t lastMicros = 0;

// Temp
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void ppgsetup()
{
  max86150Sensor.setup();
}

void PPG() {

while (1){
 if(max86150Sensor.check()>0)
    {
        ppgunsigned16 = (uint16_t) (max86150Sensor.getFIFORed()>>2);

        Serial.println(ppgunsigned16);
  //ppgunsigned16 = (uint16_t) (max86150Sensor.getFIFORed()>>2);
  //Serial.println(ppgunsigned16);

  if (ppgunsigned16 > 7000){

     for (int z = 0; z <= 500; z++){//This takes a reading every 10 milliseconds for 5000 milli seconds which is 5 seconds, 500 readings
       digitalWrite(ledPin,HIGH);//turning LED on
        //if (micros() - lastMicros > INTERVAL) { //This takes a reading every 100th of a second
            //lastMicros = micros(); // do this first or your interval is too long!

            if(max86150Sensor.check()>0)
    {
        ppgunsigned16 = (uint16_t) (max86150Sensor.getFIFORed()>>2);
        irdata = (uint16_t) (max86150Sensor.getFIFOIR()>>2);

        Serial.print(ppgunsigned16);
        Serial.print(",");
        Serial.println(irdata);
            //Serial.print("Check PPG");Serial.println(y);
            //mySerial.write(84);mySerial.print(ppgunsigned16);mySerial.print("/");
            //mySerial.write(83);mySerial.print(irdata);mySerial.print("/");
    }
    }
    digitalWrite(ledPin,LOW);//turning LED off
    break;

}
}
}
}

void spirometry() {

    for (int x = 0; x <= 500; x++){
    Wire.beginTransmission(SMD993Address);
    Wire.write(PressureSensor_Data);
    Wire.write(TemperatureSensor_Data);
    Wire.endTransmission();
    Wire.requestFrom(SMD993Address,2);//This takes a reading every 100 milliseconds for 10000 milli seconds which is 10 seconds

    //if (micros() - lastMicros > INTERVAL) { //This takes a reading every 1000th of a second
      //lastMicros = micros(); // do this first or your interval is too long!

    if(Wire.available()<= 2) {
    P0 = Wire.read();
    P1 = Wire.read();
      }

    int Ptotal = P0 + (P1<<8); //The high byte is transmitted second so that

    Serial.println(Ptotal); // Print Ptotal to the serial monitor
    //mySerial.write(81);mySerial.print(Ptotal);mySerial.print("/");// Send PTotal over BLE with flag 81, this will change as sending via bytes is more efficient

    }

  }

void temperature() {
  for (int y = 0; y <= 10; y++){
      mlx.begin();
      Serial.println(mlx.readObjectTempC());
      mySerial.write(82);mySerial.print(mlx.readObjectTempC());mySerial.print("/");
      delay(10);
}
}

void setup() {

  // BT
  mySerial.begin(9600);
  Serial.begin(9600);//Sets BT Serial Comms to 115200, ensure that BT is allowing for this
  //LED
  pinMode(ledPin, OUTPUT);
  // PPG
    // Initialize sensor
    if (max86150Sensor.begin(Wire, I2C_SPEED_FAST) == false)
    {
        Serial.println("MAX86150 was not found. Please check wiring/power. ");
        while (1);
    }
    Serial.println(max86150Sensor.readPartID());
    ppgsetup();

  //Pressure Sensor

  //Temp

  //Sleep
  sleep();

}

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

   PPG();
   delay(10000);
   spirometry();
   delay(1000);
   temperature();

}

```

# Answer
I had a similar problem sometime ago, where I attached 2 servo driver boards and a battery hat (that used I2C for reading power levels) to a Raspberry Pi. The battery board worked alone and the servo boards worked alone, but when all three were present, the battery board stopped working. And all had unique addresses. After a few hours of going nuts, I realised that there were pullup resistors on the pi and all three boards attached. The total resistance of all 4 parallel pullup resistors were out of spec for I2C. I removed the resistors from the servo boards and everything started working together. So maybe you could disable the pullups on all baords except the Arduino and see if that is the problem.
> 2 votes

# Answer
As pointed out by @peterpaulkeifer; Here

```
// Initialize sensor
    if (max86150Sensor.begin(Wire, I2C_SPEED_FAST) == false)
    {
        Serial.println("MAX86150 was not found. Please check wiring/power. ");
        while (1);
    }

```

I was setting the I2C Speed of the I2C Interface bus to fast and it seems that the pressure sensor was not able to handle this and would therefore give error answers and then crash.
> 2 votes

---
Tags: i2c, communication
---


title: Sense person connected to TENS unit

text:
# Question
Title: Sense person connected to TENS unit
So let's say I use a store-bought TENS unit for liability. I want to make a challenge where you need to hold on to the TENS unit for 10 seconds before it activates a solenoid. How can I have an Arduino detect if someone is touching some metal posts connected to the unit? Would I need to measure the current for the tens unit or something? Any ideas/suggestions? Thanks!

Edit- Not sure if this should be in Arduino or Electrical Engineering, feel free to move it.

# Answer
> 1 votes
I think the main problem here is that you want to measure in the presence of high voltage from the TENS. Not having experience with TENS circuits, I would suppose that their contact pins are connected to the high voltage source through resistors to limit the current. (Or some equivalent current-limiting scheme.) If so, the voltage between the contacts should drop when there is a person connected. You should be able to detect that drop with the Arduino. The "obvious" approach would be to use voltage dividers to reduce the no-load voltage to less than 5V so the Arduino ADCs can handle it. You'd need high-value resistors in the dividers so they don't load the TENS... maybe 1 Megohm or more for each divider. One problem with this simplistic approach is that the TENS is putting out its stimulus using brief pulses, which may be too quick to catch with the ADCs. To get around that, you'd feed the output of each divider through a diode to an R-C filter. (Note that you need the diode anyway, since the TENS output is probably AC and the Arduino ADCS only want DC.) This may take a fair amount of experimentation to get the values right, which you should do *without* the Arduino... just a DVM or scope that you can start at a high-voltage range until you sure you have everything worked out to 0-5V.

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