body:
I have the following very basic program that reads MPU6050(accelerometer and gyroscope) sensor using the I2C library, and prints the sensor information. This program works as expected.

````
#include <Arduino.h>
#include <MPU6050_6Axis_MotionApps20.h>

inline void printToSerial(bool, bool) __attribute__((always_inline));

MPU6050 imu;
int16_t ax, ay, az, gx, gy, gz;

void setup() {
  imu.initialize();

  imu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  imu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);

  imu.setXAccelOffset(-1451);
  imu.setYAccelOffset(-682);
  imu.setZAccelOffset(1448);
  imu.setXGyroOffset(69);
  imu.setYGyroOffset(-16);
  imu.setZGyroOffset(29);
  Serial.begin(9600);
}

void loop() {
  imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  printToSerial(false, true);
  delay(50);
}

void printToSerial(bool a, bool g){
  if(a){
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.println(az);
  }

  if(g){
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
  }
}
````

But as I want to add more functionality to the main program - I want to move MPU6050 specific code to separate file.

So, I created `Sensor.h` with the following content,
````
#ifndef SENSOR_H
#define SENSOR_H

#include <MPU6050_6Axis_MotionApps20.h>

extern MPU6050 imu;
extern int16_t ax, ay, az, gx, gy, gz;

void sensorInit();
void sensorUpdate();

#endif
````

And placed the implementation in the `Sensor.cpp` file.

````
# include "Sensor.h"

void sensorInit(){
  imu.initialize();

  imu.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  imu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);

  imu.setXAccelOffset(-1451);
  imu.setYAccelOffset(-682);
  imu.setZAccelOffset(1448);
  imu.setXGyroOffset(69);
  imu.setYGyroOffset(-16);
  imu.setZGyroOffset(29);
}

void sensorUpdate(){
    imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
}
````

And finally, modified the `main.cpp` file in the following way,

````
#include "Sensor.h"
#include <Arduino.h>

inline void printToSerial(bool, bool) __attribute__((always_inline));

void setup() {
  sensorInit(); // replaced few lines of codes
  Serial.begin(9600);
}

void loop() {
  sensorUpdate(); // replaced few lines of codes
  printToSerial(false, true);
  delay(50);
}

void printToSerial(bool a, bool g){
  if(a){
    Serial.print(ax); Serial.print("\t");
    Serial.print(ay); Serial.print("\t");
    Serial.println(az);
  }

  if(g){
    Serial.print(gx); Serial.print("\t");
    Serial.print(gy); Serial.print("\t");
    Serial.println(gz);
  }
}
````

But when I try to build the code, I get the following error in the linking step,

```
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpInitialize()'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpPacketAvailable()'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(long*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(long*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(long*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGyro(VectorInt16*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGravity(int*, unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetEuler(float*, Quaternion*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpProcessFIFOPacket(unsigned char const*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetFIFOPacketSize()'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\build\uno\src\main.cpp.o (symbol from plugin): In function `MPU6050::dmpInitialize()':
(.text+0x0): multiple definition of `MPU6050::dmpGetCurrentFIFOPacket(unsigned char*)'
.pio\build\uno\src\Sensor.cpp.o (symbol from plugin):(.text+0x0): first defined here
.pio\libdeps\uno\I2Cdevlib-MPU6050/MPU6050.h:436:7: warning: type 'struct MPU6050' violates one definition rule [-Wodr]
 class MPU6050 {
       ^
.pio\libdeps\uno\I2Cdevlib-MPU6050\MPU6050.h:436:7: note: a different type is defined in another translation unit
 class MPU6050 {
       ^
.pio\libdeps\uno\I2Cdevlib-MPU6050/MPU6050.h:1036:18: note: the first difference of corresponding definitions is field 'dmpPacketBuffer'
         uint8_t *dmpPacketBuffer;
                  ^
.pio\libdeps\uno\I2Cdevlib-MPU6050\MPU6050.h:436:7: note: a type with different number of fields is defined in another translation unit
 class MPU6050 {
       ^
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o: In function `MPU6050::getDeviceID() [clone .constprop.29]':
<artificial>:(.text+0xbba): undefined reference to `imu'
<artificial>:(.text+0xbd0): undefined reference to `imu'
<artificial>:(.text+0xbd4): undefined reference to `imu'
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x10c): undefined reference to `imu'
<artificial>:(.text.startup+0x11c): undefined reference to `imu'
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o:<artificial>:(.text.startup+0x12a): more undefined references to `imu' follow
C:\Users\iamcr\AppData\Local\Temp\cc1jV0kL.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x282): undefined reference to `ax'
<artificial>:(.text.startup+0x286): undefined reference to `ax'
<artificial>:(.text.startup+0x28a): undefined reference to `imu'
<artificial>:(.text.startup+0x28e): undefined reference to `imu'
<artificial>:(.text.startup+0x298): undefined reference to `ay'
<artificial>:(.text.startup+0x29c): undefined reference to `ay'
<artificial>:(.text.startup+0x2a0): undefined reference to `imu'
<artificial>:(.text.startup+0x2a4): undefined reference to `imu'
<artificial>:(.text.startup+0x2ae): undefined reference to `az'
<artificial>:(.text.startup+0x2b2): undefined reference to `az'
<artificial>:(.text.startup+0x2b6): undefined reference to `imu'
<artificial>:(.text.startup+0x2ba): undefined reference to `imu'
<artificial>:(.text.startup+0x2c4): undefined reference to `gx'
<artificial>:(.text.startup+0x2c8): undefined reference to `gx'
<artificial>:(.text.startup+0x2cc): undefined reference to `imu'
<artificial>:(.text.startup+0x2d0): undefined reference to `imu'
<artificial>:(.text.startup+0x2da): undefined reference to `gy'
<artificial>:(.text.startup+0x2de): undefined reference to `gy'
<artificial>:(.text.startup+0x2e2): undefined reference to `imu'
<artificial>:(.text.startup+0x2e6): undefined reference to `imu'
<artificial>:(.text.startup+0x2f0): undefined reference to `gz'
<artificial>:(.text.startup+0x2f4): undefined reference to `gz'
<artificial>:(.text.startup+0x30c): undefined reference to `gy'
<artificial>:(.text.startup+0x310): undefined reference to `gy'
<artificial>:(.text.startup+0x328): undefined reference to `gz'
<artificial>:(.text.startup+0x32c): undefined reference to `gz'
```

Main.cpp, Sensor.cpp and Sensor.h files are in the same directory. I am using PlatformIO to build and deploy the code on an Arduino Uno and the platformio.ini file content is the following,

```
[env:uno]
platform = atmelavr
board = uno
framework = arduino
lib_deps = jrowberg/I2Cdevlib-MPU6050@0.0.0-alpha+sha.fbde122cc5
```

I am wondering what is causing the linking errors.

title: Splitting up code in multiple files causing `multiple definition` and `undefined reference` error

Answers: 1

body:
The failing is not with your code. The failing is with the MPU6050_6Axis_MotionApps20.h library. It erroneously has code in the header rather than in a separate CPP file.

You have done everything right. The author of that library could do well in taking a leaf out of your book.

To get it working you will have to move the code out of the header file into the .cpp file - or move it to reside inside the class definition and make it `inline`.


body:
I'm trying to read an analog input on the Attiny85 physical pin 6 (PB1, PWM), but analogRead(PB1) always returns 1023. Is it even possible to use analogRead on this pin?
I'm fairly new to this so sorry if it's an obvious answer.
Thanks!

title: Attiny : Is it possible to analog read on PB1?

Answers: 1

body:
PB1 has no analog input. So no, you can't read analog with it.

For analog you must use any of PB2 through PB5.


body:
I am trying to use I2C to communicate between my XBee3 (controller) and an adafruit trinket m0 (peripheral). I'm pretty confident I have the modules connected properly (trinket SCL/pin 2 to xbee SCL/pin DIO1 & trinket SDA/pin 0 to xbee SDA/pin DIO11, and both grounds are connected). Here is my arduino code on the trinket:
```
#include <Wire.h>

void setup()
{
Wire.begin(72); // join i2c bus
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
Serial.print("Waiting for data...");
}

