# Question
Title: Invalid use of non-static member function
In order to explain my problem I used 3 classes: `Actions`, `Triggers`, and `Combine`.

`Actions` simulates an action function, that is defined externally.

`Triggers` has that function that needed to be executed.

`Combine` combines `Actions` and `Triggers`.

Now, `void combine_funcs()` is a member function of `Combine` class, when the match between `Triggers` and `Actions` happen -\> passing a function to be executed.

Here `void combine_funcs()` is show with `std::bind`, but is was also tested straight foreward.

Error outsput is given below code.

```
class Actions
{
  typedef void (*cb_func)(uint8_t resaon);

private:
  cb_func exter_func;

public:
  void get_external_func(cb_func func)
  {
    exter_func = func;
  }
  void callAction(uint8_t i)
  {
    exter_func(i);
  }
};

class Triggers
{
public:
  void this_is_external_func(uint8_t i)
  {
    Serial.println(i);
  }
};

class Combine
{
public:
  Actions a;
  Triggers b;

  void combine_funcs()
  {
    a.get_external_func(std::bind(&Triggers::this_is_external_func, this,std::placeholders::_1));
  }
  void loop()
  {
    if (millis() > 10000)
    {
      a.callAction();
    }
  }
};

Combine combo;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Start!");
  combo.combine_funcs();
}

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

```

Compilation output:

```
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::combine_funcs()':
    sketch_jul26a:36:34: error: cannot convert 'std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type' to 'Actions::cb_func' {aka 'void (*)(unsigned char)'}
       36 |     a.get_external_func(std::bind(&Triggers::this_is_external_func, this,std::placeholders::_1));
          |                         ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          |                                  |
          |                                  std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:9:34: note:   initializing argument 1 of 'void Actions::get_external_func(Actions::cb_func)'
        9 |   void get_external_func(cb_func func)
          |                          ~~~~~~~~^~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::loop()':
    sketch_jul26a:42:20: error: no matching function for call to 'Actions::callAction()'
       42 |       a.callAction();
          |                    ^
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:13:8: note: candidate: 'void Actions::callAction(uint8_t)'
       13 |   void callAction(uint8_t i)
          |        ^~~~~~~~~~
    /Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:13:8: note:   candidate expects 1 argument, 0 provided
    exit status 1
    cannot convert 'std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type' to 'Actions::cb_func' {aka 'void (*)(unsigned char)'}

```

**EDIT\_1 : Change `Combine` class to inherete other classes**

```
class Combine : public Actions, Triggers
{
public:
  void combine_funcs()
  {
    get_external_func(this_is_external_func);
  }
  void loop()
  {
    if (millis() > 10000)
    {
      callAction(13);
    }
  }

```

yeilds same error:

```
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::combine_funcs()':
sketch_jul26a:33:23: error: invalid use of non-static member function 'void Triggers::this_is_external_func(uint8_t)'
   33 |     get_external_func(this_is_external_func);
      |                       ^~~~~~~~~~~~~~~~~~~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:22:8: note: declared here
   22 |   void this_is_external_func(uint8_t i)
      |        ^~~~~~~~~~~~~~~~~~~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: At global scope:
sketch_jul26a:60:6: error: redefinition of 'void setup()'
   60 | void setup()
      |      ^~~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:46:6: note: 'void setup()' previously defined here
   46 | void setup()
      |      ^~~~~
sketch_jul26a:68:6: error: redefinition of 'void loop()'
   68 | void loop()
      |      ^~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:54:6: note: 'void loop()' previously defined here
   54 | void loop()
      |      ^~~~
exit status 1
invalid use of non-static member function 'void Triggers::this_is_external_func(uint8_t)'

};

```

# Answer
The problem is, that the return type of bind is not the same type as the type of the original function so you can't set it with `void get_external_func(cb_func func)`.

But it looks like in X-\>Y problem. If you do OOP, use objects.

I take the sketch in the question as a test so I want comment on other parts and how to do them properly. I just made minimal changes to pass the object and call the method (member function) with the object.

```

class Triggers
{
public:
  void func(uint8_t i)
  {
    Serial.println(i);
  }
};

class Actions
{
  Triggers* trigers;

public:
  void set_triggers(Triggers* t)
  {
    trigers = t;
  }

  virtual void callAction(uint8_t i)
  {
    trigers->func(i);
  }
};

class Combine
{
public:
  Actions a;
  Triggers b;

  void combine_funcs()
  {
    a.set_triggers(&b);
  }
  void loop()
  {
    if (millis() < 10000)
    {
      a.callAction(1);
    }
  }
};

Combine combo;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Start!");
  combo.combine_funcs();
}

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

```
> 1 votes

---
Tags: c++, class
---


# Question
Title: ESP8266 NodeMCU 3v3 current for fingerprint sensor
From what i see that 3.3Vpin provide 3.3V and 400mA. The fingerprint module i use is AS608. Connecting the fingerprint module power pin to 3.3V of the nodemcu. From the datasheet it only can handle 3.3VDC, operating current\<60mA and peak current at \<70mA. Do i need to add a resistor to take the current away. Since last time i use another fingerprint module which is R307 connecting to Vin of the nodemcu and now it not working anymore?

# Answer
> 2 votes
**Be careful using Vin on the NodeMCU for 3.3V devices!** If you are powering it by 5V USB power, this Vin pin will probably have something like 4.76V on that pin. The circuit diagram shows that Vusb is connected to Vin with just a schottky diode, which drops the current about .34 volts and provides some noise isolation from the Vusb supply. If you connected a 3.3V device to this pin at 4.76V, you may have damaged your component.

You'd have to check the datasheet or documentation for the fingerprint module, but it sounds like the fingerprint module will only draw 60-70mA when it's given 3.3 volts. Datasheets often provide application examples and may specify that you do need additional resistors, capacitors, etc. The refrain in cases like this is always *read the datasheet*.

If your NodeMCU datasheet says it can provide 400mA then it should certainly be able to provide the 60-70mA that the fingerprint sensor needs. I've powered an ESP8266 by connecting its Vin pin to the Vin of another NodeMCU and they seem fairly happy together, although there tends to be quite a bit of noise on the Vin pin.

# Answer
> 1 votes
Dont mix your pins. and use 3V pin (NOT Vin), that should be able to output it. AMS1117 used in most nodeMCU's I have seen can reasonably provide 800mA medium lenght periods with voltage drop of 8-9 Volts. The MCU can reasonably take 100mA-350mA. This varies based on the amount of the work it does, running core frequency (I am not advanced enough to mess with that yet), Whether its communicating over wifi and how strong does it have to make the signal (influenced by distence, other wifi devices around). This leaves you with about 450mA to play about. As designers were responsible a good designers 50mA was cut as a margin.

Because of how voltage regulators work, the more voltage you are droping the lover current you can sustain. (worth researching heat decipation) Next is the matter of wether the device is enclosed etc. So 60mA is OK for most nodeMCU as extra load. If you reach few hundred mA and are really concerned you can reasonably control consumption simply by controling whether the nodeMCU is sending any majour communication over or if it does encryption (demanding tasks) etc.

---
Tags: esp8266, sensors, nodemcu, current
---


# Question
Title: How to control 1 servo with 2 potentiometer?
I have been building a RC plane completely from scratch using an arduino but I am fairly new to this.

Essentially I have been able to make my two arduinos communicate with each other so that when one joystick is moved, the brushless motor is activated, and when the other joystick is moved up or down, 2 servos are activated to push my plane flaps up or down. The problem I am running into is I am not sure how to control the same servo motors when I move the joystick left and right. Ideally when moved left, one servo would push a flap up and the other down, and vice versa.

The closest thing I have come across on the internet is using a push button to switch between the two control methods but I would ideally like everything to work more smoothly together w/o the push button if that makes sense.

If anyone has any ideas what to write in my code please let me know or if I need to clarify anything else.

Thank you so much for the help in advance.

# Answer
> 1 votes
First you should make sure that your inputs and outputs are separated in code. This means that the inputs (like the joystick potis) only change variables in your code. Then below the input code block you output these variables to the servos and motors. This makes the code in your situation easier, since the inputs don't trigger actions, but only set the variables for the actions, which then get executed by another code block.

Your up-down joystick sets the position for the flaps (as you have already coded). The left-right joystick then only creates a deflection from that position. You can code this like the following (in pseudo code):

```
Read up-down joystick
Map value from analog value to range 0 to 180 and save in variable "flap_pos"
Read left-right joystick
Map value from analog value to range -90 to 90 and save in variable "flap_deflection"
Write servo1 value as "flap_pos+deflection"
Write servo2 value as `flap_pos-flap_deflection"

```

Note that `flap_deflection` can be negative or positive (depending on joystick direction) and can thus deflect in both directions. And the different signs in the servo commands make sure that the deflection will behave inverted between the servos (one side moving down when the other is moving up). You will need to adjust the value mapping depending on your flap hardware. And you might want to restrain the values to a specific range (also depending on your hardware).

As you can see there is no `if` statement or similar in the pseudo code above. All the magic is in the mapping of the read analog values and the addition and subtraction.

---
Tags: servo, potentiometer
---


# Question
Title: How to connect a 4 channel relay switch directly to a 5V power source?
When connecting a 4 channel relay to a Arduino Pro mini, there is a noticeable power drain from the board when relays are active. This is clearly visible as the 16x2 LCD dims. I remember reading that this could damage the Arduino, is this true?

In any case, since the entire project will be powered by a rechargeable 12V battery, I bought some buck converters to lower the voltage from 12V to 4.66V (this is what I identified the output to be from the Arduino, I even tried increasing it to 4.8V), so I can power the relay switch directly instead of going through the Arduino.

However, the relay does not power on and I have no idea why. Can someone help me understand? I'm new to this.

## Parts

## Edit

I found this answer but I do not know if it applies and, if it does, what changes I would need to make with my current connections.

# Answer
> 0 votes
OK,

1. You should not ever use inductive load from voltage regulator shared with MCU.
2. Relays are massive eaters, and the 4.6 volts were actually caused by arduinos NTC kicking in to protect arduinos supply, the relays on your picture are designed for power around 5DC so you should design your circuit in that regards. I am impressed by the fact that little regulator on pro miny even survived it, meaning its likely to be reasonably made board. The Pro miny voltage regulator is nowhere near as powerful as thatone on Nano or UNO and only barely manages to run anything more then the MCU itself.
3. Watch your current. I am not sure whats the max current of your buck converter. Amazon specifications usually do not concern themselves with petty things like reality. SO it might not be strong enough to run all 4 relays. Though Colour is matching more often then wrong
4. Again relays are massive power eaters and the lower voltage, the higher current so you can often lower your consumption by using relays made for higher voltage.
5. Next batteries don't store that much power, get influenced by external influences and their capacity further decreases as the life goes. you can save a lot of power by using transistors/mosfets where possible.

It takes considerable additional design steps to make project run on a battery and replacing relays for bigger transformers or mosfets is often part of it.

Set any of the relays on, in arduino code and measure its voltage against ground. If its 5V then arduino is sending signal fine.

If it is not, then check the resistance between its and arduinos ground. if its just few ohms look for issues on the arduino. if resistance between grounds is big or even unmeasurable, then connect the arduino ground with relay board ground. If you can measure 3-5V (Dependant on a pro mini version) between arduinos output and the ground then you don't have enough power on the relay modules supply.

Extra note:Make sure the arduino is not powered from buck converter as volage regulator has minimum voltage diference it can drop and could not be powered via regulator from a supply of less then 6.something Volts

As stated in Jroberts answer once everithing is working, you might want to disconnect the suplly to arduino from 12 volt source to Vin; and connect your arduino to your buck converter set at 5V (4.95ish-5.05ish) to 5V pin adding 10uF capacitor between the 5V and GND on arduino. The buck converters are more efficient in dropping voltage, then voltage regulators, so that would extend your battery life. (this isnt majourisue as compared to the arduinos consuption is tiny compared t the consumption of the relays

# Answer
> 0 votes
I'm not a double-E but I'll take a stab at it.

Arduinos' on-board voltage regulators are not particularly efficient; they sink to ground whatever the board doesn't draw, dissipating it as heat. And they usually are not provided with heat sinks, meaning the regulator is heat-limited. You're powering the Arduino with 12v, so whatever current the Arduino does draw, that same current times 7 volts (the voltage drop from 12v to 5v) is waste heat. Driving four relay coils draws (using the specs on the Amazon page) adds 80mA (times 7v) to that heat dissipation.

It looks like at least some Pro Minis (yours?) use a Micrel 2095 voltage regulator which has internal current limiting which may include thermal protection(?) -- shutting off your Arduino when the regulator gets too hot.

Despite that some of the above is speculative on my part, it does suggest an experiment. You've got a regulated 5v source - instead of powering the Arduino at Vin from the 12v source, try powering it's +5v pin with +5, which would significantly reduce the regulator's power dissipation (and therefore, its temperature).

---
Tags: arduino-nano, relay
---


# Question
Title: How to wire an ESP32-S2 Dev KitM-1 for power?
I'm putting an Espressif ESP32-S2 Dev KitM-1 into a project box. The box will have 12VDC power and a 5V buck converter for the Dev Kit.

Do I need to use the USB port to power the Dev Kit or can I directly wire 5VDC to the 5V pin (and ground, of course) to power it?

# Answer
> 1 votes
The official documentation has

> Power Supply Options
>
> There are three mutually exclusive ways to provide power to the board:
>
> * Micro-USB Port, default power supply
> * 5V and GND pin headers
> * 3V3 and GND pin headers

---
Tags: power, esp32, espressif
---


# Question
Title: I want a Rotary Encoder to make 10 steps at once, but my code isn't working. What am I doing wrong?
I'm using a rotary encoder on my Arduino Micro, that is supposed to do single steps or ten steps at once, depending on which position a switch is in.

The Rotary: https://www.reichelt.de/drehimpulsegeber-15-impulse-30-rastungen-vertikal-ec11mvbfx-p315144.html?&nbc=1 (on this site are pictures and datasheets as well.)

The Switch: https://www.reichelt.de/miniatur-kippschalter-ein-aus-ein-3-a-250-v-goobay-10023-p285990.html?&nbc=1

Wiring: (image following later)

> ```
>         1--------Pin16 |  Pin A3----Switch
> Rotary  2--------GND   |  GND-------|
>         3--------PIN17 |
>
> ```

The rotary encoder gives no output, neither the Serial.print nor the gamecontroller. Also there is no output in either switch position.

**EDIT:** After using arrays and loops like @jsotola teached me, it works nearly the way its supposed to, but sometimes, although the switch is off, it clicks ten times. The code looks like this shortened **now**

```
#include <Arduino.h>
#include <Joystick.h>
#include <BasicEncoder.h>
#include <TimerOne.h>

int EncoderPins[] = {
  4, 5, 6, 7, 8, 9, 10, 11
};
int EncoderCount = 8;

BasicEncoder encoder4(EncoderPins[6], EncoderPins[7], HIGH, 2);

void timer_service() {
  encoder4.service();
}

#define joyButton16 EncoderPins[6]  // Rotary4
#define joyButton17 EncoderPins[7]  // Rotary4
#define joyButton18 21              // HDG_SWITCH := Switch to select between single and 10 steps

//Joystick(Joystick HID ID, Joystick Type, Button Count, Hat Switch Count, Include X, Include Y, Include Z, Include Rx, Include Ry, Include Rz, Include Rudder, Include Throttle, Include Accelerator, Include Brake, Include Steering)
Joystick_ Joystick(0x15, JOYSTICK_TYPE_JOYSTICK, 19, 0,
                   true /*X*/, false/*Y*/, false/*X*/,
                   false/*Rx*/, false/*Ry*/, false/*Rz*/,
                   false/*Rudder*/, false/*Throttle*/, false/*Acc*/,
                   false/*Brake*/, false/*Steer*/);

const bool initAutoSendState = true; // code is sends continuously and doesnt wait for polling

int EncoderState[] = {
  0, 0, 0, 0
};

void setup() {
  for (int q  = 0; q < EncoderCount; q++)
  {
    pinMode(EncoderPins[q], INPUT_PULLUP);
  }

  Serial.begin(9600);
  Joystick.begin();

  Timer1.initialize(100);
  Timer1.attachInterrupt(timer_service);
}

void loop() {
  GET_CHANGE();

  int CurrentButton18State = !digitalRead(joyButton18);
  switch(CurrentButton18State){
    case 0:
      switch(EncoderState[3]){
        case  1: clickButton(15); Serial.println(EncoderState[3]); break;
        case -1: clickButton(16); Serial.println(EncoderState[3]); break;
        } break;
    case 1:
      switch(EncoderState[3]){
        case  1: clickTen(15); break;
        case -1: clickTen(16); break;
        } break;
  }
}

void clickButton(int pin) {
  Joystick.setButton(pin, 1);
  delay(2);
  Joystick.setButton(pin, 0);
}

void clickTen(int pin) {
  for (int ii = 0; ii < 10; ii++)
  {
    clickButton(pin);
    Serial.println("step: "); Serial.println(ii);
    delay(10);
  }
}
void GET_CHANGE()
{
  for(int E = 0; E<4; E++)
  switch(E) {
    case 3: EncoderState[E] = encoder4.get_change(); break;
  }
}

```

# Answer
> 2 votes
This is not an answer to the question, but a tip about simplifying your code.

This is a snippet of your code.

```

void loop() {

// some more code here

  int encoder1State = encoder1.get_change();
  switch (encoder1State) {
    case 1:
      Joystick.setButton(8, 1);
      delay(25);
      Joystick.setButton(8, 0);
      //Serial.println(encoder1State);
      break;
    case -1:
      Joystick.setButton(9, 1);
      delay(25);
      Joystick.setButton(9, 0);
      //Serial.println(encoder1State);
      break;
    case 0:
      break;
  }
  int encoder2State = encoder2.get_change();
  switch (encoder2State) {
    case 1:
      Joystick.setButton(10, 1);
      delay(25);
      Joystick.setButton(10, 0);
      //Serial.println(encoder1State);
      break;
    case -1:
      Joystick.setButton(11, 1);
      delay(25);
      Joystick.setButton(11, 0);
      //Serial.println(encoder1State);
      break;
    case 0:
      break;
  }
  int encoder3State = encoder3.get_change();
  switch (encoder3State) {
    case 1:
      Joystick.setButton(12, 1);
      delay(25);
      Joystick.setButton(12, 0);
      //Serial.println(encoder1State);
      break;
    case -1:
      Joystick.setButton(13, 1);
      delay(25);
      Joystick.setButton(13, 0);
      //Serial.println(encoder1State);
      break;
    case 0:
      break;
  }
  int currentButton20State = !digitalRead(joyButton20);
  int encoder4State = encoder4.get_change();
  switch (currentButton20State) {
    case 0:
      switch (encoder4State) {
        case 1:
          Joystick.setButton(14, 1);
          delay(25);
          Joystick.setButton(14, 0);
          Serial.println(encoder4State);
          break;
        case -1:
          Joystick.setButton(15, 1);
          delay(25);
          Joystick.setButton(15, 0);
          Serial.println(encoder4State);
          break;
        case 0:
          break;
      } break;
    case 1:
      switch (encoder4State) {

        case 1:
          TenRotaryStepsUP();
          break;
        case -1:
          TenRotaryStepsDOWN();
          break;
        case 0:
          break;
      } break;
  }

  //GetParamFromFS2020();
  //ShowFlightParam();

  delay(10);

}

void TenRotaryStepsUP()
{
  for (int i = 0; i < 10; i++)
  {
    Joystick.setButton(14, 1);
    delay(25);  //for testing set on higher number e.g. 500
    Joystick.setButton(14, 0);
    Serial.println("step: "); Serial.println(i);
    delay(10);
  }
}

void TenRotaryStepsDOWN()
{
  for (int i = 0; i < 10; i++)
  {
    Joystick.setButton(15, 1);
    delay(25);
    Joystick.setButton(15, 0);
    Serial.println("step: "); Serial.println(i);
    delay(10);
  }
}

```

It can be simplified by putting repeated code into functions.

```

void loop() {

// some more code here

  int encoder1State = encoder1.get_change();
//Serial.println(encoder1State);
  switch (encoder1State) {
    case 1:
      clickButton(8);
      break;
    case -1:
      clickButton(9);
      break;
    case 0:
      break;
  }

  int encoder2State = encoder2.get_change();
  switch (encoder2State) {
    case 1:
      clickButton(10);
      break;
    case -1:
      clickButton(11);
      break;
    case 0:
      break;
  }

  int encoder3State = encoder3.get_change();
  switch (encoder3State) {
    case 1:
      clickButton(12);
      break;
    case -1:
      clickButton(13);
      break;
    case 0:
      break;
  }

  int currentButton20State = !digitalRead(joyButton20);

  int encoder4State = encoder4.get_change();
  switch (currentButton20State) {

    case 0:
      switch (encoder4State) {
        case 1:
          clickButton(14);
          break;
        case -1:
          clickButton(15);
          break;
        case 0:
          break;
      } break;

    case 1:
      switch (encoder4State) {
        case 1:
          clickTen(14);
          break;
        case -1:
          clickTen(15);
          break;
        case 0:
          break;
      } break;
  }

  //GetParamFromFS2020();
  //ShowFlightParam();

  delay(10);

}

void clickButton(int pin) {
  Joystick.setButton(pin, 1);
  delay(25);
  Joystick.setButton(pin, 0);
}

void clickTen(int pin) {
  for (int i = 0; i < 10; i++)
  {
    clickButton(pin);
    Serial.println("step: "); Serial.println(i);
    delay(10);
  }
}