void loop()
{
delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
(void)howMany; // avoid compiler warning about unused parameter

while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
```
and here is my code on the XBee:
```
from machine import I2C

# Instantiate an I2C peripheral.
i2c = I2C(1)
slave_addr = 72
i2c.writeto(slave_addr, b'123', False)
```
Additionally, when I run an i2c.scan() on the xbee with an ISM330DHCX connected to the xbee's I2C, the address pops right up. But when I use the exact same code with the xbee connected to the trinket m0, the xbee cannot find any devices. (Code pasted below)
```
from machine import I2C

# Instantiate an I2C peripheral.
i2c = I2C(1)

# Scan for I2C slaves connected to the interface and print their address.
for address in i2c.scan():
    print("- I2C device found at address: %s" % hex(address))
```
Does anyone have any ideas what I'm doing wrong with configuring the trinket m0 to be an i2c peripheral? Thank you!

title: Configure Trinket M0 as I2C peripheral

Answers: 1

body:
I have two Adafruit Trinket M0 arduino boards running on my bench right now talking to each other over I2C. The trick is that you need to install a pull-up resistor between SDA and +3V, and another one between SCL and +3V. Typically it is the peripheral boards that come with those but when you talk between two microcontrollers which are often used as the master controller themselves they are open drain or not powerful enough to drive the bus. Any resistor between 4.7k and 10k ohms should do.

see the following reference doc:

https://docs.particle.io/cards/firmware/wire-i2c/pull-up-resistors-i2c/

From the other direction if you have many peripheral boards that all include their own pull up resistors, the combined resistance on the bus may low enough leak enough current to raise "low" state above 0.4v, at which point communication may have errors.

Or if the wires are too long or there are too many devices without enough pull up resistance (thus too much inherent capacitance) it will take too long for the data lines to reach the "high" state, and you will have to slow down the clock rate or add a signal booster like the LTC4311 (e.g. Adafruit product #4756) to get stable results.


body:
I have an Arduino Mega 2560 and a HM10 Bluetooth module ([this one][1])

I have connected the Bluetooth according to the manufacturer's specifications:
VCC -> 5v
GND -> GND

TXD and RXD of the Bluetooth, I have tried to put them in pins of Arduino, in Serial1, in Serial2, in Serial3, with the same result.

The code I use for my tests is this:

    #define BTserial Serial1

    int LED_BOARD = 13;
    int LED_RED = 2;
    int LED_GREEN = 3;

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

        pinMode(LED_BOARD,OUTPUT);
        pinMode(LED_RED,OUTPUT);
        pinMode(LED_GREEN,OUTPUT);
    }

    void loop() {
        if (Serial1.available()) {
            dato = Serial1.readStringUntil('\n');

            Serial.println("DATA RECEIVED: [" + String(dato) + "]");

            if (dato.equals("1")) {
                digitalWrite(LED_BOARD, HIGH);
            }
            if (dato.equals("0")) {
                digitalWrite(LED_BOARD, LOW);
            }

            if (dato.equals("RED_ON")) {
                digitalWrite(LED_RED, HIGH);
            }
            if (dato.equals("RED_OFF")) {
                digitalWrite(LED_RED, LOW);
            }

            if (dato.equals("GREEN_ON")) {
                digitalWrite(LED_GREEN, HIGH);
            }
            if (dato.equals("GREEN_OFF")) {
                digitalWrite(LED_GREEN, LOW);
            }
        }
    }

I have an Android phone, and I use the Arduino Bluetooth Controller (HM-10 Module) app.

- I send the text 1, and the led of the Arduino board (pin 13) turns on.
- I send the text 0, and the led of the Arduino board (pin 13) turns off.
- I send RED_ON, and the led of my breadboard, connected to pin 2, turns on
- I send RED_OFF, and the led of my breadboard, connected to pin 2, turns off
- I send GREEN_ON, and the led of my breadboard, connected to pin 3, turns on
- I send GREEN_OFF, and the led of my breadboard, connected to pin 3, turns off

So the Bluetooth works.

My problem is trying to see the list of Bluetooth commands (AT+HELP command).

I have a method that is responsible for sending AT+HELP to bluetooth, but I have no response.

This is the method, which I run in the main:

    String str_ii = "";
    int ii_0 = 0;
    void ble_help(){
        Serial.println("ble_help");

        BTserial.println("AT+HELP"); // list all AT+ commands
        while (true){ // loop to print all AT+ commands
            char in_char = BTserial.read();
            if (int(in_char)==-1 or int(in_char)==42){
                continue;
            }
            str_ii+=in_char;
            if (in_char=='\n'){
                if (str_ii==String('\r')+String('\n')){
                    if (ii_0 == 0){
                        ii_0 = 1;
                        continue;
                    }
                    break; // break after more than 1 empty carriage return and newline
                }
                Serial.print(str_ii);
                str_ii = "";
            }
        }
    }

When executing this method, in application Arduino Bluetooth Controller (HM-10 Module) app i see the text AT+HELP, but there is no reaction / response from the bluetooh. Neither in the Arduino Bluetooth Controller (HM-10 Module) application nor in the Arduino serial monitor

What am I doing wrong?

Thank you.

  [1]: https://www.amazon.es/gp/product/B06WGZB2N4/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1

title: Arduino Mega 2560 + BLE HM-10 - I cannot execute AT commands

Answers: 1

body:
First thing first you can see all AT commands available from the data sheet available from [datasheet][1]

Second to get strings from Serial to BTserial you can just use `c = Serial.readStringUntil('\n');` like here

    #define BT_RX           0
    #define BT_TX           1
    #define BT_Serial       Serial1
    #define BT_Timeout      100

    String c, c2;

    void setup() {
      BT_Serial.setTX(BT_TX);
      BT_Serial.setRX(BT_RX);
      BT_Serial.begin(9600);//baudrate
      BT_Serial.setTimeout(BT_Timeout); //set bluetooth read/write timeout

      Serial.begin(9600);
      Serial.setTimeout(100);
      delay(100);
    }

    void loop()
    {
      if (Serial.available()) {
        c = Serial.readStringUntil('\n');
        Serial.println(c);
        BT_Transmit_AT(c);
      }
      if (BT_Serial.available()) {
        c2 = BT_Serial.readStringUntil('\n');
        Serial.println(c2);
      }
      delay(20);
    }

    void BT_Transmit_AT(String data) { //send AT commands
      unsigned long current_time = millis();
      while (BT_Serial.available() > 0) {
        if (millis() - current_time > 100){ //timer to get out incase not receiving anything
          Serial.println("Timeout");
          break;
        }
      }
      BT_Serial.print(data);
    }

And lastly you need to make sure your HM-10 is genuine/has genuine firmware installed or it's a clone. Check if it respond to "AT" with "OK" at all. If it does then it's genuine and you can continue. If it doesn't then you need to flash genuine firmware onto it, then upgrade from there if you. [Here][2] is a good tutorial on flashing the genuine firmware onto the module.

After that you can follow a tutorial [here][3] on upgrading the firmware from an older genuine firmware. You can get the latest genuine firmware from the [Manufacture's website][4].

  [1]: http://jnhuamao.cn/bluetooth40_en.zip
  [2]: https://circuitdigest.com/microcontroller-projects/how-to-flash-the-firmware-on-cloned-hm-10-ble-module-using-arduino-uno
  [3]: https://techienoise.blogspot.com/2016/02/upgrading-firmware-to-hm-10-cc2541-ble.html
  [4]: http://jnhuamao.cn/download_rom_en.asp?id=1


body:
I have a mobile app (done using MIT App Inventor) storing some values to a Firebase database. App inventor stores all the values as strings (i.e. with quotes, and strings have quotes enclosed within quotes eg. `"\"hello\""`).

I'm using [this][1] library to fetch data from Firebase to ESP8266. I'm using `String` var to store the value retrieved and then change it to a CString (trying to store it directly doesn't work) as below:

This doesn't work:

```c++
Firebase.get(firebaseData, "/SCHEDULE DETAILS/SCHEDULE1/FREQ FR");
Serial.print("node -- schedule1 /FREQ FR -- type: ");
Serial.println(firebaseData.dataType());
char * cstr1 = new char [33];
cstr1 = firebaseData.stringData();
Serial.print(" -- data: ");
Serial.println(cstr1);
```

This works:

```c++
Firebase.get(firebaseData, "/SCHEDULE DETAILS/SCHEDULE1/WEIGHT");
Serial.print("node -- schedule1/WEIGHT -- type: ");
Serial.println(firebaseData.dataType() ) ;
String dummy = firebaseData.stringData();
Serial.print(" -- data: ");
Serial.print(dummy);
char * cstr = new char [dummy.length()+1];
strcpy (cstr, dummy.c_str());
Serial.print(" -- data int type: ");
Serial.println(atoi(cstr)) ;
```

I have some more nodes to get data from and I've read that lots of `Strings` are a bad practice. While trying to find out more, I saw the source code and `stringData` function itself returns a CString:

[![enter image description here][2]][2]

I feel like I'm doing one step more than what is required! Any suggestions on how to go about this would be very useful!

**Try1** Based on the answer from @Majenko, I tried this before adding to the library:

```c++
const char* get_cstring() {
  String str = "will it work" ;
  return str.c_str();
}

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

void loop() {
  const char *new_c = get_cstring();
  int len = strlen(new_c);

  for (int i = 0; i < len; i++) {
    Serial.println(new_c[i]);
    delay(1000);
  }
  Serial.println("----------");
}
```

But how do I access the contents, because it just prints garbage values; `strlen(new_c)` gives 2 (I'm guessing that's the amount of storage needed in bytes!?)

Thanks!

  [1]: https://github.com/mobizt/Firebase-ESP8266
  [2]: https://i.stack.imgur.com/fOL8c.png

title: Reading a string from Firebase and storing it as a CString

Answers: 1

body:
In returning a `String` object the Firebase first generates that `String` object and copies the C string data into it.

If you want to get at the raw C string data you will have to look at adding a new "getter" to the library to return the pointer to that C string data:

I'd write it for you, but since you posted a screenshot of the Firebase function, and the change from that code to the new code is very minor (just change the function name and the return type), I can't copy-and-paste it. And I'm not going to peer at that little image and type it all in again.

Incidentally, internally the Firebase library actually uses `std::string`, which is a better implementation of the same thing that `String` does. `String` was created because the Arduino compiler has no STL, and hence no `std::string`. Either way they both use dynamic allocation.


body:
I have a piece of code that captures input from infrared and spits it out to the serial port.

When I use it with a simple controller that comes with a typical kit, it receives the infrared code just fine for each button I depress.

But when I try and capture information from my air conditioning remote (the one I need to clone), I receive the first hexcode and then the output gets thrown into an infinite loop with that 1 hexcode, and will not break out.

```c++
#include <IRremote.h>

const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  Serial.begin(115200);
  irrecv.enableIRIn();
  irrecv.blink13(true);
}

void loop(){
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume();
  }
}
```

What is causing the infinite loop from "some" controllers and how do I prevent it?

Update:

In changelog they say they renamed RAW_BUF to RAW_BUFFER_LENGTH. I find RAW_BUFFER_LENGTH in IRremoteInt.h and not IRremote.h

I'm not calling on IRremoteInt.h

I did try and reset the buffer from 101 to 201 in IRremoteInt.h, recompiled, uploaded, same issue.

title: Infared: some controllers send code into infinite loop

Answers: 0


body:
I am using Free RTOS on esp32 in my program.
However at some point of time when I execute xTaskCreate() it returns -1 , which error is  could_not_allocate_required_memory. In my program, each time i pring getFreeHeap() it is reduced by 2000 approximately and is never cleared or reset, when it is not sufficient or below 2000 xTaskCreate returns -1.

After reading a lot of forums I could not find a way to clear the memory to create a task, can anyone guide me achieving this ?

**code snippet**

```cpp
void createTsk(){
  SerialDebug.print("available Heap size: ");
  SerialDebug.println(ESP.getFreeHeap());

  BaseType_t xBy = xTaskCreate(taskPriorityOne, "TaskOne", 20240, NULL, 1, &thOne);
  SerialDebug.println("Return Val : ");
  SerialDebug.println(xBy);
}

void taskPriorityOne(void *paramter)
{
   SerialDebug.println("Prio 1 task Initiated");
   threadTask(priorityOneQue, "task1", thOne);
}

void threadTask(QueueHandle_t priorityQue, String taskName, TaskHandle_t th)
{
  xQueueReceive(priorityQue, &taskdataholder, portMAX_DELAY);
  ongoingProcess = taskdataholder;
  furtherExecutionHttp(taskdataholder, fnm, taskName, th);
}

void furtherExecutionHttp(DataHolder *taskdataholder, String fnm, String
taskName, TaskHandle_t th)
{
   String response = httpRequest(taskdataholder->protocol, taskdataholder-
   >host, taskdataholder->port, taskdataholder->url, taskdataholder->body,
   fnm);

  delay(10);

  free(taskdataholder);
  SerialDebug.println("Releasing memory..\n");

  vTaskDelete(th);
}
```

title: how to clear heap memory in esp32?

Answers: 2

body:
You probably don't want to "clear" the heap, assuming you mean either deallocating or zeroing all memory that you've allocated from the heap.

If you simply return all memory to the heap when you run out, your code may have pointers to that memory remaining when that memory gets allocated to another use, meaning some data will likely get over-written. Or, if you clear the heap (by zeroing it) you will be over-writing data already stored there, and possibly still be unable to allocate more memory if the allocator doesn't "know" that you meant to return it.

Instead, your code should free each memory allocation as soon as it is no longer useful, and make sure its pointer to that memory won't be used again. One way to protect re-use of dead pointers is 1) zero them when you deallocate the memory they point to; and 2) always test for a valid pointer (non-zero) before you try to use it.

body:
The heap memory in ESP32 cannot be cleared explicitly. The heap memory is used to store dynamically allocated objects, and when an object is no longer needed, it is automatically deallocated by the garbage collector.

You can free up some heap memory by deleting unused objects. In your code, you create a new object called **taskdataholder** in the **furtherExecutionHttp()** function. This object is allocated on the heap and will only be deallocated once the function returns. If you want to free up this memory, you can call the **free()** function before the function returns.


body:
I want to attach my GOOJPRT Thermal Printer (I believe model QR701, communication RS232) to my ESP32 but I cannot seem to get them working.

I tried all the Adafruit Thermal Printer library examples but get the same error each and every time:

    "Error compiling for board ESP32 Dev Module."

I guess the libraries are not meant for the ESP32.
I also tried the ["Thermal Printer Library" by Larry Bank][1] (which should be compatible with the ESP32 according to its github docs) but there I cannot figure out how to connect the wires of thermal printer to the ESP32 correctly.

Of course, I do not ask for a specific solution, I am just looking for someone to point me in the right direction!

[![enter image description here][2]][2]

[This is an image of the exact thermal printer I have][3]

*Full error message from Adafruit Thermal Printer examples:*

    C:\Users\Thomas\Documents\Arduino\libraries\SoftwareSerial-master\SoftwareSerial.cpp:41:27: fatal error: avr/interrupt.h: No such file or directory
    compilation terminated.
    Multiple libraries were found for "Adafruit_Thermal.h"
     Used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit_Thermal_Printer_Library
     Not used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit-Thermal-Printer-Library-master
    Multiple libraries were found for "SoftwareSerial.h"
     Used: C:\Users\Thomas\Documents\Arduino\libraries\SoftwareSerial-master
     Not used: C:\Users\Thomas\Documents\Arduino\libraries\EspSoftwareSerial
    exit status 1
    Error compiling for board ESP32 Dev Module

*Second error message from Adafruit Thermal Printer example after removing the manually installed SoftwareSerial.h:*

    A_printertest:21:28: fatal error: SoftwareSerial.h: No such file or directory
    Multiple libraries were found for "Adafruit_Thermal.h"
    compilation terminated.
     Used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit_Thermal_Printer_Library
     Not used: C:\Users\Thomas\Documents\Arduino\libraries\Adafruit-Thermal-Printer-Library-master
    exit status 1
    SoftwareSerial.h: No such file or directory

  [1]: https://github.com/bitbank2/Thermal_Printer
  [2]: https://i.stack.imgur.com/KGyg3.jpg
  [3]: https://i.stack.imgur.com/UBHeI.jpg

title: How to connect a thermal printer to an ESP32?

Answers: 1

body:
You need to use the <HardwareSerial. h> library. SoftwareSerial is for Arduino boards.
"Thermal Printer Library" by Larry Bank is for GOOJPRT PT-210 and uses Bluetooth. Won't work for QR-701.
Instead of using Adafruit Library, you can try with this: ThermalPrinter.

This May Help,
Peter


body:
I am using the Arduino IDE to run and monitor, with an Arduino Nano clone.
This code shows what I mean by the question:
```c++
char foo = 127;
char bar = 128;
Serial.println(String(foo, BIN));
Serial.println(String(bar, BIN));
foo = 383;
bar = 384;
Serial.println(String(foo, BIN));
Serial.println(String(bar, BIN));

```
prints
```
1111111
1111111110000000
1111111
1111111110000000
```
It still happens if I then cast the elements to `char`, but not if I cast them to `uint8_t`:
```c++
char foo = 127;
char bar = 128;
Serial.println(String((char)foo, BIN));
Serial.println(String((char)bar, BIN));
Serial.println(String((uint8_t)foo, BIN));
Serial.println(String((uint8_t)bar, BIN));
```
```
1111111
1111111110000000
1111111
10000000
```
It behaves the same if I do some arithmetic as well:
```c++
char foo = 127;
char bar = 128;
Serial.println(String(foo / 64, BIN));
Serial.println(String(bar / 64, BIN));
```
```
1
1111111111111110
```
Why is this? If I assign a number bigger than 255, but smaller than 384, it behaves like for numbers below 128, but above that, it does it again, so it's obvious that only the least significant 8 bits of the value are stored as expected, but in cases where (n mod 255) > 127 (so the 8th bit is `1`) they are retrieved from memory together with another 8 bits, which are all `1`s.

**I can live without an answer to the above issue, what I really need to have confirmed is the following:**

If I were to store and retrieve a `uint16_t` as two elements of a `char[]`, it would always be safe (and not undefined behavior) if I did it as follows, right?:
```c++
uint16_t foo = 34952;
char bar[2];
bar[0] = foo >> 8;
bar[1] = foo;
uint16_t extracted = (uint16_t((uint8_t)bar[0])) << 8 | (uint8_t)bar[1];
```

Thank you in advance for any help you can provide.

title: Why are characters with value above 127 "padded" with 1s to be 16 bits long, while ones with values 0-127 aren't?

Answers: 1

body:
On the AVR platform the `char` type happens to be signed, and it can
store numbers in the range [−128, +127]. Thus, when you write

```c++
char bar = 128;
```

You are asking to store in `bar` a number that does not fit. It then
gets reduced modulo 28 into the value that does fit, namely
−128. For the kind of manipulations you are trying to make, I would
recommend you use `uint8_t` instead of `char`.

> it would be always safe (and not undefined behavior) if I did it as
> follows

It is indeed safe, and the casts you use are needed to make it safe.


body:
I have a project having two input status

- first the input is not continuous the output buzzer relay will be on for 10 seconds and then turned off or it can be off directly by push button

- the second state if the input is continuous the output buzzer relay will be on for 10 seconds and then turned off or it can be off directly by push button

I made this code but it does not work can anyone suggest an edit without using millis() because it will crash after 49 days and without using delay function.

Note that the device will work 24 hours / 365 days.

```c++
const int input1 = 19;
const int input2 = 36;
const int relay1 = 10;
const int relay2 = 21;
const int reset = 40;
const int buzzerreset = 45;
const int buzzerrelay = 46;

int buttonState1 = 0;    //for input1
int buttonState2 = 0;    //for input2
int buttonState3 = 0;    //for pushbutton
int buttonState4 = 0;    //for buzzer reset
int b4 = 0;              //for buzzer reset

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(buzzerrelay, OUTPUT);
  pinMode(input1, INPUT);
  pinMode(input2, INPUT);
  pinMode(reset, INPUT);
  pinMode(buzzerreset, INPUT);

  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(buzzerrelay, LOW);
}