```

You can even format your code like this.

```
switch (encoder3State) {
  case  1:      clickButton(12);      break;
  case -1:      clickButton(13);      break;
  case  0:                            break;
}

```

EDIT

Also refer to the following about the use of arrays as variables, to specify pins, instead of individual variable names

https://www.arduino.cc/en/Tutorial/BuiltInExamples/Arrays

eg. use `lastButtonState[1]` instead of `lastButton1State` and `joyButton[1]` instead of `joyButton1`

that will allow the use of `for` loops to repeat the same action for multiple pins

```
int currentButton2State = !digitalRead(joyButton2);
if (currentButton2State != lastButton2State) {
  Joystick.setButton(1, currentButton2State);
  if (currentButton2State == 1) {
    delay(1);
    Joystick.setButton(1, 0);
  }
  lastButton2State = currentButton2State;
}

```

becomes

```
int currentButtonState[pin] = !digitalRead(joyButton[pin]);
if (currentButtonState[pin] != lastButtonState[pin]) {
  Joystick.setButton(pin-1, currentButtonState[pin]);
  if (currentButtonState[pin] == 1) {
    delay(1);
    Joystick.setButton(pin-1, 0);
  }
  lastButtonState[pin] = currentButtonState[pin];
}

```

---
Tags: rotary-encoder, joystick
---


# Question
Title: The RF 433MHz receiver code is working only when I reset the Arduino
I'm working on RF modules using Arduino but I observed the `if` statement is only running once and I need to reset the receiver every time to make it work with real-time changes in the transmitter.

I connected the 16X2 LCD display for displaying the data. If I start the transmitter and started sending data as "1", it's showing "Bye" but when I change the transmitter data to "0", then also it is showing "Bye" only.

I changed a code a little bit but I felt it is the problem with the previous data stored in `buf` variable.

I'm expecting the LCD should display "Hi" when I changed the transmitting data to "0" from "1" which is not happening only "Bye" is displaying every time.

Here is the Arduino receiver code:

```
#include <RH_ASK.h>
#include <SPI.h>
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
RH_ASK rf_driver;
char message[2];

void setup()
{
    rf_driver.init();
    Serial.begin(9600);
    lcd.begin(16,2);
}

void loop()
{
    uint8_t buf[2];
    uint8_t buflen = sizeof(buf);

    buf[1] = '\0';

    if (!rf_driver.recv(buf, &buflen))
    {
        if (strcmp((char*)buf, "0") == 0) {
            Serial.println("Hi");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Hi");
            }

            lcd.display();
        }
        else if (strcmp((char*)buf, "1") == 0) {
            Serial.println("Bye");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Bye");
                lcd.display();
            }
        }
    }
    message[0] = (char*)buf[0];
}

```

Here is the transmitter code:

```
#include <RH_ASK.h>
#include <SPI.h>
RH_ASK rf_driver;

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

void loop()
{
    const char *msg = "1";
    rf_driver.send((uint8_t *)msg, strlen(msg));
    rf_driver.waitPacketSent();
    delay(1000);
}