void loop() {
  buttonState1 = digitalRead(input1);
  if (buttonState1 == HIGH) {
    digitalWrite(relay1, HIGH);
    digitalWrite(buzzerrelay, HIGH);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState3 = digitalRead(reset);
  if (buttonState3 == HIGH) {
    digitalWrite(relay1, LOW);
    //digitalWrite(buzzer, LOW);
  } else {
    buttonState4 = digitalRead(buzzerreset);

    if ((buttonState4 == HIGH || buttonState1 == HIGH) && b4 == LOW) {
      digitalWrite(buzzerrelay, LOW);
    }
    // while (digitalRead(input1) == HIGH);
    // digitalWrite(buzzerrelay, LOW);

    (buttonState2 = digitalRead(input2));
    if (buttonState2 == HIGH) {
      digitalWrite(relay2, HIGH);
      digitalWrite(buzzerrelay, HIGH);
      //delay(10000);
      //digitalWrite(buzzer, LOW);
    }

    buttonState3 = digitalRead(reset);
    if (buttonState3 == HIGH) {
      digitalWrite(relay2, LOW);
      //digitalWrite(buzzer, LOW);
    } else {
      buttonState4 = digitalRead(buzzerreset);
      if (buttonState4 == HIGH) {
        digitalWrite(buzzerrelay, LOW);
      }
      //while (digitalRead(input2) == HIGH);
      //digitalWrite(buzzerrelay, LOW);
    }
  }
}
```

title: Turn on relay for amount of time by continuous input

Answers: 2

body:
Whatever the inputs do, when one of them first goes HIGH you want the buzzer to sound, stopping after 10 seconds or a button-press, whichever comes first?
Then you need something like this:

    if any input is HIGH,
       save millis();
       start the buzzer;

       if button is HIGH
          stop the buzzer;
       else if millis() - saved millis() >= 10*1000 millisec),
          stop the buzzer;
    end;

body:
I would suggest having a `buzzerPlaying` state, an `oldInput` state, and a `buzzerOffTime` (unsigned long millis when you should turn the buzzer off.

Ignore input if `buzzerPlaying == true` and just check the `buzzerOffTime`. When `buzzerOffTime` passes, turn off the buzzer, set `buzzerPlaying` to false, and start checking the input again.

If the `buzzerPlaying == false` and input is high:

   1. check `buzzerPlaying`. If it's true, do nothing.

   2. If `buzzerPlaying` is false, check `oldInput`. If `oldInput` is high, do nothing (The input has not been reset.) else set buzzerPlaying to true, set oldInput to high, turn on the buzzer, and calculate `buzzerOffTime`.

If the `buzzerPlaying == false` and input is low, set oldInput to low (Once the buzzer has stopped playing and the input has dropped low, start looking for more inputs.)


body:
I want to use a Leonardo with USB chip to emit some commands via USB port to a digital piano computer (running Windows 7) for various functions. I've gotten the Leonardo to emit page up and page down functions using a simple project I found on the web. What I need now is the following set of functions: left arrow, right arrow, F11, wake, and sleep. What I need help with is:
- where is the complete list of functions available with keyboard.press?
- are wake and sleep among those available?
- if they aren't, what header file could be modified to include them?

Thank you for any suggestions.

title: Using Leonardo as keyboard: add wake and sleep functions

Answers: 1

body:
It turns out there is a library that can be added to compile the media and system functions for USB keyboard connection into the Leonardo, as well as other Arduino modules. It is available through 'tools','library manager'; it is HID-project by NicoHood. There is an example program called "system example" at github to test it for for wake and sleep. It works perfectly.
 I expect it'll work for the other functions too.


body:
I am currently testing a small Arduino Nano project (schematic below) and have encountered issues when communicating between a HC-05 Bluetooth module and the Arduino. I am using a simple LED bulb which I am trying to turn on and off from a phone which is connected to the HC-05. The HC-05 is powered separately by some batteries instead of being powered by the Arduino itself. The Bluetooth connection is functional, and so is the actual LED functionality on the Arduino, but there seems to be a problem when I am trying to send stuff through the RX/TX connection. I previously attempted this without a voltage divider and had the same problem. Am I using the right resistors for the voltage divider or should I step them up to 1k and 2k respectively? I measured the voltage on the RX/TX and for some reason it only amounts to around 1.5V (instead of the desired 3.3V). Is there any other issue I am not seeing?

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/hhsdG.png

Edit: I also measured the voltage on the RX/TX without the voltage divider and somehow it's straight up 0. Why would that be?

title: HC-05 voltage divider

Answers: 0


body:
I have an Arduino Uno and Mega, but when I connect them to a computer with the USB they came with, there is no green light near the reset button that illuminates.

On the Uno board the pin 13 continuously flashes with red light while on the Mega board the R17 and R18 both illuminate red light but no flashing.

How do I know if the boards work or are damaged?

title: Checking if Arduino board works or is damaged

Answers: 1

body:
Did you try to connect to the computer and upload a blank sketch or a blink sketch...
If the program complies and uploads successfully it is alive.
But you will have to check IO, ADC and other features separately.


body:
I am trying to get a strain gauge working with the [HX711][1] load cell amp. I posted about this a few months ago and got told to get some high precision resistors for the wheatstone bridge. I have now obtained these (https://www.digikey.fi/product-detail/en/vishay-foil-resistors-division-of-vishay-precision-group/Y0007350R000T9L/Y0007-350-ND/2609877).

My wiring and code are as shown below. The wiring is basically a wheatstone bridge with one arm replaced by the strain gauge and each of the corners of the wheatstone bridge connected to RED, BLK, WHT and GRN on the red HX711 (BLK and GRN are the ones connected to the strain gauge arm). On the other side, VCC is to 5V on the arduino, GND to GND on the arduino, DAT to digital pin 5 and CLK to digital pin 6.

```c++
#include "HX711.h"

#define calibration_factor -550.0 //This value is obtained using the SparkFun_HX711_Calibration sketch
#define DOUT  5
#define CLK  6

HX711 scale;

void setup() {
  Serial.begin(9600);
  Serial.println("HX711 scale demo");

  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0

  Serial.println("Readings:");
}

void loop() {
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
  Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();
}
```

[![Schematic of Wiring][2]][2]

The problem is that the values are not changing when I bend the strain gauge. Only random, short spikes in values are happening and they do not seem to correspond to the strain gauge being strained or unstrained (see below). Any ideas what could be causing this?

[!["Readings" in Serial Plotter][3]][3]

Any help is greatly appreciated.

  [1]: https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf
  [2]: https://i.stack.imgur.com/V4mrB.jpg
  [3]: https://i.stack.imgur.com/56RUS.jpg

title: Strain Gauge with HX711 Load Cell Amp

Answers: 0


body:
I have the following problem: I am working with an Arduino Nano 33 IoT and a second serial interface via sercom0. The code is just taken from this tutorial:

http://www.getmicros.net/serial-communication-on-the-arduino-nano-iot.php

In loop, I just print the input from my serial connection to the standard serial connection. The input comes from a ozon sensor that sends data packages every single second.

Now when I program the arduino with my Laptop, my IDE version being 1.8.5, it works well, but when I use my PC with a newer version (IDE 1.8.13), it doesn't work any more. The code is the same, the cable and the arduino are the same, the only difference is the PC. But when I try to use an hyperterminal to print the data packages recieved from the sensor, both the Laptop and the PC receive the correct packages. Somehow, the Arduino or the difference in IDE versions causes the communication to fail....

Does anyone have experience with this error?

title: Arduino Serial Communication possible with IDE 1.8.5 but not with IDE 1.8.13

Answers: 0


body:
I am extremely new to Arduino and have searched for this on the web but have not found it.

My project has 2 files, a .ino file with the sketch and another .h file with the secrets and configuration parameters, such as reading intervals, credentials to connect to WiFi, etc.

Now I need in runtime to be able to connect to the arduino, either by serial or by any other way to be able to set these parameters.

My question is: How can I change the parameters after compiling the sketch? For example, how can I specify the credentials for the Arduino to connect to the client's WiFi, since each client has different credentials?

title: Set parameters after compilation

Answers: 2

body:
It is likely 2 features are desired for this project:

 1. A way to enter WIFI credentials after the program is running.
 2. A way to store the WIFI credentials between power cycles.

The solution for the 2nd requirement is to use [non volatile memory][1]. Both problems have been solved before for certain types of Arduinos.  [Here is a project on GitHub][2] which has solutions for boards using the [ESP8266][3] or [ESP32][4] processors.

  [1]: https://en.wikipedia.org/wiki/Non-volatile_memory
  [2]: https://github.com/tzapu/WiFiManager
  [3]: https://en.wikipedia.org/wiki/ESP8266
  [4]: https://en.wikipedia.org/wiki/ESP32

body:
You can set parameters, like SSID and password, at run time in several ways. The two most obvious are:
- a small dialog using the serial monitor or an other serial console;
- a web interface served by the Arduino that lets you enter parameters.

The idea of the latter is that, when the Arduino can't connect to an available network (because it is unknown, or because it doesn't have the right credentials stored), it sets itself up as an *access point* with a known SSID, password, and IP address.

You can then (first) connect to the Arduino's access point WiFi network, and then open a HTML page from the Arduino in a webbrowser that lets you enter your WiFi credentials for the "real" WiFi network. This is how the [WiFiManager library][1] works (for the ESP8266 and the ESP32).

Once the credentials have been entered, you can store them (permanently) in EEPROM using the [EEPROM library][2] or, if the MCU on your Arduino doesn't have EEPROM, using a library that stores in flash, like the [FlashStorage library][3] for SAMD21-based Arduinos.

The same mechanisms can be used for other parameters you may want to set at run time.

  [1]: https://github.com/tzapu/WiFiManager
  [2]: https://www.arduino.cc/en/Reference/EEPROM
  [3]: https://github.com/cmaglie/FlashStorage


body:
If I have an interrupt attached to two pins and the handler of the first is still executing when the second interrupt fires, does it:

a) queue the second interrupt,

b) ignore the second interrupt (missing it altogether), or

c) pause processing of the first interrupt to execute the second?

I am writing code that logs the exact time the interrupt occurs. Quite lightweight, but have three pins and am logging the rise and fall of each, so there is the potential for collisions. If a) then the second interrupt timestamp will be late, b) there is no timestamp for the later interrupt or c) the timing of the first and second interrupts will be ambiguous.

b) is the worst case, the other two are manageable.

title: Do interrupts block other interrupts?

Answers: 2

body:
It depends on the architecture.

Assuming AVR (8-bit Arduino) then it will queue the second interrupt until the first is finished.

It works by setting a flag in a register at the moment the interrupt occurs. Then between instructions it checks that flag and executes the associated interrupt routine. If an interrupt is in progress at the time the flag still gets set, but it is unable to check the state of that flag until after the current interrupt is over and normal execution occurs, at which point after the next instruction is completed it checks the interrupt flag statuses and runs the second interrupt routine.

body:
It depends on the specific MCU, not all are exactly the same.

Some have interrupt priority circuitry that you can use.  But in general, an ISR can be interrupted by another incoming IRQ, etc.  What you often do in an ISR is mask IRQ, handle the IRQ, and then unmask to let any pending IRQs be handled.

This is one reason why long-running ISRs should be avoided!


body:
I want to create a sketch that counts the days from the moment the "project" start and send and osc message every two days (or more) for 3 weeks. So:

day zero : osc message -> 0
day two. : osc message -> 1
day four : osc message -> 2

etc.

I'm trying to create a state machine to send the messages when the millis reaches a certain time it should print message and so on for the other times.
I'm giving a small example:

I went with @jsotola's suggestion and tried out the BlinkWithoutDelay approach. It seemingly works because I get serial prints around the correct millis() they are printed in 4fold or 3fold the messages.

EDITED CODE:
```c++
int daytwo = 25920; // for testing purposes other numbers then the actual millis()
int dayfour = 44400;

void loop() {
  unsigned long currentMillis = millis();   // store current time

  if (currentMillis == daytwo) {
    Serial.println("daytwo");
  }

  if (currentMillis == dayfour) {
    Serial.println("dayfour");
  }
}
```

Serial output:

    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.926 -> daytwo
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour

title: Switch case (millis()) UPDATED

Answers: 2

body:
The following code is not very "clean" but easy to understand. Use a variable to hold the day, you have already printed and check in which interval you are. If you change the 2 day interval print a message and set the actDay variable to the number of the day you have already printed; to avoid repprinting it again.

    int daytwo = 25920;
    int dayfour = 44400;

    int actDay = -1;

    void loop()
    {
      unsigned long currentMillis = millis();
      if (currentMillis < daytwo)
      {
        if ( actDay != 0 )
        {
          actDay = 0;
          Serial.println("dayzero");
        }
      }
      else if (currentMillis < dayfour )
      {
        if ( actDay != 2 )
        {
          actDay = 2;
          Serial.println("daytwo");
        }
      }
      else
      {
        if ( actDay != 4 )
        {
          actDay = 4;
          Serial.println("dayfour");
        }
      }
    }

body:
```lang-cpp
int day = 0;
unsigned long prevMillis = 0;
const unsigned long MILLIS_PER_DAY = 86400000UL;

void setup()
{
  prevMillis = millis();
}

void loop() {
  if( millis() - prevMillis > MILLIS_PER_DAY )
  {
    // one whole day has passed
    day++;
    prevMillis += MILLIS_PER_DAY;

    // do the things you want to do at the beginning of a new day
    if( day==2 ) {
      Serial.println("daytwo");
    }
    else if (day == 4) {
      Serial.println("dayfour");
    }
  }
}
```

This is a more generic version. It checks if `24*60*60*1000` milliseconds have past since the last time the day rolled over. When this occurs, it will increment the current day and update `prevMillis` to have the value of millis() when the day started.

This also has the advantage that is will only run your "daily code" once.

And will also run, when some other task takes a long time. I your old code, you might miss the exact moment millis() is the value you are looking for, if some other code takes more than 1 ms.


body: I'm trying to make a RC car (with a surveillance camera if possible, using the web-cam code that comes with the ESP library) using a ESP-32 CAM as a wifi module to control the car using my computer. Problem is that I keep getting the "invalid head of packet" error whenever I try uploading anything. I've tried holding the boot button as I upload and I cannot use the capacitor simply because I don't have it and don't want to buy it and spend time getting it. I also have the GPIO0 pin connected to GND during the uploading process. Any other ways to get it working? My car consists of 2 DC motors powering only the back two wheels and a servo that steers the front wheels, and I want to use the ESP32-CAM to connect to wifi to connect to a webserver from my pc to control the car.

title: Help with ESP32-CAM "AI THINKER" module

Answers: 0


body:
I am using an ESP32 (https://heltec.org/project/wifi-kit-32/) with a AM2302 DHT22 and an LDR, talking to mosquitto on a Linux box.  Publishing data is working fine, other than the "exceeded timeout, disconnecting" lots of people seem to be having.  However, when a message is sent from another client to a topic I am subscribed to, my callback is never called, so I can't consume it.

In my reconnect function, I have
```
    boolean success = mqttClient.subscribe("sensors/basement/led");
    Serial.print("Subscribe returned ");
    Serial.println(success);
```
and it does return 1 which I believe is success (usually success is zero but I don't think that's the case here).  I also see the subscription in my mosquitto logs, which are currently cranked up to debug.
```
1610417274: New client connected from XXX.XXX.XXX.XXX as Basement1 (c1, k15, u'XXXXXXXXX').
1610417274: Sending CONNACK to Basement1 (0, 0)
1610417275: Received SUBSCRIBE from Basement1
1610417275:     sensors/basement/led (QoS 0)
1610417275: Basement1 0 sensors/basement/led
1610417275: Sending SUBACK to Basement1
```
When I send data to sensors/basement/led from the other client (mqttdash), the server receives it, and sends it to mqttdash, as well as Basement1, which is my ESP32:
```
It's definitely sending the message to the ESP32:
1610417546: mqttdash-3785c5ce 0 sensors/basement/led
1610417546: Sending SUBACK to mqttdash-3785c5ce
1610417578: Received PUBLISH from mqttdash-3785c5ce (d0, q0, r0, m0, 'sensors/basement/led', ... (1 bytes))
1610417578: Sending PUBLISH to Basement1 (d0, q0, r0, m0, 'sensors/basement/led', ... (1 bytes))
1610417578: Sending PUBLISH to mqttdash-3785c5ce (d0, q0, r0, m0, 'sensors/basement/led', ... (1 bytes))
```
However, my callback is never called.  Here is the setup of the callback:
```
WiFiClient espClient;
PubSubClient mqttClient(espClient);
...
void setupMQTT()
{
    mqttClient.setServer(MQTT_HOST, MQTT_PORT);
    mqttClient.setCallback(mqttSubHandler);
    mqttConnect();
}
...
void mqttSubHandler(char *topic, byte *message, unsigned int length)
{
    Serial.print("Message arrived on topic: '");
    Serial.print(topic);
    Serial.print("'. Message: ");
    String messageTemp;

    for (int i = 0; i < length; i++)
    {
        Serial.print((char)message[i]);
        messageTemp += (char)message[i];
    }
    Serial.println();
...
```

Full code at https://github.com/djsegfault/arduino/blob/master/basement_monitor/basement_monitor.ino

Does anyone know why the callback is not being called?  Thanks in advance.

title: PubSubClient: Subscription working, but callback never called

Answers: 1

body:
nknolleary, the owner of the library, correctly identified the problem:
You need to call mqttClient.loop() in you main loop. Without that, you are never giving the client a chance to check for any incoming messages.


body:
I have an Arduino Mega 2560 and I want to control four 23-frame steppers same speed/direction for a conveyor application. I want these to be synchronized exactly as possible for smooth operation.

- Can four TB6600 drivers be daisy chained to the same Arduino GPIO pins?

- Is there a limit to how many number of drivers I can daisy chain?

- I'm wondering about current draw from the 5 volt Arduino GPIO, spread out over many drivers.

Thanks for your help!
Bob

title: Using same GPIO pins to control multiple stepper drives

Answers: 1

body:
Those devices use opto-isolated inputs. To all intents and purposes they look just like an LED with a resistor in series.

The built-in resistor looks like it sets the current to "between 8mA and 15mA" and typically 10mA, though it's impossible to say what it *actually* is.  So we'll take the worst-case scenario of 15mA.

The Arduino has an absolute maximum of 40mA, and a recommended maximum of 25mA from each IO pin, with a maximum of 200mA in total through all pins.

That means you ideally can't really have more than one TB6600 per IO pin, but you could get away with 2 per pin, certainly no more.

To run lots in parallel you would need a separate set of drivers that can "fan out" the low-current signal to either a single high current signal or a parallel set of low-current signals.

It looks like you provide 5V to one pin of each input (the anode of the opto-isolator) and sink the current through the other pin (the cathode of the opto-isolator) to ground through your IO pins. That means you could use a single large N-channel MOSFET to sink all of the cathodes in parallel and invert your IO logic in software.


body:
I am trying to read data from a Blynk widget via ESP8266 and Arduino UNO and trying to send it to another slave Arduino UNO.  But, the problem is the data is taking some time to reach to the slave Arduino for further processing and I need it to be fast as it is needed for controlling a drone.

If any one can help, please help. I am a tenth grader and a newbie. So, I don't have a lot of experience.

Here is the code for the master Arduino:

```c++
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <SoftwareSerial.h>   //We are using software serial so as not to conflict with serial download and monitor

SoftwareSerial mySerial(5,6); // RX, TX

int of=0;
int throttle=0;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "auth";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "wifi_name";
char pass[] = "wifi_pass";

// Hardware Serial on Mega, Leonardo, Micro...
//#define EspSerial Serial1
// or Software Serial on Uno, Nano...
//#include <SoftwareSerial.h>
//SoftwareSerial EspSerial(2, 3); // RX, TX

// Your ESP8266 baud rate:
#define ESP8266_BAUD 115200

ESP8266 wifi(&Serial);
WidgetLED l(V3);

void setup()
{
 // Debug console
 Serial.begin(9600);
 delay(10);
 // Set ESP8266 baud rate
 Serial.begin(ESP8266_BAUD);
 delay(10);
 Blynk.begin(auth, wifi, ssid, pass);
 mySerial.begin(9600);
}

void loop()
{
 Blynk.run();
 l.on();
 mySerial.write(of);
 mySerial.write(throttle);
}

BLYNK_WRITE(V1)
{
  of = 100+param.asInt();
}

BLYNK_WRITE(V2)
{
  throttle = param.asInt();
}
```

title: Maximum baud rate for sending a byte of data via SoftwareSerial from master Arduino UNO to slave Arduino UNO

Answers: 0


body:
How do I get this [example][1] to run on using an Arduino Uno. I've updated `RFM95_RST`, `RFM95_CS` & `RFM95_INT` to the relevant pins (2,4 & 3 respectively).

This is the output on the Serial Monitor when the sketch is loaded:

    Feather LoRa RX Test!
    ERROR: Failed to put device in LoRa mode.
    RH_RF95_REG_01_OP_MODE: 0
    LoRa radio init failed

I've followed [this][2] wiring set up:
[![enter image description here][3]][3]

[![enter image description here][4]][4]

    #include <SPI.h>
    #include <RH_RF95.h>

    #define RFM95_RST     2
    #define RFM95_CS      4
    #define RFM95_INT     3

    // Change to 434.0 or other frequency, must match RX's freq!
    #define RF95_FREQ 915.0

    // Singleton instance of the radio driver
    RH_RF95 rf95(RFM95_CS, RFM95_INT);

    // Blinky on receipt
    #define LED 13

    void setup()
    {
      pinMode(LED, OUTPUT);
      pinMode(RFM95_RST, OUTPUT);
      digitalWrite(RFM95_RST, HIGH);

      Serial.begin(115200);
      while (!Serial) {
        delay(1);
      }
      delay(100);

      Serial.println("Feather LoRa RX Test!");

      // manual reset
      digitalWrite(RFM95_RST, LOW);
      delay(10);
      digitalWrite(RFM95_RST, HIGH);
      delay(10);

      while (!rf95.init()) {
        Serial.println("LoRa radio init failed");
        Serial.println("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info");
        while (1);
      }
      Serial.println("LoRa radio init OK!");

      // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
      if (!rf95.setFrequency(RF95_FREQ)) {
        Serial.println("setFrequency failed");
        while (1);
      }
      Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);

      // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

      // The default transmitter power is 13dBm, using PA_BOOST.
      // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
      // you can set transmitter powers from 5 to 23 dBm:
      rf95.setTxPower(23, false);
    }

    void loop()
    {
      if (rf95.available())
      {
        // Should be a message for us now
        uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
        uint8_t len = sizeof(buf);

        if (rf95.recv(buf, &len))
        {
          digitalWrite(LED, HIGH);
          RH_RF95::printBuffer("Received: ", buf, len);
          Serial.print("Got: ");
          Serial.println((char*)buf);
           Serial.print("RSSI: ");
          Serial.println(rf95.lastRssi(), DEC);

          // Send a reply
          uint8_t data[] = "And hello back to you";
          rf95.send(data, sizeof(data));
          rf95.waitPacketSent();
          Serial.println("Sent a reply");
          digitalWrite(LED, LOW);
        }
        else
        {
          Serial.println("Receive failed");
        }
      }
    }

  [1]:https://github.com/adafruit/RadioHead/blob/master/examples/feather/Feather9x_RX/Feather9x_RX.ino
  [2]: https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts/arduino-wiring
  [3]: https://i.stack.imgur.com/ZSkUb.png
  [4]: https://i.stack.imgur.com/52l35.jpg

title: How can I get an Arduino Uno run the Feather9x_RX example?

Answers: 0


body:
I've scored a couple Nanos with FT232RL chips but can't see them on my brand new M1 mini. Can someone point me at how to determine whether v11.1 supports this USB chip?

It appears that the device is being instantiated but the Arduino IDE gets no response to the Get Board Info.
```
FT232R USB UART:

  Product ID: 0x6001
  Vendor ID: 0x0403  (Future Technology Devices International Limited)
  Version: 6.00
  Serial Number: AR0JT9YB
  Speed: Up to 12 Mb/s
  Manufacturer: FTDI
  Location ID: 0x02214000 / 20
  Current Available (mA): 500
  Current Required (mA): 90
  Extra Operating Current (mA): 0
```
Executing the ioreg mentioned by @st2000 gives;
```
+-o Root  <class IORegistryEntry, id 0x100000100, retain 31>
  +-o AppleT8103USBXHCI@00000000  <class AppleT8103USBXHCI, id 0x100000291, registered, matched, active, busy 0 (1676 ms), retain 328>
  | +-o Extreme SSD@00200000  <class IOUSBHostDevice, id 0x10000081d, registered, matched, active, busy 0 (219 ms), retain 132>
  +-o AppleT8103USBXHCI@01000000  <class AppleT8103USBXHCI, id 0x100000295, registered, matched, active, busy 0 (4 ms), retain 39>
  +-o AppleT8103USBXHCIFL1100@02000000  <class AppleT8103USBXHCIFL1100, id 0x1000006eb, registered, matched, active, busy 0 (1220 ms), retain 494>
    +-o Keyboard Hub@02100000  <class IOUSBHostDevice, id 0x10000071c, registered, matched, active, busy 0 (164 ms), retain 30>
    | +-o Apple Keyboard@02120000  <class IOUSBHostDevice, id 0x100000805, registered, matched, active, busy 0 (162 ms), retain 32>
    +-o 4-Port USB 2.0 Hub@02200000  <class IOUSBHostDevice, id 0x100000730, registered, matched, active, busy 0 (826 ms), retain 46>
    | +-o 4-Port USB 2.0 Hub@02230000  <class IOUSBHostDevice, id 0x100000785, registered, matched, active, busy 0 (11 ms), retain 42>
    | +-o 4-Port USB 2.0 Hub@02220000  <class IOUSBHostDevice, id 0x100000791, registered, matched, active, busy 0 (16 ms), retain 43>
    | | +-o Backup+ Hub@02223000  <class IOUSBHostDevice, id 0x1000007dc, registered, matched, active, busy 0 (6 ms), retain 41>
    | +-o 4-Port USB 2.0 Hub@02210000  <class IOUSBHostDevice, id 0x10000079d, registered, matched, active, busy 0 (776 ms), retain 43>
    | | +-o FT232R USB UART@02214000  <class IOUSBHostDevice, id 0x100007622, registered, matched, active, busy 0 (75 ms), retain 23>
    | +-o 4-Port USB 2.0 Hub@02240000  <class IOUSBHostDevice, id 0x1000007b6, registered, matched, active, busy 0 (12 ms), retain 42>
    +-o 4-Port USB 3.0 Hub@02600000  <class IOUSBHostDevice, id 0x100000749, registered, matched, active, busy 0 (231 ms), retain 46>
      +-o 4-Port USB 3.0 Hub@02620000  <class IOUSBHostDevice, id 0x10000075e, registered, matched, active, busy 0 (170 ms), retain 43>
      | +-o Backup+ Hub@02623000  <class IOUSBHostDevice, id 0x1000007c3, registered, matched, active, busy 0 (155 ms), retain 41>
      |   +-o Backup+ Hub BK@02623100  <class IOUSBHostDevice, id 0x1000007ee, registered, matched, active, busy 0 (147 ms), retain 131>
      +-o 4-Port USB 3.0 Hub@02640000  <class IOUSBHostDevice, id 0x100000763, registered, matched, active, busy 0 (15 ms), retain 42>
      +-o 4-Port USB 3.0 Hub@02630000  <class IOUSBHostDevice, id 0x100000775, registered, matched, active, busy 0 (15 ms), retain 42>
      +-o 4-Port USB 3.0 Hub@02610000  <class IOUSBHostDevice, id 0x1000007a9, registered, matched, active, busy 0 (16 ms), retain 42>
```
Which does not appear to contain the device afai can see. Any know if this means a new device for Big Sur is indicated as per Majenko♦ ?

title: USB FT232 driver on M1 mini

Answers: 3

body:
A MAC is usually (unless it is really old) running a derivative of Unix. I would open a console install and use "lsusb" to list out all the USB connected devices.

A (Linux) example of lsusb:

    $ lsusb
    Bus 001 Device 004: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

I would do this with and with out the Arduino FTDI chip connected and look for the difference. [This stackexchange question/answer][1] contains how to do this on a MAC or use other MAC commands to do the same.  As pointed out in the comments the more native MAC command is:

    ioreg -p IOUSB

Note, if you have fake FTDI chips there was a time when the [FTDI driver that Windows ran would brick the fake FTDI chip][2]. I think it would assign the vendor and device IDs both to zero. You should be able to see this with the "lsusb" command.

  [1]: https://stackoverflow.com/questions/17058134/is-there-an-equivalent-of-lsusb-for-os-x
  [2]: https://hackaday.com/2016/02/01/ftdi-drivers-break-fake-chips-again/

body:
As an addendum to @st2000's answer, it's worth noting that OS X comes with a basic driver for FTDI built in. However if your device uses a non-standard VID or PID it will not work.  At the time of writing this, [according to this forum thread](https://www.ftdicommunity.com/index.php?topic=547.30
), FTDI have not yet written an updated driver for Big Sur, and seem to be struggling to do so (they have been writing one for the past year and still haven't managed it).

This should not apply to an Arduino that uses an FTDI with default settings, but worth noting for some custom devices.

body:
I run macOS Big Sur on M1 silicon (a new machine installed in the last month) and also  FT232RL interfaces (e.g., cheap HW-417-V1.2 unit). I just went back through my downloads used in setting up the machine, as far as I can recall I did *not* have to download the [FTDI driver][1] which I used to on the previous older machine. This supports @Majenko's answer regarding a built in driver. I read a little more about this [here][2]. If anyone can point to more information about the built in driver that would be awesome.

I use `ls /dev/cu.*` in a terminal window to check which USB devices are plugged in. Mine shows up as `/dev/cu.usbserial-A5XK3RJT`

On the macOS desktop, the *[Apple Icon]\About this Mac\System Report\USB* information (which I think is a GUI representation of the ioreg mentioned above?) shows the device as:

    FT232R USB UART:

      Product ID: 0x6001
      Vendor ID: 0x0403  (Future Technology Devices International Limited)
      Version: 6.00
      Serial Number: A5XK3RJT
      Speed: Up to 12 Mb/s
      Manufacturer: FTDI
      Location ID: 0x02240000 / 17
      Current Available (mA): 500
      Current Required (mA): 90
      Extra Operating Current (mA): 0

If non-standard PIDs or VIDs are causing devices to be blocked, then a possibility (which I have not tested) might be just to reflash the config on the FTDI device see: [dangerousprototypes - how to get a nicely named serial device][3].

Use `ls /dev/cu.*` in a terminal window to see if the device is showing as a call-up USB device. Then in Arduino IDE rather than using "Get Board Info", just set Tools/Port to that USB port and try to upload a sketch. The port should show up as `/dev/cu.usbserial-AR0JT9YB` or similar.

The FTDR device is in the `ioreg` output you posted, I believe it's hiding there as:

```
FT232R USB UART@02214000 <class IOUSBHostDevice, id 0x100007622, registered, matched, active, busy 0 (75 ms), retain 23>
```

  [1]: https://www.ftdichip.com/Drivers/VCP.htm
  [2]: https://tips.graphica.com.au/macos-big-sur-rs232/
  [3]: http://dangerousprototypes.com/blog/2010/01/27/pirate-rename-get-a-nicely-named-serial-device/


body:
I bought one of theses cheaps & generic Wemos D1 MINI PRO with ESP-8266 to make a system to connect my lamp with google home etc.
But the problem is to upload the code into wemos. The Arduino IDE do not recognize the USB port that is connected.
[![enter image description here][1]][1]

When I connect to my Mac the board flashes the blue LED, so I suppose that it's not dead or something.
I've tried 5 different cables e nothing. I've read some articles about drivers to install but is only for [Sierra or High Sierra][2].
Also, uninstalled and installed the arduino IDE.
I installed the ESP8266 Boards in the Boards Manager.
I tested it out with an Arduino UNO board and it recognized normally.

I have no idea what to do. I don't have a windows PC in my house to test it out, as well.

Here the pics of the board:

[![enter image description here][3]][3]

[![enter image description here][4]][4]

  [1]: https://i.stack.imgur.com/IGQS8.png
  [2]: https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver
  [3]: https://i.stack.imgur.com/5sfDu.jpg
  [4]: https://i.stack.imgur.com/bXAt5.jpg

title: Mac Big Sur don't recognize generic Wemos D1 MINI PRO based ESP-8266EX

Answers: 1

body: You need the CP210x drivers from [here](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers).


body:
I found this [code sample][1] from the FSBrowser (Flash File System) example in the [ESP8266WebServer][2] library:
```lang-c
replyServerError(FPSTR(FS_INIT_ERROR));
replyBadRequest(F("DIR ARG MISSING"));
```

I was a bit confused at what `F()` and `FPSTR()` do, so I looked up the source (`WString.h`) and found this:
```lang-c
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F(string_literal) (FPSTR(PSTR(string_literal)))
```
Which raised more questions. How does this code work and what does this added complexity gain over just using `char*` or `String` as is?

### EDIT: Added Metrics

Here's the memory usage before and after I removed all 25 instances of F() from a file system class, measured by PlatformIO Project Inspector:

||With F()|Without F()|Difference|
|-|-|-|-|
|RAM Used|29,488 bytes (36.0%)|29,792 bytes (36.4%)|+304 bytes|
|Flash Used|355,312 bytes (34%)|355,188 bytes (34.0%)|-124 bytes|
|Total (uncompressed)|359,472 bytes|359,344 bytes|-128 bytes|

Adding F() decreases RAM usage by 1% and increases Flash by around half that. That's for a single class with 25 instances of F(). For a program containing 20x this code, the difference can be significant. However, you'll run out of RAM before you get there. The space savings will be limited to around 5-8%. Still not nothing.

  [1]: https://github.com/esp8266/Arduino/blob/a4b6003c2e5f27fcce42124f2ffef824fb90339d/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino#L177-L183
  [2]: https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer

title: What is the purpose of F() and FPSTR() in ESP8266WebServer -> FSBrowser?

Answers: 1

body:
The purpose of the `PSTR()` macro is to configure the string to be used directly from flash memory. The string is then not loaded to dynamic memory at runtime as it would be without [PROGMEM][1] specifier set by the macro.

The purpose of the `FPSTR()` macro is to cast a string to 'dummy' FlashStringHelper type to help compiler choose the right overloaded function if dynamic memory and flash memory version of a function is available. An example would be the `print` function.

The `F()` macro combines this two macros. It makes the string a PROGMEM string and casts it to FlashStringHelper.

  [1]: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/


body:
I am new to Arduino and wondering if anyone can help me get it programmed correctly. I am using two buttons to control a linear actuator to open and close a barn door. I want it to go a certain speed for a specified period of time... like 3 seconds. Then I want it to slow down and go another 2 seconds. The linear actuator does not have feedback which is fine for the application because it does not have to be precise. Below is the code I copied from the manufacturers website - it works well, but I can’t figure out how to make it go for specified periods of time. Please remember I’ve never used an Arduino before and this is literally a foreign language to me. I’m just hoping someone can tell me what to do. It’s for my house, not for a school project.

*** ADDENDUM - Thanks for the help. Wish I could post a video... Here is the final code:

    /* Firgelli Automations
     * Limited or no support: we do not have the resources for Arduino code support
     *
     * Program enables momentary direction control of actuator using push button
     */

    int RPWM = 10; //connect Arduino pin 10 to IBT-2 pin RPWM
    int LPWM = 11; //connect Arduino pin 11 to IBT-2 pin LPWM
    int RPWM2 = 5; //connect Arduino pin 5 to IBT-2 pin RPWM
    int LPWM2 = 6; //connect Arduino pin 6 to IBT-2 pin LPWM
    int downPin = 12;
    int upPin = 13;
    int speed1 = 0; // Top speed you can change it between [0-255]
    int speed2 = 0; // Low speed you can change it between [0-255]
    int speed3 = 0; // Low speed you can change it between [0-255]

    void setup() {
      pinMode(RPWM, OUTPUT);
      pinMode(LPWM, OUTPUT);
      pinMode(RPWM2, OUTPUT);
      pinMode(LPWM2, OUTPUT);
      pinMode(downPin, INPUT_PULLUP);
      pinMode(upPin, INPUT_PULLUP);
    }

    void loop() {
      if(digitalRead(upPin)==LOW){ //check if extension button is pressed
        analogWrite(RPWM, 0);
        analogWrite(RPWM2, 0);
        analogWrite(LPWM, 255); // rotate motor with top speed (with PWM set to 255)
        analogWrite(LPWM2, 236); // rotate motor with top speed (with PWM set to 255)
        delay(3000);               // wait for x sec
        analogWrite(LPWM, 185); // rotate motor with low speed (with PWM set to 150)
        analogWrite(LPWM2, 181); // rotate motor with low speed (with PWM set to 150)
        delay(1600);               // wait for x sec
        analogWrite(LPWM, 80); // rotate motor with low speed (with PWM set to 150)
        analogWrite(LPWM2, 80); // rotate motor with low speed (with PWM set to 150)
        delay(1400);               // wait for x sec
        analogWrite(LPWM, 0);     // uncomment if you want to stop motor now
        analogWrite(LPWM2, 0);     // uncomment if you want to stop motor now
      }

      else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
        analogWrite(LPWM, 0);
        analogWrite(LPWM2, 0);
        analogWrite(RPWM, 254); // rotate motor with top speed (with PWM set to 255)
        analogWrite(RPWM2, 255); // rotate motor with top speed (with PWM set to 255)
        delay(3000);               // wait for x sec
        analogWrite(RPWM, 170); // rotate motor with low speed (with PWM set to 150)
        analogWrite(RPWM2, 170); // rotate motor with low speed (with PWM set to 150)
        delay(1500);               // wait for x sec
        analogWrite(RPWM, 80); // rotate motor with low speed (with PWM set to 150)
        analogWrite(RPWM2, 80); // rotate motor with low speed (with PWM set to 150)
        delay(1500);               // wait for x sec
        analogWrite(RPWM, 0);     // uncomment if you want to stop motor now
        analogWrite(RPWM2, 0);     // uncomment if you want to stop motor now
      }

      else{ //if no button is pushed, remain stationary
        analogWrite(RPWM, 0);
        analogWrite(LPWM, 0);
        analogWrite(RPWM2, 0);
        analogWrite(LPWM2, 0);
      }
    }

title: How do I power a linear actuator at different speeds for specified periods of time

Answers: 1

body:
You can do this easily by using Arduino built-in PWM function and using delay function. But remember that using delay in your code will block your code so if your program just want to sit and wait for 3 seconds at some speed then delay is ok for you else you need to implement Millis function.

first you need to define different speeds as per your requirement remember PWM function has value from 0-255 where 0 in min speed and 255 is top speed.
So here I will define speed1 for top speed and speed2 for low speed
So now your program will look like this

```
int RPWM = 10; //connect Arduino pin 10 to IBT-2 pin RPWM
int LPWM = 11; //connect Arduino pin 11 to IBT-2 pin LPWM
int downPin = 12;
int upPin = 13;
int speed1 = 255; // Top speed you can change it between [0-255]
int speed2 = 150; // Low speed you can change it between [0-255]

void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
}

void loop() {
  if(digitalRead(upPin)==LOW){ //check if extension button is pressed
    analogWrite(RPWM, 0);
    analogWrite(LPWM, speed1); // rotate motor with top speed (with PWM set to 255)
    delay(3000);               // wait for 3 sec
    analogWrite(LPWM, speed2); // rotate motor with low speed (with PWM set to 150)
    delay(2000);               // wait for 2 sec
   // analogWrite(LPWM,0);     // uncomment if you want to stop motor now
  }

  else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
    analogWrite(LPWM, 0);
    analogWrite(RPWM, speed1); // rotate motor with top speed (with PWM set to 255)
    delay(3000);               // wait for 3 sec
    analogWrite(RPWM, speed2); // rotate motor with low speed (with PWM set to 150)
    delay(2000);               // wait for 2 sec
    // analogWrite(RPWM,0);     // uncomment if you want to stop motor now
  }

  else{ //if no button is pushed, remain stationary
    analogWrite(RPWM, 0);
    analogWrite(LPWM, 0);
  }
}
```


body:
I am using this digital potentiometer <http://www.farnell.com/datasheets/31917.pdf> to control a BLDC motor with Arduino Mega. When I am running the below code, the motor runs at the lowest speed when I am setting **i = 0** in **forward()** function.
```
const int CS = 10;
const int INC = 9;
const int UD = 8;

void setup() {
  pinMode(CS, OUTPUT);
  pinMode(INC, OUTPUT);
  pinMode(UD, OUTPUT);
  digitalWrite(CS, HIGH);
  digitalWrite(INC, HIGH);
  digitalWrite(UD, HIGH);
}

void forward() {
  for (int i = 0; i <= 100; i += 10) {
    setResistance(i);
    delay(10);
  }
}

void loop() {
  forward();
}

void setResistance(int percent) {
  digitalWrite(UD, LOW);
  digitalWrite(CS, LOW);
  for (int i = 0; i < 100; i++) {

    digitalWrite(INC, LOW);
    delayMicroseconds(1);
    digitalWrite(INC, HIGH);
    delayMicroseconds(1);
  }

  digitalWrite(UD, HIGH);
  for (int i = 0; i < percent; i++) {
    digitalWrite(INC, LOW);
    delayMicroseconds(1);
    digitalWrite(INC, HIGH);
    delayMicroseconds(1);
  }

  digitalWrite(CS, HIGH);
}
```

The problem is when I set the value of **i in the forward() function** to 70 or 80 the motor runs sometimes at a much faster speed but other times when I upload the code with the 70/80/any value other than 0, the motor doesn't move at all. When **i** is set to 0, the motor runs every time at a super slow speed but for other values it sometimes moves at a faster speed, other times it doesn't move at all.

I am not sure what is causing this issue. Please help.

title: BLDC motor erroneous running with digital potentiometer

Answers: 0


body:
I'm setting up PIR and esp8266 with arduino UNO.
First my esp8266 doesn't work after alot of research my esp8266 start working when I put arduino UNO reset pin to ground.
But now my arduino UNO does not run any program and I'm not able to use PIR with this wifi module.
Any help will be appreciated
[![enter image description here][1]][1]

Only one extra thing is that reset pin is set to GND pin.

  [1]: https://i.stack.imgur.com/qG0xM.png

title: Resolved: ESP8266 works when arduino UNO reset pin is grounded

Answers: 2

body:
The RESET of the UNO puts the ATMega328P (the MCU of the UNO) into an electrically inert state when it is connected to GND.  It is not *supposed* to be running your sketch when it is being held in reset.  It is, roughly speaking, electrically disconnected from everything else on the board.  This allows you to use the UNO as though it were a USB to TTL serial cable.

If you want to be able to run a sketch on the UNO while it uses the ESP8266, you'll need to **not** hold reset to GND and you'll also, practically speaking, need to choose a different set of pins for communicating with it, as D0 and D1 on the UNO are the same signals used to for the ATMega328P to talk to the host and used for programming the UNO via its bootloader.  On the UNO, you'd instead need to use SoftwareSerial (or something similar) and pins other than D0 and D1.  **[Update: see the [original poster's own answer][1] containing the guide they ultimately used, making use of SoftwareSerial on pins 10 and 11]**

The ESP-01 can run Arduino sketches using the [ESP8266 Arduino][2] core and it may make a great deal more sense to not involve the UNO at all, and instead connect the distance sensor more or less directly to the ESP8266.

  [1]: https://arduino.stackexchange.com/a/80883/70020
  [2]: https://github.com/esp8266/Arduino

body:
So, I got it working with this information on this blog
Few things, my serial.begin(115200) where as in blog its 9600
Thanks @timemage for moving me in right direction
  [1]: https://medium.com/@cgrant/using-the-esp8266-wifi-module-with-arduino-uno-publishing-to-thingspeak-99fc77122e82


body:
I purchased a DigiSpark attiny85 off of ebay. Over the weekend I tried to get my computer to recognize the DigisSpark, but it won't recongnize it. When I plug the device in, the 'Device Connection' Sound alerts me and then a second or two the 'Device Disconnection' Sound alerts, then 'Device Connection' Sound, then the 'Device Disconnection' sound. This happens until I unplug the device. The light does turn on, but Windows (10) doesn't recognize the device, it just loops the sounds.

I am trying on a Windows 10 machine.
I installed the drivers from the DigiStump Github: https://github.com/digistump/DigistumpArduino/releases/download/1.6.7/Digistump.Drivers.zip

I do see 'Digispark Bootloader' in my device manager for a couple of seconds in my device manager.

I tried different cables. I tried to install the drivers on another computer and the same thing happens.

What should I try next? Am I missing other drivers?

title: DigiSpark attiny85 computer not detecting

Answers: 1

body:
Unless, during the short time it shows in device manager, you see that it is missing a driver, it would seem you don't need to do anything further with drivers.  You didn't mention it saying it was missing a driver or as an "unrecognized" device, so I'm guessing you mean it doesn't *stay* recognised or that it isn't recognized as a *serial* device.  If I'm incorrect in that, do say. The fact that it is showing in device manager for any length of time suggests that your cables are fine.

I'm not a Digispark user, but as far I can understand what you're saying, the connecting and disconnecting (once at least) is [expected behaviour][1]:

> In addition remember the Digispark only shows up as a programmable
> device for **5 seconds**, after that it will start running its code (when
> it is new and un-programmed this means it will blink) and disappear or
> act like the USB device you programmed it to act like.

If anything in the sketch (or lack thereof) causes the board to reset or jump to the bootloader, it *would* continually reconnect for 5 second intervals.  They documentation suggests should blink, as in run a blink sketch that was put on the board before you received it.  But then you got this from ebay, so who knows what they did or did not put on it.  I haven't studied the [micronucleous bootloader][2] enough to know, but it wouldn't surprise me if it jumps to the sketch area irrespective of whether or not it's unprogrammed.  If it *is* unprogrammed then it is probably [nop-sliding][3], for lack of a more appropriate term, right back into the bootloader.

You're not going to see it recognized as a serial port device like a typical Arduino.  The bootloader uses a vendor specific protocol that will not list as a COM# (or /dev/ttyXYZ#) device.

Indications are that if you compile the blink sketch and "upload", the IDE will run the micronucleus programming tool which gives you a 60 second window for you to plug the board in, at which point it will load the board with the blink sketch.  After which it should blink the LED.  If unplugged and replugged, you can expect it to show up for 5 seconds on USB and if left alone should disconnect (electrically) from USB and begin blinking.

  [1]: http://digistump.com/wiki/digispark/tutorials/connecting
  [2]: https://github.com/micronucleus/micronucleus/tree/master/firmware
  [3]: https://en.wikipedia.org/wiki/NOP_slide


body:
I am using the Preferences.h library in my Arduino code. I initialize some values. I save them with the preference library. I then modify all the values, then read back the original saved values.

All the values, **except one**, are restored with the associated get instruction. The one still shows the modified value. I can't see why it is wrong.

Can someone point out my error with calibratedWeight? And if you see some other general errors with the code, please point them out. (I'm not a programmer)

```
#include <Preferences.h>