```

The Serial monitor output is as follows:

# Answer
I pointed this out in a comment thinking the question would probably get closed when this was understood to be a typo, but I guess it's not a typo.

> `char message[2];` ... `if (strcmp(message[0],` You should be getting a warning for this. If not, turn your warning level up in the preferences.

If you increase the warning level you should see something that at least hints at some of what I'm saying below.

Cutting your code down to a part relevant to the description of the problem:

```
char message[2];
// ...
uint8_t buf[2];
// ...
if (strcmp(message[0], (char*)buf[0]) != 0) {

```

`strcmp()` expects a *pointer* to a character for both its first and second arguments. However, `message[0]` is of type `char` and `buf[2]` is of type `uint8_t` (ultimately an `unsigned char`). The individual characters being used are being interpreted as pointer values (as in memory addresses) which `strcmp()` expects to refer to the first characters of strings. In other words, it's going to some pair of memory addresses between 0 and 255 and trying to interpret whatever it finds at those locations as strings and compare them. The combination of what you're doing being undefined and not having a strong expectation of what to find at these memory addresses, it's not really surprising (to me anyway) how your comparisons are evaluating.

A minimal change that should bring the `strcmp` closer to making sense is:

```
if (strcmp(message, (char*)buf) != 0) {

```

`message` and `buf` here will end up evaluating to the actual locations of their strings. You were already doing half of this line correctly in your other use of buf in `if (strcmp((char*)buf, "0") == 0)`; note no `[0]` usage there.

---

In the above I'm addressing this directly and taking it for granted that you have some reason to want to use string that have one (non-null) character in them, that you intended to expand this code to longer messages somehow. Otherwise it makes more sense to just dispense with strings altogether and have `rh_driver.recv` read directly into a single character type and then use the equality comparison `==` rather than `strcmp()`.

The sections of code would look more like:

```
char message; // now individual char
// ...
uint8_t buf;  // now individual char
// ...
if (!rf_driver.recv(&buf, sizeof buf)) { //sizeof buf is 1
    if (buf == '0') { // now simple application of ==
        Serial.println("Hi");
        if (message != buf) {  // now simple application of !=
            lcd.print("Hi");
        }
// ...
message = buf; // no longer using [0] because no longer an array

```
> 1 votes

---
Tags: arduino-uno, serial, communication, rf
---


title: Ethernet shield reset problems

text:
# Question
Title: Ethernet shield reset problems
I know there are multiple threads about ethernet shields not starting properly after power up and that there are versions that don't have those problems. But which versions are okay? Which versions do not require extra soldering/pin bending/physical resets?

How good are chinese rip-offs of those versions?

# Answer
> 1 votes
I have worked with Ethernet Shields and modules. Most of them has reset issue. So I just put a 100nF Capacitor between the reset pin and ground pin. This solution works for most of the time.

This issue is there because the IC on board the shield does not have the power on reset option.

You can also tie the reset pin of your module with the reset pin of the Arduino.

# Answer
> 0 votes
If you don't want to make any modifications to the shield, and you don't want to make any modifications in code, then there really is only one option:

* Don't use cheap knockoffs, but buy a genuine Arduino one.

If you have a board that requires modifications to work properly and if you're unwilling to make those required modifications then you can not just magic it into working by waving your magic wand.

---
Tags: arduino-uno, ethernet
---


title: Duplicate Arduino SD Library

text:
# Question
Title: Duplicate Arduino SD Library
I need to have two independent arduino sd libraries so that I can modify one and have the other one intact. I struggle to do so. Does anyone know if this is even possible? What should be the path to properly do so?

I tried a lot of things but I always end up in a spot where I dont know what code is working and what is not. Last try I duplicated all the files and renambed all the functions to whatever"2" but couldn't make it work

# Answer
If you want to use two SD card than instead of copying the whole library just create another instance of the class like

```
SDClass SD2;

```

Now you can call SD2.begin(CS\_PIN\_2) or any other function of the sd library.
> 1 votes

---
Tags: sd.h
---


title: ESP8266 SDCard initialization bug

text:
# Question
Title: ESP8266 SDCard initialization bug
I have an ESP8266 wich is connected to an SDCard module, an SHT21 sensor and an BMP280. The idea is that I want to log data from the sensors to the SD Card, but if I initialize the SD Card with SD.begin(chipSelect), all the data from sensors become NaN or random values. If I initialize it, it is logging only NaN on the sd card, so the card is working, and if I dont initialize it, I get good and normal values into the serial monitor. The Card Module is connected to D5,D6,D7,D8, and the two sensors are connected to D1 and D2, and all powered from 3v. Any idea? This is the code:

```
#include <Wire.h>
#include <SPI.h>
#include <Sodaq_SHT2x.h>
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp;
#include <SD.h>
File myFile;
float pressure;
float temperature;
float altimeter;
float humidity;
float dewPoint;
float temperature2;
float humidity2;
float dewPoint2;
int chipSelect = 5;
float QNH = 1015;
const int BMP_address = 0x76;

int ledB = D4;
int ledG = D3;
int ledR = D0;

void setup()
{

  Serial.println("initialization done.");
  Wire.begin();
  Serial.begin(9600);
  bmp.begin(BMP_address);
  Serial.println("PTHBox Logger");
    //Checking if SDCard is alive
    if (SD.begin(5)){
    Serial.println("SD card is alive");
  }else{
    Serial.println("SD card is ded");
    while(1); //halt program
  }

//Checking the logfiles from the SDCard and deleting them
  if (SD.exists("/csv.txt"))
  {
    Serial.println("Removing csv.txt");
    SD.remove("/csv.txt");
    Serial.println("csv.txt is fresh and ready to log");
  }

//  Writing headers to csv.txt
   myFile = SD.open("/csv.txt", FILE_WRITE);
   if (myFile) // it opened OK
    {
    Serial.println("Writing headers to csv.txt");
    myFile.println("Altitude,Pressure,Temperature,Humidity,DewPoint");
    myFile.close();
    Serial.println("Headers written");
    }else {
    Serial.println("Error opening csv.txt");
  }
//  Setting pinModes for the LED
  pinMode(D0, OUTPUT);
  pinMode(D3, OUTPUT);
  pinMode(D4, OUTPUT);
  //Set PWM frequency 500, default is 1000
  //Set range 0~100, default is 0~1023
  analogWriteFreq(500);
  analogWriteRange(100);

}

void loop()
{
  // Testing the led
  analogWrite(ledR, 100);
  analogWrite(ledG, 0);
  analogWrite(ledB, 60);

  Serial.print("Humidity(%RH): ");
  Serial.print(SHT2x.GetHumidity());
  Serial.print("     Temperature(C): ");
  Serial.print(SHT2x.GetTemperature());
  Serial.print("     Dewpoint(C): ");
  Serial.print(SHT2x.GetDewPoint());
  pressure = bmp.readPressure()/100;  //and conv Pa to hPa
  Serial.print("     BMP PRESSURE");
  Serial.print(pressure);
  Serial.print("     BMP ALT");
  Serial.println(bmp.readAltitude (QNH));
  Serial.print("     BMP TEMP");
  Serial.print(bmp.readTemperature());

//  Assigning values to variables

 pressure = bmp.readPressure()/100;  //and conv Pa to hPa
 temperature = (bmp.readTemperature()); //temperature from bmp
 altimeter = bmp.readAltitude (QNH); //QNH is local sea lev pressure
 humidity = (SHT2x.GetHumidity());
 dewPoint = (SHT2x.GetDewPoint());
 temperature2 = (SHT2x.GetTemperature());

//  Writing the values to SDCARD
myFile = SD.open("/csv.txt", FILE_WRITE);
    // if the file opened okay, write to it:
    if (myFile)
    {
      Serial.println("Writing to csv.txt");
      myFile.print(altimeter);
      myFile.print(pressure);
      myFile.print(temperature);
      myFile.print(humidity);
      myFile.println(dewPoint);
      myFile.close();
    }
    else
    {
      Serial.println("error opening csv.txt");
    }
  delay(1000);
}

```

# Answer
> 0 votes
You're calling

```
if (SD.begin(5)){

```

GPIO5 is not necessarily `D5`. Use the `D5` constant; it will evaluate to whatever GPIO number `D5` actually is. So,

```
if (SD.begin(D5)){

```

Although you don't appear to be using the variable, you also have:

```
int chipSelect = 5;

```

which should be

```
int chipSelect = D5;

```

The difference between GPIO numbers and pin labels leads to problems for a lot of people. `GPIOx` is specific to the ESP8266 - it corresponds to a pin number and function on the actual chip; `Dx` is specific to the particular breakout board and is not always the same GPIO number (or the same between breakout boards).

---
Tags: esp8266, esp
---


# Question
Title: DS1307RTC Outputting cryptic 165/165/2165 date. What are some possible fixes?
My board.

I think I have it wired correctly (the lights aren't, but the board is).

I've read through the first few Google results to no avail.

My sample code to test the chip:

```
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

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

void setup () {
  while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
    }

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

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

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

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

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

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

```

Serial output:

```
`RTC is NOT running!
2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

2165/165/165 (Tuesday) 165:165:85
 since midnight 1/1/1970 = 1551138385s = 17952d
 now + 7d + 30s: 2019/3/5 12:16:31

```

# Answer
Had the same issue, however, my RTC was 1302 (not 1307) and yours seems to be as well, please check. If it's 1302, use this library: https://github.com/msparks/arduino-ds1302

Also, make sure you connect pins like this:

1. Arduino Pin 7 goes to CLK
2. Arduino Pin 6 goes to DAT
3. Arduino Pin 5 goes to RST
4. Arduino 5+ goes to VCC
5. Arduino GND goes to GND
> 3 votes

# Answer
Your picure shows also another device on the bread board. Remove that and ensure that:

Uno Ground --\> 1307 Ground

Uno 5Volt --\> 1307 +5v

Uno A4 --\> 1307 Data

Uno A5 --\> 1307 Clock

If the 1307 has a power led indicator, it should be lit.

If that still does not work, then in the code, comment this line out:

```
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

```

and uncomment this line to set the 1307 with a specific time stamp:

```
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));

```
> 2 votes

# Answer
Put in the following line in void setup():

```
Wire.begin();

```

(Assuming Wire library has been included.) This will set up the I2C connection between the Master (Arduino) and the Slave (RTC).

For more generic use, the syntax is: Wire.begin(address);

The complete code is:

```
void setup () {
  Wire.begin();
  Serial.begin(9600);
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // UNCOMMENT TO SET TIME & DATE TO THAT AT COMPILATION.
  //rtc.adjust(DateTime(2017, 8, 31, 14, 45, 14 )); // UNCOMMENT TO SET TIME & DATE MANUALLY. (YEAR, MONTH, DAY, 24-HOUR, MINUTE, SECOND)

}

```
> 2 votes

# Answer
On the DS3231 seems like the device can get unsynchronized with the microcontroller. Not sure if the same problem with DS1307 I think worth trying. My complete solution on stackoverflow for the same question

> The I2C interface is accessible whenever either VCC or VBAT is at a valid level. If a microcontroller connected to the DS3231 resets because of a loss of VCC or other event, it is possible that the microcontroller and DS3231 I2C communications could become unsynchronized, e.g., the microcontroller resets while reading data from the DS3231. When the microcontroller resets, the DS3231 I2C interface may be placed into a known state by toggling SCL until SDA is observed to be at a high level. At that point the microcontroller should pull SDA low while SCL is high, generating a START condition.
> 2 votes

# Answer
I had the same "165" problem. Very intermittent. Turns out that I was drawing too much power from the Arduino rails for the circuit I was controlling. I was being lazy by not powering it independently when I started. Nick Gannon on arduino.cc showed where the 165 came from and solved my problem. He included the bcd math.
https://forum.arduino.cc/index.php?topic=184908.0
> 2 votes

# Answer
With the Arduino Due, the 165 problem came up intermittently with a knock off DS3231 (compatible with 1307 supposedly). Tried switching to a different RTC but it didn't help. Switching to an Arduino Mega 2560 seems to have resolved it. The Mega 2560 is a lot slower so maybe it was a clock speed issue? In any case, it was useful for resolving the intermittent issue.

That said, if you always get 165:165 it means your Arduino is not communicating with your RTC. This is a different problem and won't be solved by switching Arduinos.
> 1 votes

# Answer
I can verify that the 1302 does not work with the 1307 library. Very different chips. No I2C on the 1302. I'm trying to setup an autosync with the 1302 by studying how the 1307 does it... not having a lot of success. I did it once before, and it is driving me bonkers that I can't figure it out again.
> 0 votes

# Answer
I had the same exact issue and discovered that the Tiny RTC 1307 board. I found that the board I had was operating at 3.3v. Once I moved the board to a 3.3v pin on my Arduino Nano.
> 0 votes

# Answer
I had same issue. Put in setup `rtc.begin();`
> 0 votes

# Answer
I had the same problem 165/165.

I change the Crystal 32 kHz which solved my problem.
> -1 votes

---
Tags: rtc
---


# Question
Title: Code explanation when pH sensor is connected to Arduino
I have to measure the pH value for some experiment. I have checked various codes and all include the average of pH values.

```
#define SensorPin 0          // the pH meter Analog output is connected with the Arduino’s Analog
unsigned long int avgValue;  //Store the average value of the sensor feedback
float b;
int buf[10],temp;

void setup()
{
  Serial.begin(9600);
  Serial.println("Ready");    //Test the serial monitor
}
void loop()
{
  for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
  {
    buf[i]=analogRead(SensorPin);
    delay(10);
  }
  for(int i=0;i<9;i++)        //sort the analog from small to large
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //take the average value of 6 center sample
  avgValue+=buf[i];
  float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
  phValue=3.5*phValue;                      //convert the millivolt into pH value
  Serial.print("pH:");
  Serial.println(phValue,2);
  delay(5000);
}

```

Kindly explain the meaning of these two lines. Why take constant values as in bold (**5/1024**/6) and (**3.5**\*pH)? Can I use some other value instead of these?

```
float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
  phValue=3.5*phValue;                      //convert the millivolt into pH value

```

# Answer
This is a fine example why magic numbers are bad. Always use symbolic constants.

**Concerning the first line:**

1. The "5.0" is the reference voltage of the ADC, apparently 5.0 volts.
2. The "1024" is the width of the range of values returned by the ADC.
3. The "6" is the number of samples summed up in the two lines before.

The ADC returns values in the range from 0 to 1023, giving you 1024 different values. If it measures 0% of its references voltage, it returns 0. If it measures 100% of its references voltage, it returns 1023. Actually the value "1024" should be "1023", but considering the accuracy it does not really matter.

By dividing the measured value by 1024, a single ADC value ranges from 0.0 (0%) to 0.999 (nearly 100%).

Multiplication by "5.0" gives the voltage, if we suppose that the reference voltage is 5.0 volts.

As 6 samples are summed up, another division by 6 is necessary to obtain the average.

In contrary to the comment the result of the first line is the measured and averaged voltage in volts, not in millivolts.

If the author had used smybolic constants, no comment would have been necessary and thus could not become erroneous.

**Concerning the second line:**

Apparently this is the factor of the sensor between voltage and pH value. A voltage of 0 volts means a pH value of 0, and a voltage of 4 volts means a pH value of 14. *Note: pH can only range from 0 to 14.*

Since you did not post a link to the data sheet of the used sensor, we cannot check this. But you can.

**A first approach with symbolic constants:**

```
static const int FIRST_INDEX_FOR_AVERAGE = 2;
static const int NUMBER_OF_VALUES_TO_AVERAGE = 6;

static const float FULL_SCALE_IN_VOLTS = 5.0;
static const int ADC_MAXIMUM = 1023; // was 1024

static const float PH_PER_VOLT = 3.5; // or even better 14.0 / 4.0

// ...

avgValue = 0;
for (int i = FIRST_INDEX_FOR_AVERAGE;
     i < FIRST_INDEX_FOR_AVERAGE + NUMBER_OF_VALUES_TO_AVERAGE;
     i++)
{
    avgValue += buf[i];
}

float phValue = avgValue * FULL_SCALE_IN_VOLTS / ADC_MAXIMUM / NUMBER_OF_VALUES_TO_AVERAGE;

phValue = phValue * PH_PER_VOLT;

```

There is no need to cast `avgValue` to `float` since `FULL_SCALE_IN_VOLTS` is `float` and so the calculations are done in floating point.
> 1 votes

---
Tags: arduino-uno, nodemcu, constants
---


# Question
Title: What type of connector does the GROVE system use?
What type of connector does GROVE use?

I'm interested in wiring some old sensors so they're compatible with GROVE, so I first need to identify the connector so I can buy the housing and pins to crimp. It looks to be some type of JST connector, but there are many different sizes, each with incompatible pitches and a lot of retailers often advertise them incorrectly. Unfortunately, I can't find any documentation of the connector on Seeedstudio's site.

# Answer
> 12 votes
It looks like the Grove connector is proprietary. I emailed Seeedstudio, and they directed me to this datasheet. Unless I'm reading it incorrectly, it doesn't appear to correspond to any type of JST connector, although it's similar. It has 2mm pin spacing, which would make it closest to the JST-PH type, but all the other dimensions are slightly different.

# Answer
> 11 votes
Here is the updated link on the seed website.

http://wiki.seeedstudio.com/wiki/File:3470130P1.pdf

Also note that Digikey now stocks seeedstudio stuff.

http://www.digikey.com/product-detail/en/seeed-technology-co-ltd/110990030/1597-1082-ND/5482560

http://www.digikey.ca/product-detail/en/seeed-technology-co-ltd/110990037/1597-1083-ND/5482561

# Answer
> 7 votes
I believe the OEM part is NS-Tech 1125S-4P: Wire to Board connector \> PITCH 2.00mm \> 1125 Series

Good luck finding a vendor!

# Answer
> 5 votes
It is not a JST connector. There are ramps on the side of the connector that won't allow the grove/seeed cables slide into the connectors. After I shaved/cut off the ramps, to allow them to fit into the connector, I found that the pins are slightly offset in there vertical alignment. This appears to be a custom connector. However, if anyone knows better, I would be interested, but the answer is not JST.

# Answer
> 3 votes
It is proprietary. It makes it hard to build your own custom length cables. But then if you are, you probably don't need Grove modules in the first place. I would use them more if I could build a cable. The JST PH 2.0 definitely doesn't work well, even if you shave it down. The PH also doesn't have the locking tab that the Grove connector does. It's interesting that some of the Grove boards have both JST PH 2.0 as well as Grove connectors for different purposes (e.g. LiPo battery connector)

# Answer
> 2 votes
These look like equivalents to the Molex Sherlock-series connectors (www.molex.com/molex/products/family?key=sherlock). I've ordered a Grove-compatible board that should get here Monday. I'll try connecting a Sherlock connector to it, and if I remember I'll give an answer back here as to whether it mates and locks properly. The pin pitch and pin dimensions are the same, I can tell that already, and it sure "looks like" a Sherlock connector.

# Answer
> 1 votes
It's definitely not a jst-connector - please have a look at them here http://www.amazon.com/Seeedstudio-20-pack-Grove-Connectors/dp/B00BB0I7V2 (the seeed website seems to be down at the moment). I Eagle you would search for a TWIG-4P-2.0. These guys have 4PINs which are connected to ground and VCC + the data lines depending on the sensor you want to use.

# Answer
> 1 votes
Here there are GROVE connectors in SMD and a drawing is included: Grove - SMD Universal 4 pin connector (10 Stück).

# Answer
> 1 votes
Following up from Cerin's answer, as the link to the datasheet on Seeed's website appears to have expired, I also contacted the technical support team at Seeed.

They sent me, I assume, the same datasheet. Here is a link to it, 110990030-model, and here is a screenshot, should the link die in the future:

Along with the datasheet, I also received the following information:

> 11006005(OLD) --\>110060161(NEW)
>
> Grove - Light Sensor change to V1.2, which had another light sensor.
>
> Others same.
>
> 101020040(OLD)--\>101020175(NEW)
>
> Just some performance optimization.

From MCU's answer, and the linked eBay item for the Grove - SMD Universal 4 pin connector (10 Stück), the diagram below also shows the dimensions. However, it is quite clearly only a **three pin** connector, and *not* the **four pin** connector used in the Grove system:

See also Grove connector.

# Answer
> 1 votes
Have a look at:

YEONHO\_ELECTRONICS\_20037wr

YEONHO\_ELECTRONICS\_SMH200

YEONHO\_ELECTRONICS\_YST200

or

CJT CONN A2008 WR S 4P / A2008 H ......

# Answer
> 1 votes
This connector A2005(PHB-SMD) Series has become common in China, I have not found a supplier in the USA that carries it yet.

There is a similar connector, the A2008 series here.

A2005 images without-latching-plug:

# Answer
> 1 votes
I might have found at least one of the many possible manufacturers that make these types of connector. The manufacturer is Boom Precision Electronics and you can buy the connectors through LCSC.

Here are the links to four of the connectors on LCSC.

Vert. THT 4-Pin 2.00mm RA THT 4-Pin 2.00mm Vert. SMD 4-Pin 2.00mm RA SMD 4-Pin 2.00mm

Disclaimer: I never bought these connectors listed above so I never got the chance to try and mate the grove cable housing with it. It however does seem to fit the dimension and shape based on the drawings.

---
Tags: sensors, pins, wires
---


# Question
Title: Define a custom baudrate in Serial Monitor
Is there a way to define a different baud rate from the ones we are shown in the dropdown menu of the Serial Monitor? I want to define a custom value.

# Answer
There is no easy way to do so. The list of available baud rates is hard-coded in the Java source of the Arduino IDE. To add a custom rate, you would have to modify the source code and rebuild the IDE.

I suggest you consider using a terminal emulator instead of the serial monitor. On Linux, I like picocom: not a real terminal emulator, but a minimal program that “connects” the terminal emulator you are already using (gnome-terminal, rxvt...) to the serial port. It supports custom baud rates, which it rounds to the nearest rate the hardware can provide. Picocom works on Mac too.

For Windows, Adafruit recommends Putty or X-CTU. Sparkfun recommends quite a few options for Windows, Mac and Linux.
> 4 votes

# Answer
If you are growing out of the Arduino IDE consider swaping to PlatformIO, baud-rate is just one of the many extra things you will get a chance to tweek. If you are on X64 architecture, you can although use eclipse, but I find platformIO bit better for Arduino. Arduino IDE is an OK starter, but to grow you will need to move further.

To add to Edgar Bonets answer, there are many other serial terminals including but not limited to: pyserial (multiplatform),screen (UNIXes), even good old Putty (runs on nearly everything that can blink I believe even on comodore)...
> 0 votes

---
Tags: arduino-ide, baud-rate
---


# Question
Title: Mouse.move: how do I move the mouse to the center of a screen?
I have a program operating in full screen mode. I would like to move the mouse to the center of the screen. Is this something I can do with the functionality of Mouse.h? https://www.arduino.cc/reference/en/language/functions/usb/mouse/

Mouse.move moves fixed increments. maybe I should change the mouse start location in the computer program.

my issue, is that the "circuit playground" is the primary interface, using the accelerator for position. Once the computer is running the software, the Arduino has to be centered to work properly.

alternatively, is there a command I can send that could center the mouse?

# Answer
> 4 votes
There are two ways of working with HID mice - absolute and relative. The Arduino `Mouse` library only works in relative mode, but you want absolute.

There's another library **https://github.com/NicoHood/HID** which does do considerably more than the normal Arduino HID libraries - including "Absolute Mouse".

---
Tags: programming, keyboard, mouse
---


title: Esp8266-01 and Arduino

text:
# Question
Title: Esp8266-01 and Arduino
I recently bought an ESP8266 (ESP-01s). When I first connected it to Arduino,AT commands showed. Then when I uploaded other code,the commands stopped showing. I flashed it using many flashing tools and firmwares and the flashing was successful but AT commands still not showing. ESP is not responding to any code I execute in Arduino.

# Answer
> 1 votes
This is a common problem with newcommers to the ESP8266. It ships with AT commands working and as soon as you try putting your own code on it the AT commands stop working.

Well, of course they do.

The AT commands aren't something the ESP8266 does. It's something the software installed on the ESP8266 does, and you just deleted that software and put your own software on.

You can *either* have AT commands (by installing the correct AT firmware for your board) *or* run your own software on it - not both (unless, of course, you write your software in such a way that it responds to AT commands, but that's a completely separate thing...)

---
Tags: esp8266
---


# Question
Title: Not enough memory error using OneSheeld.h
I'm a dairy farmer and I'm new to playing around with Arduino's. I created a code to send me SMS's when my equipment stops working as it should, but I run into a "Not enough memory" error. Here's my code:

```
#include <OneSheeld.h>
int IPFeed = 13;
int IPScraper = 12;
int IPPump = 11;
int XVal = 0;
int TFeedCharge = 0;
int TFeedRun = 0;
int TScraper = 0;
int TPump = 0;
int TLFeedCharge = 60;
int TLFeedRun = 60;
int TLManure = 2;
int TInc = 60000;

void setup() {
  pinMode(IPFeed, INPUT);
  pinMode(IPScraper, INPUT);
  pinMode(IPPump, INPUT);
  OneSheeld.begin();
}

void loop() {
  XVal = digitalRead(IPFeed);
  if (XVal == HIGH) {
    TFeedRun = 0;
    TFeedCharge = TFeedCharge +1;
    if (TFeedCharge == TLFeedCharge) {
      delay(150);
      SMS.send("613xxxxxx6","ProFeed 2020 is stoped at the charging station.");
      delay(150);
      SMS.send("613xxxxxx9","ProFeed 2020 is stoped at the charging station.");
      TFeedCharge = 0;
    }
  }
  else {
    TFeedCharge = 0;
    TFeedRun = TFeedRun +1;
    if (TFeedRun == TLFeedRun) {
      delay(150);
      SMS.send("613xxxxxx6","ProFeed 2020 is stopped away from the charging station.");
      delay(150);
      SMS.send("613xxxxxx9","ProFeed 2020 is stopped away from the charging station.");
      TFeedRun = 0;
    }
  }

  XVal = digitalRead(IPScraper);
  if (XVal == HIGH) {
    TScraper = TScraper +1;
    if (TScraper == TLManure) {
      delay(150);
      SMS.send("613xxxxxx6","The manure scraper has stopped working.");
      delay(150);
      SMS.send("613xxxxxx9","The manure scraper has stopped working.");
      TScraper = 0;
    }
  }

  XVal = digitalRead(IPPump);
  if (XVal == HIGH) {
    TPump = TPump +1;
    if (TPump == TLManure) {
      delay(150);
      SMS.send("613xxxxxx6","The manure pump has stopped working.");
      delay(150);
      SMS.send("613xxxxxx9","The manure pump has stopped working.");
      TPump = 0;
    }
  }

  delay(TInc);
}

```

Here is the error message:

```
Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano, ATmega328P"

Sketch uses 24812 bytes (80%) of program storage space. Maximum is 30720 bytes.

Global variables use 2087 bytes (101%) of dynamic memory, leaving -39 bytes for local variables. Maximum is 2048 bytes.

Not enough memory; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing your footprint.

data section exceeds available space in board

Error compiling for board Arduino Nano.

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

```

Any ideas on how to fix this issue?

# Answer
> 6 votes
Including the whole library, which is what you are doing, does not work on small boards like yours. Instead you have to only use the parts of the library that you need.

Fortunately the OneSheeld library provides a simple way of doing that, through the use of a couple of `#define` directives *before* you include the library.

Since you are only using the SMS functionality you only need to turn on that functionality - so start your sketch with:

```
#define CUSTOM_SETTINGS
#define INCLUDE_SMS_SHIELD

```

before the `#include <OneSheeld.h>` line and it will compile.

# Answer
> 3 votes
Your problem is caused by using too much RAM, not program memory, as the error message says:

`Global variables use 2087 bytes (101%) of dynamic memory, leaving -39 bytes for local variables. Maximum is 2048 bytes.`

The library you are using is likely occupying a large amount of RAM. However, currently your alert messages are stored in RAM as well, causing the limit to be exceeded. To make the compiler store the strings in program memory (flash) instead of RAM, you can wrap each string in an `F()` macro. For example,

`SMS.send("613xxxxxx6","ProFeed 2020 is stopped away from the charging station.");`

becomes

`SMS.send("613xxxxxx6",F("ProFeed 2020 is stopped away from the charging station."));`

(You can also wrap the phone number to save even more RAM, but as the limit has only been exceeded by 39 bytes/characters it is unnecessary.)

Majenko's answer might potentially work too as the excluded parts of the library might happen to save just enough RAM, but the `F()` technique is still handy.

---
Tags: memory, error
---


title: Arduino + ESP8266 to send MQTT messages

text:
# Question
Title: Arduino + ESP8266 to send MQTT messages
I'm wondering if an Arduino Uno (or any other 328 family) that connects via Serial to an ESP8266 can send MQTT messages, rather than AT commands.

# Answer
> 2 votes
*I didn't use MQTT yet so I didn't try any of the following options. I only know they exist.*

1. AT firmware version 2 has a set of AT commands for MQTT. But development of AT 2 for esp8266 was ended with version 2.2. It requires an esp8266 with a 4 MB flash.
2. a very old esp8266 firmware called ESPLink has support to register to a MQTT topic and then use it in Arduino with the EL-link library. (The main goal of the ESPLink firmware was OTA update for Uno)
3. PubSubClient library is a very popular Arduino library for MQTT. It works over any standard Arduino networking library. For esp8266 there are multiple options for a firmware+library combination. I can only recommend my WiFiEspAT library (all others have too many problems). WiFiEspAT works with AT firmware in esp8266. Best is to use AT 1.7.5 or the 'fake' AT firmware ESP\_ATMod, which is an Arduino sketch.

The third option will take much more flash and RAM than the first two, but it is a standard and portable way. You can port it to other networking library or other MCU type.

EDIT: Another option is to write a sketch with MQTT for the esp8266 directly and communicate the data with Uno or not use the Uno at all.

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


# Question
Title: Why does keyboard.h add 136 to each key?
I want to create a custom keyboard mapping in the official arduino keyboard library

Why do the key definitions add 136 to each number?

See Keyboard\_es\_ES.h on github

```
#define KEY_MASCULINE_ORDINAL    (136+0x35)
#define KEY_INVERTED_EXCLAMATION (136+0x2e)
#define KEY_GRAVE                (136+0x2f)
#define KEY_N_TILDE              (136+0x33)
#define KEY_ACUTE                (136+0x34)
#define KEY_C_CEDILLA            (136+0x31)

```

Looking at the ascii table, I see nothing special about value 136

# Answer
> 2 votes
It could be argued that this is an implementation detail of the library, that does not need to be documented. ;-) Anyway, here is the reason...

The keyboard library uses a custom encoding scheme for representing *both* characters and keys. The public methods `press()`, `release()`, `write()`, `print()` and `println()` interpret the user-provided data according to this scheme. With this encoding, the interpretation of a byte depends on which of these three ranges it belongs to:

* Bytes in the range \[0, 127\] are understood to be ASCII characters. This is what enables you to write things like `Keyboard.println("Hello!");`. The library uses a keyboard layout array to map those characters to key scan codes¹, possibly modified by Shift or AltGr. You provide a pointer to this array as an argument to `begin()`.
* Bytes in the range \[128, 135\] are interpreted as modifier keys, such as `KEY_LEFT_CTRL`, `KEY_RIGHT_SHIFT`, etc. Note that these keys do not have proper scan codes, as their state is transmitted to the host as a bit map (one byte for the eight keys) rather than as codes added to a list.
* Bytes in the range \[136, 255\] are interpreted as raw scan codes in the range \[0, 119\], shifted by 136. This is what lets you actuate arbitrary keys such as `KEY_PRINT_SCREEN` or `KEY_LEFT_ARROW`. All scan codes of a standard full-size PC keyboard (ANSI 104 or ISO 105) lie in the range \[4, 101\]: you can access all of them, and even some more like `KEY_F24`.

Regarding the file Keyboard\_es\_ES.h: the codes in there are for keys that match ASCII characters in the US layout but not in the Spanish layout. The purpose is to ensure that every key of a ISO 105 keyboard can be actuated using either an ASCII character (like `Keyboard.press('a');`) or a `KEY_*` macro.

¹ The USB standard calls them “usage codes”, but the old term “scan codes” seems more prevalent.

---
Tags: keyboard
---


title: One LED in 4x4 matrix does not turn on

text:
# Question
Title: One LED in 4x4 matrix does not turn on
I'm an art student and absolute beginner to electronics/code - my broader goal is to learn how to control individual LEDs when there are many of them (like 64 or more even, so am learning about shift registers, multiplexing etc. also).

I have been working with a 4x4 matrix example by Jon Fox. I have breadboarded it as below and checked it multiple times.

For the most part it's successful; the code runs and I get the LED animations in his code. I am also able to anticipate which parts of the code refer to which LEDs when I test by commenting out parts of the code - for example `r1c1()` refers to the top row, right-most LED.

However, the top row, second from the left LED does not turn on.

I have tested the individual LEDs before starting, tested the connections of the wires in case they don't make good connection in the breadboard, and tried adding 330 Ω resistors to the rows (instead of the orange connection wire in the image), and tried with 1 kΩ resistors instead of 220 Ω. The reason I tried those values was that I have been successful when I've used another set up I have, image below.

The blue and the white LEDs draw similar voltage so as far as I understand this wouldn't affect anything. The code runs great on this also.

I understand I could still be making some human error, especially as I've been going crazy with this. However, because I really want to understand the factors involved in controlling LEDs, I'd love to know if at all there are other variables at play.

For one, I was looking into 'floating inputs' hence tried adding the other set of resistors, and tried colour LEDs (more bulbs were either off or dim) as well as 3 mm white LEDs (same result as 5mm). The most difficult thing in this process is wondering what I don't know, so if anyone can direct me towards things I should consider for my purpose, or help me solve my current problem, I'd be really grateful.

# Answer
It is very difficult to be certain. You state that the second from the left LED in to top row is not turning on as expected. In the bread-board diagram this LED is plugged into holes D7 and D8. However, in the image it appears this LED is plugged into holes D8 and E8.

The exact letter/number may not matter if you are not following your bread-board diagram precisely. However all pins in a row (i.e. A8, B8, C8, ... , E8) are shorted together. So plugging in an LED into holes D8 and E8 would prevent it from lighting up.

Also, you have added resistors to your matrix which are not in the bread-board diagram. The column resistors appear correct but the row resistors are questionable. In practice, if you are going to light only 1 LED in a column at a time, then you might get by with only column resistors. For such a configuration (only column resistors) you may see the LEDs dim if you light more than 1 per column. If you do want to light more then one LED per column, the trick is to let the software switch LEDs on and off such that there is only one lit per column at a time. But fast enough so that a human eye can not see it. So a bit faster than 100ms.
> 0 votes

---
Tags: led, voltage, led-matrix
---


# Question
Title: How can an Arduino-Quadcopter be stabilized?
I have built an arduino quad-copter and I am using an MPU6050 to read the rotational position and velocity of the aircraft. The problem is that I cannot get the thing to stabilize. Watch this video here to get an idea of what I mean.

So as you can see from the footage (and you did watch it, right?), I'm not even getting steady oscillations, it's just random. What I don't understand is how people get their quad-copters to oscillate very quickly (maybe 10 times per second) and then trim up their PID gains to smooth it out, whereas if I raise my p-gain high enough for it to adjust that quickly, the quad-copter just goes berserk and tries to kill me.

And, speaking of p-gains, here's the PID I wrote:

```
float KrP = 0.002000;
float KrI = 0.000001;
float KrD = 0.200000;

void adjustRoll(float currentRoll, int newRoll) {
  if (thrust <= 1200){
    inAutoRoll = false;
    NWPower = thrust;
    NEPower = thrust;        //PID not ready to turn on yet? Just set motor powers
    SWPower = thrust;        //equal to the throttle.
    SEPower = thrust;

    I_roll = 0;              // Reset the integral.
    return;                  // Don't do anything else
  }

  float newRate = 2 * (newRoll - currentRoll); // How fast should the drone try to
                                                                       // adjust, based on the error.

  if (newRate > 50)newRate = 50;        // Don't adjust too fast!
  else if (newRate < -50)newRate = -50;

  float offset = newRate - rollRate;

  I_roll += KrI * offset;

  if(!inAutoRoll) {        // Is the PID just now turning on? (Throttle requirement met).
    lastRollRateOffset = offset;  //Smooth transition.
    inAutoRoll = true;
  }

  float adjust = (KrP * offset) + (KrI * I_roll) + (KrD * (offset - lastRollRateOffset));

  NWPower += adjust;
  NEPower -= adjust;
  SWPower += adjust;
  SEPower -= adjust;

  if (NWPower > maxOut) NWPower = maxOut;
   else if (NWPower < minOut) NWPower = minOut;

  if (NEPower > maxOut) NEPower = maxOut;
   else if (NEPower < minOut) NEPower = minOut;

  if (SWPower > maxOut) SWPower = maxOut;
   else if (SWPower < minOut) SWPower = minOut;

  if (SEPower > maxOut) SEPower = maxOut;
   else if (SEPower < minOut) SEPower = minOut;

  lastRollRateOffset = offset;
}

```

And in case you were wondering... yes, I do know about integral windup. The reason I have not dealt with that in my code is because the quadcopter is no where near stable, so I'm not worrying about perfection just yet. Also, I have my I-gain set to 0.000001, so it doesn't matter. The reason I have done this is because (as far as I know) a quadcopter can fly with only P and D, and with the way mine is behaving, I think a larger I-gain would only make things worse.

More detail about my PID: The PID corrects for the rotational velocity of the quad-copter, which, as I understand it, is the best way to control a quadcopter. The correction-rotation-rate is determined by multiplying the error (in degrees) by two. Why two? I dunno. I experimented with some other multipliers and two seems to be okay. Its also a prime number, so, yeah...

So anyways! **What do I need to do to make the quad-copter stable?** I have seen amazingly perfect quad-copters using the same arduino and the same MPU6050, but mine just tilts all over the place.

Some possible problems off the top of my head:

1. Bad algorithm for calculating the needed rotational velocity based on error.
2. Bad PID algorithm.
3. Bad PID gains.
4. I didn't balance my props, but seriously, would a couple of pieces of electrical tape stuck to the props really fix this? It doesn't seem like it would.

Thanks for any help you have to offer!

# Answer
To help solve this problem, I wrote a program in *Processing* that graphs all the data from the quadcopter, including roll rate, roll angle, thrust, etc... After doing so I realized that the problem was not in the PID, but in how I handled the data coming out of MPU6050. You can read all about it in this question I posted here before I had discovered the full solution.

The quadcopter is now capable of taking off, though sadly it is not very stable. This could be from bad PID gains, but I suspect it is from vibration in the roll-rate values from the MPU6050. The reason I think this is because I don't see steady oscillations, but rather random movement. Anyway, If I find a more complete solution I will update this answer.
> 1 votes

# Answer
For stability and tuning you need to make the adjustment cycle time compatible with the physical system. How fast does this adjustment code get called relative to how fast the physical system oscillates? Without that under control, tuning the gains will be difficult, particularly for krI and krD.

For instance, if you are updating every millisecond, and it takes a 1/10th of a second to physically flop over from -90 to 0 at the current roll\_thrust setting, there's only enough kP to adjust the roll\_thrust `kP*(RollDelta/2)*DT/dt=0.002*(90/2)*0.1/0.001=9` Is that a sane adjustment for a thrust/motorPower of 1200+? If you sample fast enough to make it capable of a full-throttle (+/-800?) adjustment with this particular kP, you might need to sample 88x faster (1ms/(800/9)=0.01125ms). From the other direction, I'd figure out how fast you can sample, then choose a krP that could get you a full-bias adjustment in reasonable time.

Maybe think of `adjust` as `roll_thrust` state variable measured in units of ESC\_microseconds, and krP is the conversion factor from whatever error you are measuring. Is it roll angle error? roll rate error? Absolute roll rate error? It looks like this bit:

```
float newRate = 2 * (newRoll - currentRoll); // How fast should the drone try to
if (newRoll - currentRoll < 0) {             // adjust, based on the error.
   newRate = 0 - newRate;
}

```

is essentially:

```
float newRate = 2 * abs(newRoll - currentRoll);

```

which might make control discontinuous. If currentRoll is a positional roll angle setpoint, it won't be able to tell if it is on one side or the other.

If you want a roll angle of -90deg to make full throttle one way and 90deg to full throttle the other, then krP should be on the order of 900us/90deg=10us/degree. And krI=krD=0 to start with.

I'd code up separate PIDs for `thrust`, `roll_thrust`, `pitch_thrust`, `yaw_thrust` control variables and then sum them together to get the `{NE,NW,SE,SW}Power` outputs. Then you could monitor and control in {thrust,roll\_angle,pitch\_angle,yaw\_rate} space and the coding will be more straightforward and interpretable.
> 1 votes

# Answer
To be sure the receiver gets the right signal from the emitter it is mandatory to scrutinize the signal on the receiver for a while. Once the signal on the receiver is checked good it is possible to go ahead step by step. The first step is to drive the 4 ESC/motors with the same signal coming from the throttle. Once the behavior of the 4 motors complies with changes on the throttle coming from the emitter it is time to go to the next step. The next step stems from a mix with pitch/roll/yaw coming from the emitter. The mix is added/removed to/from the throttle addressing each motor. The behavior of the 4 motors must show exactly the mix that comes from the emitter. An "acceptable" mix is something like (in the same unit, degres or microseconds):

Something like this:

```
int throttle_gaz;
int roll_length, pitch_length, yaw_length;

throttle_gaz=pulse_duration[throttle_chanel];
if ( abs(throttle_gaz-1500) <= 50 )
{
 throttle_gaz=1500;
}
roll_length=pulse_duration[roll_chanel]-1500;            //ROLL
if (abs (roll_length) <=100 )
{
roll_length=0;
}
roll_length/=3;

pitch_length=pulse_duration[pitch_chanel]-1500;           //PITCH
if (abs (pitch_length) <= 100 )
{
  pitch_length=0;
}
pitch_length/=3;

yaw_length=pulse_duration[yaw_chanel]-1500;             //YAW
if (abs (yaw_length) <=100 )
{
  yaw_length=0;
}
yaw_length/=3;

//add/soustract from THROTTLE (pulse_duration[throttle_chanel])
//change the sign (+ / -) acc
pulse_length_esc1=throttle_gaz + roll_length + pitch_length - yaw_length;
pulse_length_esc2=throttle_gaz - roll_length +  pitch_length +  yaw_length;
pulse_length_esc3=throttle_gaz + roll_length - pitch_length  + yaw_length;
pulse_length_esc4=throttle_gaz - roll_length -  pitch_length  -  yaw_length;

```
> 0 votes

---
Tags: mpu6050, pid, drone
---


# Question
Title: How can I prepare for a short circuit between 5V and GND pins?
My Arduino Uno controls a couple of LEDs in a watertight enclosure. I'm running wires from ground, a data pin, and the 5 V pin into the enclosure. The Arduino is powered through the DC jack.

What measures can I take to handle failure of the watertight enclosure, which would short-circuit the wires? Can I protect the Arduino, or at least prevent a fire?

# Answer
Shoutout to @k.Cyborg who gave a very nice pointer in the comments to a YouTube video on the effects of water on electronics!

One of the things you can do to handle failure of the watertight enclosure better is to use nail polish clear coat and apply that over your board - it will form a protective layer. I use this technique on protoboards with solder bridges on the bottom - adding a layer of clear coat seals them and prevents any shorts due to placing the bottom of the board on a conductive surface, or from fingers touching and shorting things. This would work with water too, to prevent any electrolytic reaction and corrosion, which the video talks about. The video also briefly shows a nail polish clear coat (but doesn't elaborate and says it's a topic for another video).

Another point to consider when talking about shorts. In my case, I was powering my Arduino Pro Mini through the Vin , connected to a 9v battery. I fried the LDO on it by briefly reversing the polarity by switching the terminals by mistake (nice puff of magic smoke!). I added a reverse polarity protection diode in series with the + to prevent a repeat on my next Pro Mini. Since you are powering your Uno through the DC jack (which has a reverse polarity protection diode), it is not an issue for you, but thought I'd mention it if you plan to move to Vin.
> 0 votes

---
Tags: safety, fuses
---


# Question
Title: Problem with displaying true RMS of the main voltage using Arduino Uno and MAX7219
I want to display the true RMS of the main voltage using an Arduino and a MAX7219. At first, I used of circuit #1 (the following circuit) and the True RMS library. The circuit could successfully return the true RMS and print it on the Serial Monitor of thr Arduino every 0.5 s. The accuracy was acceptable. This circuit was supplied from a PC.

At the next step, I decided to use a MAX7219 (LedControl library) to display the true RMS voltage on a 7-segment display. For this, I used of circuit #2. I don't know what happened. The displayed voltage had variations. In circuit #1, the maximum error was 1 volt (checked by a true-RMS multimeter - for example, the voltage was 210 V and the printed voltage was 209 or 211 V). But in circuit #2, the error was up to 10 V with a fast variation. For example, the voltage was about 210 V (using multimeter) for a minute, but the displayed voltage by the Arduino was 203, then 209, then 217, then 205, then 200, then 215, ....

I also used another true-RMS multimeter to check the first multimeter. The voltage was the same value as the first one showed. The problem was that the voltage remained approximately constant, but the Arduino showed a variable voltage. I checked the supplied voltage from the PC. It doesn't have effective changes.

I also used of circuit #3, but I still had the same problem. It seems that the used of MAX7219 is causing the problem. What is the solution?

My code (for bi-color common anode 7-segment - I have 3 digits):

```
#include <TrueRMS.h>
#include <digitalWriteFast.h> // It uses digitalWriteFast only for the purpose of debugging!
                              // https://code.google.com/archive/p/digitalwritefast/downloads

#define LPERIOD 1000    // 1000 loop period time in us. In this case 1.0ms
#define ADC_INPUT 0     // define the used ADC input channel
#define RMS_WINDOW 40   // rms window of 40 samples, means 2 periods @50Hz
// #define RMS_WINDOW 50   // rms window of 50 samples, means 3 periods @60Hz

#define PIN_DEBUG 4

unsigned long nextLoop;
int adcVal;
int cnt = 0;
float VoltRange = 5.00; // The full scale value is set to 5.00 Volts but can be changed when using an
                        // input scaling circuit in front of the ADC.
Rms readRms; // create an instance of Rms.

// Max7219 ===============================================================
#include "LedControl.h"
int ClockPin = 5;
int CsPin = 6;
int DinPin = 7;
LedControl lc = LedControl(DinPin, ClockPin, CsPin, 1);
// 1 as we are only using 1 MAX7219

void setup() {
  Serial.begin(115200);
  pinMode(PIN_DEBUG, OUTPUT);

  // configure for automatic base-line restoration and continuous scan mode:
  readRms.begin(VoltRange, RMS_WINDOW, ADC_10BIT, BLR_ON, CNT_SCAN);
  //readRms.begin(VoltRange, RMS_WINDOW, ADC_10BIT, BLR_OFF, CNT_SCAN);
  // configure for no baseline restauration and single scan mode:
  //readRms.begin(VoltRange, RMS_WINDOW, ADC_10BIT, BLR_OFF, SGL_SCAN);
    readRms.start(); //start measuring
    nextLoop = micros() + LPERIOD; // Set the loop timer variable for the next loop interval.

  // Max7219
  // the zero refers to the MAX7219 number, it is zero for 1 chip
    lc.shutdown(0, false); // turn off power saving, enables display
    lc.setIntensity(0, 15); // 15 sets brightness (0~15 possible values)
    lc.clearDisplay(0); // clear screen
  }

// Max7219
byte board[1][8] = {
  {
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000
  }
};

//  Max7219             Device
void ClearDisplay(int b, int digit) {
  for (int i=0; i<8; i++) { // It clears all segments of Digit "digit" of Device "n"
    bitClear(board[b][i], 7-digit);
  }
}

void Display() {
  for (int i=0; i<9; i++){
     lc.setRow(0, i, board[0][i]);
  }
}

//         Device  Digit      Num       Dot
void SetNum(int b, int digit, int num, int dot) {
switch(num) {
  case -2: // displays  "-"
    bitClear(board[b][0], 7-digit); // seg-A
    bitClear(board[b][1], 7-digit); // seg-B
    bitClear(board[b][2], 7-digit); // seg-C
    bitClear(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitClear(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
  case -1: // it clears the display
    bitClear(board[b][0], 7-digit); // seg-A
    bitClear(board[b][1], 7-digit); // seg-B
    bitClear(board[b][2], 7-digit); // seg-C
    bitClear(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitClear(board[b][5], 7-digit); // seg-F
    bitClear(board[b][6], 7-digit); // seg-G
    break;
  case 0:
    bitSet(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitSet(board[b][3], 7-digit); // seg-D
    bitSet(board[b][4], 7-digit); // seg-E
    bitSet(board[b][5], 7-digit); // seg-F
    bitClear(board[b][6], 7-digit); // seg-G
    break;
  case 1:
    bitClear(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitClear(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitClear(board[b][5], 7-digit); // seg-F
    bitClear(board[b][6], 7-digit); // seg-G
    break;
  case 2:
    bitSet(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitClear(board[b][2], 7-digit); // seg-C
    bitSet(board[b][3], 7-digit); // seg-D
    bitSet(board[b][4], 7-digit); // seg-E
    bitClear(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
  case 3:
    bitSet(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitSet(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitClear(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
  case 4:
    bitClear(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitClear(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitSet(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
  case 5:
    bitSet(board[b][0], 7-digit); // seg-A
    bitClear(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitSet(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitSet(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
  case 6:
    bitSet(board[b][0], 7-digit); // seg-A
    bitClear(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitSet(board[b][3], 7-digit); // seg-D
    bitSet(board[b][4], 7-digit); // seg-E
    bitSet(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
  case 7:
    bitSet(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitClear(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitClear(board[b][5], 7-digit); // seg-F
    bitClear(board[b][6], 7-digit); // seg-G
    break;
  case 8:
    bitSet(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitSet(board[b][3], 7-digit); // seg-D
    bitSet(board[b][4], 7-digit); // seg-E
    bitSet(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
  case 9:
    bitSet(board[b][0], 7-digit); // seg-A
    bitSet(board[b][1], 7-digit); // seg-B
    bitSet(board[b][2], 7-digit); // seg-C
    bitSet(board[b][3], 7-digit); // seg-D
    bitClear(board[b][4], 7-digit); // seg-E
    bitSet(board[b][5], 7-digit); // seg-F
    bitSet(board[b][6], 7-digit); // seg-G
    break;
    default:
    break;
  }
  if (dot == 1) {
    bitSet(board[b][7], 7-digit); // seg-dp
  }
}

//                          0-1-2-3
//                  Device  Digit      Num       Dot      Color
void SetNumWithColor(int b, int digit, int num,  int dot, char color) {
  switch(color) {
    case 'r': // digits 0,1,2,3 are Red
      SetNum(b, digit, num, dot);
      SetNum(b, 4, -1, dot); // clears all Green segments
      SetNum(b, 5, -1, dot); // clears all Green segments
      SetNum(b, 6, -1, dot); // clears all Green segments
      SetNum(b, 7, -1, dot); // clears all Green segments
      break;
    case 'g': // digits 4,5,6,7 are Green
      SetNum(b, digit+4, num, dot);
      SetNum(b, 0, -1, dot); // clears all Red segments
      SetNum(b, 1, -1, dot); // clears all Red segments
      SetNum(b, 2, -1, dot); // clears all Red segments
      SetNum(b, 3, -1, dot); // clears all Red segments
      break;
    case 'o':
      SetNum(b, digit, num, dot); // Turns Red on
      SetNum(b, digit+4, num, dot); // Turns Green on
      break;
    default:
      break;
  }
  Display();
}

void loop() {
  adcVal = analogRead(ADC_INPUT); // read the ADC.
  // readRms.update(adcVal); // update
  digitalWriteFast(PIN_DEBUG, HIGH);
  readRms.update(adcVal); // for BLR_ON or for DC(+AC) signals with BLR_OFF
  // readRms.update(adcVal-512); // without automatic baseline restoration (BLR_OFF); substract a fixed DC offset in ADC-units here.
  digitalWriteFast(PIN_DEBUG, LOW);

  cnt++;
  if (cnt >= 1500) { // 500 = publish every 0.5s
    readRms.publish();
    float RMS=readRms.rmsVal;
    float AccRMS=RMS*128;
    int RMSout=AccRMS;
    Serial.print("Vrms=");
    Serial.print(RMSout);
    int a1=RMSout/100;
    int b1=RMSout%100;
    int a2=b1/10;
    int a3=b1%10;
    if (RMSout<200) { // Red
      SetNumWithColor(0, 0, a1,  0, 'r'); // displays a1 at digit 0
      SetNumWithColor(0, 1, a2,  0, 'r'); // displays a2 at digit 1
      SetNumWithColor(0, 2, a3,  0, 'r'); // displays a3 at digit 2
    }else if(RMSout<215){ // Orange
      SetNumWithColor(0, 0, a1,  0, 'o'); // displays a1 at digit 0
      SetNumWithColor(0, 1, a2,  0, 'o'); // displays a2 at digit 1
      SetNumWithColor(0, 2, a3,  0, 'o'); // displays a3 at digit 2
    }else{ // Green
      SetNumWithColor(0, 0, a1,  0, 'g'); // displays 1 at digit 0
      SetNumWithColor(0, 1, a2,  0, 'g'); // displays 2 at digit 1
      SetNumWithColor(0, 2, a3,  0, 'g'); // displays 3 at digit 2
    }
    Serial.print(", Vin=");
    Serial.println(RMS,4);
    // float dc=readRms.dcBias;
    // Serial.println(dc,4);
    cnt=0;
    // readRms.start();  // Restart the acquisition after publishing if the mode is single scan.

  }

  while (nextLoop > micros());  // wait until the end of the loop time interval
  nextLoop += LPERIOD;  // set next loop time to current time + LOOP_PERIOD

}

// end of Measure_rms.ino

```

# Answer
Without seeing your code it's hard to guess completely, but this is my supposition:

* The RMS measurement has to measure rapidly over a short period to capture the peak values of the AC waveform
* You are updating the display while doing the measurement
* The display updates slow down the sampling of the AC waveform giving you incorrect values.

You need to make sure that the sampling of the AC waveform happens fast enough by not doing anything else (much) during the sampling period and only displaying anything on the display when all the sampling for the current data point is done.
> 0 votes

---
Tags: arduino-uno, voltage, max7219
---


title: Trigger event onRelease of button

text:
# Question
Title: Trigger event onRelease of button
I am using the EasyButton library to detect button presses on an arduino.

I want do execute a function when the user

1. Presses a button
2. Presses and holds a button
3. Releases a button

Detecting when a user presses or holds a button is straight forward

```
#include <Arduino.h>
#include <EasyButton.h>
# define BUTTON_PIN 2;
EasyButton button(BUTTON_PIN);

void onPressedCallback() {
  Serial.println("Button was pressed and released");
}

void onHoldCallback() {
  Serial.println("Button was pressed and held");
}

void setup() {
  button.begin();
  button.onPressed(onPressedCallback);
  button.onPressedFor(buttonHoldDuration, onHoldCallback);
}

```

The easyButton library has the following events

* onPressed
* onPressedFor
* onSequence

It has the following states

* isPressed
* isReleased
* wasPressed
* wasReleased
* pressedFor
* releasedFor

**How would you trigger an event when a button is 'released'?**

Full Documentation

https://easybtn.earias.me/docs/on-single-press-api

## What I've tried

1. Check the state from inside an event

```
void onHoldCallback() {
  while (button.isPressed() {
     Serial.println("you are still holding the button");
  }
  Serial.println("Button was released");
}

```

This unfortunately creates an infinite loop since the button state is never refreshed (button.begin();)

### Additional Resources

# Answer
> 1 votes
The `onPressed()` event Triggers a callback function when the button has been pressed and released.

Here's a test sketch to show what I mean. I've also added a function you could use to detect the moment the button is first pressed.

```
#include <EasyButton.h>

// EasyButton(uint8_t pin,
//            uint32_t debounce_time = 35,
//            bool pullup_enable = true,
//            bool active_low = true)
EasyButton button(2);

void onReleased(){
  Serial.println("Button Releast");
}

void firstPressed(){
  Serial.println("First Pressed");
}

void setup(){

  // Test output to serial monitor.
  Serial.begin(9600);

  // Initialize the button.
  button.begin();

  // Add the callback function to be called
  // when the button is pressed then released.
  // NOTE: This function is only called AFTER
  // the button has been released.
  button.onPressed(onReleased);

}

void loop(){

  // Continuously read the status of the button.
  button.read();

  // Call a function the moment the button is pressed.
  if(button.wasPressed()){
    firstPressed();
  }

}

```

# Answer
> 0 votes
Just check the easyButton state in your loop code and run your functions as required. The library already has the events you need, no point rolling your own. It's best just to set a variable or flag in event code so it returns quickly, then deal with the results in the main loop. The easyButton library has done most of that work for you.

# Answer
> -1 votes
Origionally I started with the EasyButton library, but when I wasn't able to get it working I switched to the `madleech/Button@^1.0.0` library and got the following working.

Note that this depends on polling which could definitly be improved.

While this deviates from the original question, I feel it is worth sharing for anyone else who wants a working but (less than ideal) solution.

```
#include <Arduino.h>

#include <Button.h>

Button button1(2);

unsigned long buttonCheckMillis;

void setup()
{
  buttonCheckMillis = millis();
  button1.begin();
}

void loop()
{
  if (button1.toggled()) {
    // User pressed the button
    if (button1.read() == Button::PRESSED) {
      Serial.println("Button Pressed");
    }
    // User released the button
    else {
      Serial.println("Button Released");
    }
  }
  // Poll every 100 milliseconds to see if user is still holding button
  if (millis() - buttonCheckMillis > 100) {
    buttonCheckMillis = millis();
    if (button1.read() == Button::PRESSED) {
      Serial.println("Button Held");
    }
  }

}

```

---
Tags: button, callbacks
---


# Question
Title: Using Visual Studio Code to program an Arduino
I had recently got an Arduino Uno and did quite a few programs on it. Now, I had always used Visual Studio Code to do my C projects. So, is it possible to use Visual Studio Code to program an Arduino, but without the Arduino plugin available in Visual Studio Code?

This might sound a bit weird, but I wanted to learn how to build those type of plugins from scratch. Are there some resources from where I could learn to do that? I searched through Google, but I couldn't find any answers.

# Answer
> 2 votes
This might not be the answer you are looking for, but maybe it helps you and others. Besides, it's too long to write as a comment.

1. Use VS Code only as editor

Make sure that your .ino file is as small as possible, typically, just enough to call a second file (.cpp or .c file). The idea is that you do not need to change the .ino file often as you need to load the .ino file only in your Arduino IDE. All other files (including the .ino) you load in VS Code.

Than you edit your files in VS Code as asual, but you compile/upload the file with the default Arduino IDE. The Arduino IDE doesn't see files being saved as new, so that's why you need not to change the .ino file often, as you need to synchronize it manually.
2. MS Visual Studio

I'm using MS Visual Studio, comparable to VS Code and written stubs or even emulations for certain Arduino classes (like Arduino, but also for other libraries I use on the Arduino, which mimic or at least print something when called).

This way I can fully compile an Arduino project, and most important, run it so I can check the business logic and some parts of the hardware logic on a normal PC having a decent debugger etc. When working, I can use the first solution to upload it to an Arduino.

Writing these stubs is quite some work and the simulation can depend on the project (like for a LED strip project I actually visualized the LEDs on a PC).
3. In both above cases, I use the Arduino IDE only for compiling and uploading, not for editing. It would be also useful to skip using this Arduino IDE completely by using a command line to compile/upload using the CLI version of Arduino (see comment of theBusyBee below. In at least Microsoft Visual Studio but probably Visual Studio Code external commands can be added calling this Arduino IDE for compiling/uploading.
4. PMF's comment below: You can use VisualMicro on top of Microsoft Visual Studio; this is a paid extension.

# Answer
> 5 votes
If you really looking for an alternate for Arduino IDE. Than I will recommends you to go with platformio. It has great library management.

Just install the platformio extensions on the vs code and you are ready to go.

# Answer
> 2 votes
You can write C++ file with the editor of your choice, include `avr/io.h` to manage Arduino I/O, and then compile with avr-gcc and upload with avrdude. This is what I do because I don't like working with the .ino sketch directory structure that hides away normal C++ code that you would use with any other microcontroller. (See What is the relationship of an Arduino .ino file to main.cpp?, Why does an \`.ino\` file have to be in a folder of the same name?)

Guide: https://create.arduino.cc/projecthub/milanistef/introduction-to-bare-metal-programming-in-arduino-uno-f3e2b4

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


# Question
Title: How to connect Draw wire encoder to Arduino Uno?
Hello Stack Community,

I am new to Arduino, and I am trying to figure out how to connect a draw wire encoder to Arduino and collect data from it.

I have attached a link of the product that I currently have, which also has datasheet, incase anyone needs more information.

https://www.kuebler.com/en/products/measurement/linear-measuring-systems/product-finder/product-details/A30

I know that the encoder's output is through analog, but I am having trouble with connections as well.

To summarize, how can I connect the encoder to Arduino Uno?

Lastly, I am using the encoder to measure linear distance of linear actuators.

# Answer
> 0 votes
The simplest way is to use the version with potentiometer output:

simulate this circuit – Schematic created using CircuitLab

Connect the wiper to an analog input (A0 in the example), and use the analog reference voltage as "supply" voltage.

---
Tags: arduino-uno, potentiometer, analog
---