Preferences preferences;

int currentFile = 1;
int outputRate = 10;           // milliSeconds
float outputGain = 1.23;
int zeroWeight = 900;          // dac value to produce Zero on scale
int calibratedWeight = 2800;   // dac value equal to 100lb calibration weight.
float DACmultiplier = 20.1;

//---------------------------------------
void savePreferences() {
    preferences.begin("ScaleSetup", false);      // false for read/write
    preferences.putInt("currentFile", currentFile);
    preferences.putInt("outputRate", outputRate);
    preferences.putFloat("outputGain", outputGain);
    preferences.putInt("zeroWeight", zeroWeight);
    preferences.putInt("calibratedWeight", calibratedWeight);  // ???
    preferences.putFloat("DACmultiplier", DACmultiplier);
    preferences.end();
}

//---------------------------------------
void getPreferences() {
    preferences.begin("ScaleSetup", false);        // false for read/write

    currentFile = preferences.getInt("currentFile", currentFile);
    outputRate = preferences.getInt("outputRate", outputRate);
    outputGain = preferences.getFloat("outputGain", outputGain);
    zeroWeight = preferences.getInt("zeroWeight", zeroWeight);
    calibratedWeight = preferences.getInt("calibratedWeight", calibratedWeight);  // ???
    DACmultiplier = preferences.getFloat("DACmultiplier", DACmultiplier);
    preferences.end();
}

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

  preferences.begin("ScaleSetup", false);        // false for read/write
  preferences.clear();
  preferences.end();
  delay(90);

  savePreferences();
  Serial.println("\n save preferences");
  Serial.println("\n Original asigned values. \n");

  Serial.printf("currentFile: %i\n", currentFile);
  Serial.printf("outputRate: %i\n", outputRate);
  Serial.printf("outputGain: %f\n", outputGain);
  Serial.printf("zeroWeight: %i\n", zeroWeight);
  Serial.printf("calibratedWeight: %i\n", calibratedWeight);  // ???
  Serial.printf("DACmultiplier: %f\n", DACmultiplier);

  Serial.println("\n modify values. \n");

  currentFile = 5;
  outputRate = 50;           // milliSeconds
  outputGain = 0.45;
  zeroWeight = 1333;         // dac value to produce Zero on scale
  calibratedWeight = 2200;   // dac value equal to 100lb calibration weight.
  DACmultiplier = 12.34;

  Serial.printf("currentFile: %i\n", currentFile);
  Serial.printf("outputRate: %i\n", outputRate);
  Serial.printf("outputGain: %f\n", outputGain);
  Serial.printf("zeroWeight: %i\n", zeroWeight);
  Serial.printf("calibratedWeight: %i\n", calibratedWeight);  // ???
  Serial.printf("DACmultiplier: %f\n", DACmultiplier);

  Serial.println("\n Get original saved preferences. \n");
  getPreferences();

  Serial.printf("currentFile: %i\n", currentFile);
  Serial.printf("outputRate: %i\n", outputRate);
  Serial.printf("outputGain: %f\n", outputGain);
  Serial.printf("zeroWeight: %i\n", zeroWeight);
  Serial.printf("calibratedWeight: %i\n", calibratedWeight);  // ???
  Serial.printf("DACmultiplier: %f\n", DACmultiplier);

//  Serial.println("Restarting in 10 seconds...");
  delay(10000);
//  ESP.restart();
}

//============================================
void loop() {}
```

The following is the result.

```
 save preferences

 Original asigned values.

currentFile: 1
outputRate: 10
outputGain: 1.230000
zeroWeight: 900
calibratedWeight: 2800
DACmultiplier: 20.100000

 modify values.

currentFile: 5
outputRate: 50
outputGain: 0.450000
zeroWeight: 1333
calibratedWeight: 2200
DACmultiplier: 12.340000

 Get original saved preferences.

currentFile: 1
outputRate: 10
outputGain: 1.230000
zeroWeight: 900
calibratedWeight: 2200
DACmultiplier: 20.100000
```

title: ESP32 preferences. One error returned, all others work. SOLVED

Answers: 1

body:
At the end of the comments above I said I thought the problem was with the variable name length.

Today I tried the debug option and then ran the code. And the following error message was included in the com output.

[E][Preferences.cpp:163] putInt(): nvs_set_i32 fail: calibratedWeight **KEY_TOO_LONG**

So I guess I was right. I didn't know anything about the debug option before.


body: Iam using 28byj-48 stepper motor and I want to know how to control its speed without using any library. I got to know that we need to add delays in between steps but I don't know how much delay I need to add and how delay effects the rpm. It is very much helpful if anyone suggest me how to do this.

title: How to control speed of 28BYJ-48 stepper motor without using library?

Answers: 1

body:
A stepper motor always needs a driver. As the ULN2003 (or similar) driver is normally shipped together with the 28byj-48 motor, I will assume, that you have this driver.

The ULN2003 has 6 pins:
- Vcc and ground need to be connected to your power source. Note, that it is risky to connect Vcc to the 5V pin of the Arduino. While that might work, when there is no load on the motor, a loaded stepper motor can draw rather high currents. Letting these current run through the Arduino might fry the voltage regulator or the power switching diode. High currents should always flow past the Arduino, not through it.

- The other 4 pins (which are marked as IN1 to IN4 on my ULN2003 driver board) are for controlling the phases. You need to connect these 4 pins to 4 individual digital outputs on your Arduino. As these are the phases of the stepper motor, you need to activate them in the correct order. You have this pattern

        1000
        0100
        0010
        0001

    for full steps, and this pattern

        1000
        1100
        0100
        0110
        0010
        0011
        0001
        1001

    for half steps. Each digit of each number represents the status of the corresponding phase; 1 means activated/HIGH, 0 means deactivated/LOW. To move the stepper motor forward, you move in the list of phases down. To move backwards, you move up in the list.

When using a stepper motor, the speed is determined by the number of steps per time interval. Let's assume, we want to use `delay()`, which is really easy, though not recommended (see explanation below), we can do steps and `delay()` inbetween:

    void loop(){
        step();
        delay(10);
    }

This code would do a step and then delay for 10ms. Thus we have about 1 step every 10ms. With `64*64=4096` steps per revolution (the motor itself seems to have 64 steps; additionally there is a gear with ratio 64 mounted on it; this might be different for you) we get a full revolution every 4.096s. When you use half the `delay()`, the speed will be double: with 5ms delay we get a full rotation every 2.048s. So you can use the `delay()` to set the speed of the motor.

Now we need the `step()` function, that I used above. There are multiple ways of writing this in code. I would propose to put the pins and phases into arrays and iterate through them with a static variable, which holds the current position in our phase pattern. Something like this:

    //in global scope defining the pins for the phases
    int stepper_pins[4] = {2, 3, 4, 5};

    void step(bool forward){
        const uint8_t phase_pattern[][4] = {
            {1,0,0,0},
            {0,1,0,0},
            ...
        };
        static uint8_t current_step = 0;
        if(forward){
            current_step = (current_step + 1) % 4;
        } else {
            current_step = (current_step - 1) % 4;
        }
        for(uint8_t i=0;i<4;i++){
            digitalWrite(stepper_pins[i], phase_pattern[current_step][i]);
        }
    }

We hold the phase pattern in a 2-dimensional array. The variable `current_step` is declared `static`, so it will keeps its value between the executions of the function. Then - depending on the parameter `forward` - we increment or decrement the current step and take that value modulo 4 (the number of phase patterns). That ensures, that `current_step` stays in the index range of our phase pattern array and will wrap around from the end of the pattern to the start and vice versa. After that, we loop through the 4 stepper pins and set them according to the current element in the `phase_pattern` array. You can easily adept that code for half steps.

Note, that this code is totally untested. Also this can be reached with way less code (at least for full steps), but I think this code is better understandable.

Now: Why not using `delay()`? This function will block the execution of other code. In that time the Arduino is just fiddling thumbs. In general that is considered bad practice. It is good, when you only need that one functionality and no responsiveness. But lets assume, you want to add a button, so that the motor reacts to your button presses. Long `delay()` calls will impact the responsiveness of your code. So instead you could use a non-blocking coding style. In the Arduino world this is easily done with the `millis()` function, which returns the number of milliseconds since startup and thus acts like a clock. Refer to the `BlinkWithoutDelay` example, that comes with the Arduino IDE, and to the many tutorials on the web, that you can find with search terms like "Arduino millis tutorial" or something like that.

---
EDIT:

> how your code controlling the motor speed?

The `delay()` call is determining the motor speed. If you want to change the speed, you need to change the value of the delay. You didn't mention any input device, so I just leave the speed constant. But of course you can define a variable for the delay and change that delay based on some input device. How exactly that is done depends on your requirements, mainly what type of input you want to use.

> if we didn't specify any delays in between steps, will it spin at its max rpm?

When you don't use any delay, then most likely your code will run too fast for the motor. The driver will set the motor phases very very fast. So fast, that the motor cannot follow that (because it has a specific inertia). (Much like the wheels of your car can loose the grip on the street and spin without moving the car, the stator of the motor can loose the magnetic grip on the rotor, which leads to further rotating phases, but a rotor, that is standing still) So you reach the maximum speed before that and it depends on the motor, the driver, how much load is on the motors and how much current your power source can give you (I once tried to provide 3 of these motors with a 1A power supply, but they moved very weak, until I upgraded to a bigger power supply, that can provide about 5A, I think). You need to test yourself, how fast you can drive your motors. So try to lower the delays step by step, until the motor cannot move in your setup anymore. Then you have the minimum delay, and the maximum speed.

Note: The `delay()` function won't be accurate for very low delays in the single digit milliseconds. In that case you might wanna use `delayMicroseconds()`, which is more accurate in that range and also can get in you in the microsecond range.