# Question
Title: How to document a custom library in Arduino
I have created my own library and it is working flawlessly. Now I want to add some documentation to it that the Arduino IDE can understand.

For the functions from the Arduino IDE itself like `delay(ms)` you can right click them and then select `Find in Reference`. How can I add this feature to my own library?

# Answer
> 1 votes
OK, time for my most comprehensive answer on StackExchange so far (tanks to @Juraj for helping out with this).

To demonstrate all the steps needed for this, this answer will use an example library that will be called `Foo`.

Here we go:

To add documentation to your library that the Arduino IDE can work with, you first need to place your library in the correct directory. Thats either in your `library` folder in your `sketchbook` folder (you can locate it by selecting `File>Preferences>Sketchbook location`, by default this is

```
C:\Users\YourUsername\Documents\Arduino\libraries

```

or

```
InstallationDirectoryOfYourIDE\portable\sketchbook\libraries

```

if you are using a portable installation) or in

```
InstallationDirectoryOfYourIDE\libraries

```

In which of the two places you put your library is up to you, both work (except if you put in both places at the same time). You should keep this in mind though: If you put your library in the `libraries` folder of your sketchbook, only you will have access to that library. If there are other users on the same PC that shall be able to use your library, you have to put in in the general libraries folder (if you don't have access to that folder because it belongs to another user and you are not the admin, then too bad, sorry ;).

Your library has to contain at least a file `Foo.h` which can be located directly in the folder of your library (old standard) or in a subfolder `src` in your library folder (up to date standard). What the file contains is for the sake of this example absolutely arbitrary (e.g. just leave it empty).

Next you need a valid `library.properties` file for your library. You can create and edit it with any text editor like notepad. This file has to be placed directly into the folder of the library.

Here is a bare minimum example for this file that works:

> name=Foo
> version=1.0.0
> author=Your name
> maintainer=Your name
> sentence=Something
> paragraph=Whatever
> url=http://example.com

More information on how this file works (and other things to consider when creating a library) can be found at the Arduino Library Specification.

Now we can specify which words the IDE shall highlight and which of them shall link to which reference page (to make sure that this works in principle it is not necessary to create your own `.html` files yet). To do this, create a file `keywords.txt` in the folder of your library. In it you write something like this:

```
foo KEYWORD2    Foo

```

In this example `foo` is the keyword that will be highlighted in the IDE (and on right click present the option `Find in Reference`). `KEYWORD2` specifies how exactly `foo` will be highlighted (colour, boldness, etc.), in this case it will appear like normal text in orange (once again, see the Arduino Library Specification for more details on this). `Foo` is the name of the `.html` file (without the extension) that is opened when you right click `foo` in the IDE and select `Find in Reference`. It has to be located in this folder:

```
InstallationDirectoryOfYourIDE\reference\www.arduino.cc\en\Reference

```

The three words are separated by true `tab`s (not multiple `space` characters). Before creating your own `.html` file you can just copy one of the files there and rename it to `Foo`. Note that your library doesn't have to contain anything else besides the three mentioned files and some file in the reference folder for this to work. At this point you should restart your IDE and check whether your keyword `foo` is highlighted and offers the option `Find in Reference` when you right click it. If so, success! You can now move on to create your own `.html` file to put in the reference folder.

You could start by just changing one of the existent files to fit the style of the Arduino API, but you could also create your entirely own files. The probably best option however is to write your library according to doxygen standards and then let doxygen do the work for you creating the file automatically.

Just one more thing to be mentioned: This method works for any keywords that are used in the way `yourKeyword` or `something.yourKeyword`, but not `Something::yourKeyword` (this is how you would use a static function or variable in your library). According to @Juraj this is something caused by the IDE. There is a workaround for this though: Replace each line in the `keywords.txt` file

```
yourKeyword KEYWORDX    ReferenceFile

```

with

```
yourKeyword KEYWORDX    ReferenceFile
YourLibrary::yourKeyword    KEYWORDX    ReferenceFile

```

This way `yourKeyword` will be highlighted as you would expect it but occurrences like `YourLibrary::yourKeyword` will also bring up the option `Find in Reference` when right clicked.

That's it for today. Thanks and bye bye!

# Answer
> 2 votes
Arduino uses the keyword.txt file to highlight words and to define a reference page to keywords. But the reference page must be in `reference` folder of IDE installation and the keyword.txt contains only a filename, not the path.

> REFERENCE\_LINK This field specifies the Arduino Language Reference page to open via Right Click \> Find in Reference or Help \> Find in Reference when the cursor is on that keyword. Generally it does not make sense to define the REFERENCE\_LINK field for 3rd party library keywords since they are not likely to be in the Arduino Language Reference.

I have a library which implements WiFiClient and WiFiServer like the Arduino WiFi library, so I can link in keywords.txt to Arduino reference like this:

```
WiFiClient  KEYWORD2    WiFiClient
WiFiServer  KEYWORD2    WiFiServer
WiFiUDP     KEYWORD2    WiFiUDPConstructor

```

The names used are names of html files in `Arduino\reference\www.arduino.cc\en\Reference`.

---
Tags: library, documentation
---


# Question
Title: Can I connect more than one IR receiver to an Arduino Uno?
I want to use `#include <IRremote.h>` to receive information from an infrared remote control. It works perfectly with one IR receiver.

But I want to put three or four IR receivers:

```
IRrecv irrecv6(pin6);
IRrecv irrecv7(pin7);
IRrecv irrecv8(pin8);
IRrecv irrecv9(pin9);
IRrecv irrecv10(pin10);

```

And:

```
void setup() {
  Serial.begin(9600);
  irrecv6.enableIRIn(); // Start the receiver
  irrecv7.enableIRIn(); // Start the receiver
  irrecv8.enableIRIn(); // Start the receiver
  irrecv9.enableIRIn(); // Start the receiver
  irrecv10.enableIRIn(); // Start the receiver
}

```

Inside the loop function, I am checking each pin to see if there is any data received. But only the last pin (which means pin 10 above) is receiving the data and others are not.

# Answer
That library only supports one IR receiver at a time. Try this fork that seems to have added multiple receivers support.
> 3 votes

# Answer
Just add some delay between irrecv.decode()s and everything will work just fine.
> 0 votes

---
Tags: arduino-uno, ir
---


# Question
Title: It gives some glitching on 7 segment display
It gives the right value on the monitor but it doesnt display the value on my display.

```
int pinNumb[7] = {2, 3, 4, 5, 6, 7, 8};
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }  //nothing
};

int pin = 2;
int button = 12;
int buttonVal;
int randVal;
bool pressVal;
void setup() {
  Serial.begin(9600);

  for (int i = 0; i < 7 ; i++)
  {
    pinMode(pinNumb[i], OUTPUT);
  }
  pressVal = false;
  pinMode(button, INPUT);
}

void loop() {
  buttonVal = digitalRead(button);
  if (buttonVal == 0)
  {
    //zero();
    turnOff();
    pressVal = false;
  }
  else
  {
    //zero();
    if (pressVal == false)
    {
      randVal = rand() % 10;
      pressVal = true;
      delay(100);
    }
    Serial.println(randVal);
    if (randVal == 0)
    {
      zero();

    }
    else if (randVal == 1)
    {
      one();

    }
    else if (randVal == 2)
    {
      two();

    }
    else if (randVal == 3)
    {
      three();

    }
    else if (randVal == 4)
    {
      four();

    }
    else if (randVal == 5)
    {
      five();

    }
    else if (randVal == 6)
    {
      six();

    }
    else if (randVal == 7)
    {
      seven();

    }
    else if (randVal == 8)
    {
      eight();

    }
    else
    {
      nine();

    }
  }
}

void zero()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[0][j]);
    pin++;
  }
}

void one()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[1][j]);
    pin++;
  }
}

void two()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[2][j]);
    pin++;
  }
}
void three()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[3][j]);
    pin++;
  }
}
void four()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[4][j]);
    pin++;
  }
}
void five()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[5][j]);
    pin++;
  }
}
void six()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[6][j]);
    pin++;
  }
}
void seven()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[7][j]);
    pin++;
  }
}
void eight()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[8][j]);
    pin++;
  }
}
void nine()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[9][j]);
    pin++;
  }
}
void turnOff()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }

}

```

# Answer
> 0 votes
You are continually incrementing the pin variable via pin++, but you are never resetting it to the start (2?) when a new number is to be written. So it might work the first time but never after that.

Also, you clear the display with digitalWrite(pinNumb\[i\],LOW); But you turn segments on with digitalWRite(pin,....); pin++. Shouldn't you turn the segments on with digitalWrite(pinNumb\[i\] . . ?

# Answer
> 0 votes
These can all be byte instead of int to save on memory:

```
int pinNumb[7] = {2, 3, 4, 5, 6, 7, 8};
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }  //nothing
};

int pin = 2;
int button = 12;
int buttonVal;
int randVal;

```

In addition, the array can be reduced to 11 bytes:

```
0bFD, // 0
0bC0, // 1
0bDE, // 2
etc.

```

Then your functions can do direct port manipulation to send bits 0-5 to the Port for D2 to D7, and bit to D8.

As written, these functions probably need some hold time so they don't just flash the LED and disappear:

```
void one()
{
  for(int i = 0; i < 7 ; i++)
  {
    digitalWrite(pinNumb[i],LOW);
  }
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin, num_array[1][j]);
    pin++;
  }
}

```

---
Tags: arduino-uno
---


# Question
Title: Any advice you can give me on my step motor code?
I'm very new to Arduino, currently undertaking a uni project in which my team wish to create a sort of slot machine-esque device that uses a step motor to rotate a drum (like one of the cylinders in a slot machine).

What I've currently tried to do is merge some code that uses a counter variable and button to enable a servo to rotate round multiple times with a single button, with code I found that i think is used to test a step motor? In my mind the code I have should allow me to rotate my stepper by 45 degrees after each button press, but I have no idea if my code makes any sense. Could you guys tell me if im close or is it a load of rubbish. if it does work ok, id look to set the speed higher and have the motor perform multiple full rotations before each stop, to make it work more like an actual slot machine spinner. any advice you could offer would be great, apologies in advance if i don't quite understand certain things you may explain as I am new to coding, as I mentioned.

Here's the code:

```
#include <Stepper.h>

//variables
int counter = 0;
const int buttonPin = 8;
const int stepsPerRevolution = 90;

Stepper myStepper(stepsPerRevolution,1,2,3,4);

void setup() {

 pinMode(buttonPin, INPUT);
 myStepper.setSpeed(60);

}

void loop() {

  int buttonState;

  buttonState = digitalRead(buttonPin);

   if (buttonState == LOW)
  {
    counter++;

 delay(150);
  }

if(counter == 0)
   myStepper.step(0);

 else if(counter == 1)
   myStepper.step(45);

 else if(counter == 2)
  myStepper.step(90);

 else if(counter == 3)
    myStepper.step(135);

else if(counter == 4)
   myStepper.step(180);

 else if(counter == 5)
  myStepper.step(225);

else if(counter == 6)
    myStepper.step(270);

else if(counter == 7)
  myStepper.step(315);

else if(counter == 8)
    myStepper.step(360);

  else
   counter = 0;

}

```

# Answer
The event of a button press is not deterministic in your case. Generally, your delay()-approach combined with reading the current button state is not how sth. like this works. Instead, you have to detect when a button is **pressed/released**. One way to do that is the following:

```
#define buttonPin 8
bool last_state=false;

void loop(){
  if(!digitalRead(buttonPin)) {
    if(last_state) {
      //button has been released
      //increment your counter here
    }
    last_state=false;
  } else {
    last_state=true;
  }
}

```
> 0 votes

# Answer
First understand that myStepper.step(x) method is relative steps not absolute. So if you want the motor to do two rotations of 45 steps back to back you should write

```
myStepper.step(45);
myStepper.step(45);    /// NOT myStepper.step(90)  <-- that's 90 MORE steps

```

Second, it looks like your code will increase steps taken by 45 while HOLDING the button down but should also rotate the motor 45 steps for each button press as long as the subsequent presses do not occur while the motor is in mid rotation.

Furthermore, your can delete the following extra else if statements and it should still work.

```
else if(counter == 2)
  myStepper.step(90);

 else if(counter == 3)
    myStepper.step(135);

else if(counter == 4)
   myStepper.step(180);

 else if(counter == 5)
  myStepper.step(225);

else if(counter == 6)
    myStepper.step(270);

else if(counter == 7)
  myStepper.step(315);

else if(counter == 8)
    myStepper.step(360);

```
> 0 votes

---
Tags: arduino-mega, stepper, stepper-motor
---


# Question
Title: Is there a way to read real-time port selection on Arduino IDE when using third-party toolchain and uploading program?
I am using a third-party program to build the binary file and upload it under Arduino IDE's GUI, meaning I am not using the built-in avr-gcc nor avrdude for building and uploading. As there is a on-board DAP chip, uploading binary file is done by copy&paste the binary file into the flash memory recognized as a removable storage by the OS.

However, this make reading user's current port selection very difficult because the IDE is written in Java, but the thrid-party program I am using is in C++.

Knowing which port the user has currently selected is very important to me, as sometimes I need to program multiple boards at the same time and monitor their received data on the serial port.

If someone can point me into the right direction or link me to the previously-solved similar question , it will be much appreciated!

PS: I am working under Ubuntu&Windows10 OS and using latest Arduino IDE.

# Answer
After someone from Github gave me a link, I think I ve found the way to read the real-time port selection even using third party uploading program.

The key is command line argument in the "Platform.txt" file located under "arduino15" folder. If you have the same issue as mine, try look up this link, where you will find loads of useful information: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification

PS: rmb, after you change the command lines in the txt file, always close and restart your arduino IDE before those changes you made take effect.
> 1 votes

---
Tags: ide
---


# Question
Title: number generator show wrong segments on 7 segment display
I created a program to show a random number on a 7 segment display. It shows a random number in the serial monitor but always shows the same segments 'a c d and g'. anyone know hopw to fix this without changing the base of the coding its for and exercise so i need to have most of the code like I wrote it.

```
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }
};  //OFF

int buttonState = 0;
const int button = 12;
int randVal;
bool pressVal;
void num_Write(int);
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(button, INPUT);
}

void loop() {
  buttonState = digitalRead(button);
  if (buttonState == LOW) {
    turnOff();
    pressVal = false;

  }
  else
  {
    if (pressVal == false)
    {
      int pin = 2;
      for (int i = 0; i < 7 ; i++)
      {
        digitalWrite(pin++, num_array[11][i]);
      }
      randVal = rand() % 10;
      pressVal = true;
    }
    Serial.println(randVal);
    if (randVal == 0)
    {
      void zero();

    }
    else if (randVal == 1)
    {
      void one();

    }
    else if (randVal == 2)
    {
      void two();

    }
    else if (randVal == 3)
    {
      void three();

    }
    else if (randVal == 4)
    {
      void four();

    }
    else if (randVal == 5)
    {
      void five();

    }
    else if (randVal == 6)
    {
      void six();

    }
    else if (randVal == 7)
    {
      void seven();

    }
    else if (randVal == 8)
    {
      void eight();

    }
    else
    {
      void nine();

    }
  }
}

void zero()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[0][j]);

  }
  delay(250);
}

void one()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[1][j]);

  }
  delay(250);
}

void two()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[2][j]);

  }
  delay(250);
}
void three()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[3][j]);
  }
  delay(250);
}
void four()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[4][j]);

  }
  delay(250);
}
void five()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[5][j]);

  }
  delay(250);
}
void six()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[6][j]);

  }
  delay(250);
}
void seven()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[7][j]);

  }
  delay(250);
}
void eight()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[8][j]);

  }
  delay(250);
}
void nine()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[9][j]);

  }
  delay(250);
}
void turnOff()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[10][j]);
  }
  delay(250);
}

```

# Answer
Note, this is not an answer to your question, but I like to show some programming improvements, making your sketch much shorter and easier to maintain.

Instead of having all functions `one`, `two`, etcetera, use a parameter to pass the number. So you get this: (I couldn't test it as I don't have an Arduino IDE at hand). Also you can use a `for` loop in the `loop` function to set the output pins.

```
int num_array[11][7] = {
  { 1, 1, 1, 1, 1, 0, 1 }, // 0
  { 0, 1, 1, 0, 0, 0, 0 }, // 1
  { 1, 1, 0, 1, 1, 1, 0 }, // 2
  { 1, 1, 1, 1, 0, 1, 0 }, // 3
  { 0, 1, 1, 0, 0, 1, 1 }, // 4
  { 1, 0, 1, 1, 0, 1, 1 }, // 5
  { 1, 0, 1, 1, 1, 1, 1 }, // 6
  { 1, 1, 1, 0, 0, 0, 0 }, // 7
  { 1, 1, 1, 1, 1, 1, 1 }, // 8
  { 1, 1, 1, 0, 0, 1, 1 }, // 9
  { 0, 0, 0, 0, 0, 0, 0 }
};  //OFF

int buttonState = 0;
const int button = 12;
int randVal;
bool pressVal;

void num_Write(int);
void digit(int value);

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

  for (int pin = 2; pin <= 8; pin++)
  {
    pinMode(pin, OUTPUT);
  }

  pinMode(button, INPUT);
}

void loop() {
  buttonState = digitalRead(button);
  if (buttonState == LOW) {
    turnOff();
    pressVal = false;

  }
  else
  {
    if (pressVal == false)
    {
      int pin = 2;
      for (int i = 0; i < 7 ; i++)
      {
        digitalWrite(pin++, num_array[11][i]);
      }
      randVal = rand() % 10;
      pressVal = true;
    }
    Serial.println(randVal);
    if ((randVal >= 0) && (randVal <= 9))
    {
      digit(randVal);
    }
  }
}

void digit(int value)
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[value][j]);
  }
  delay(250);
}

void turnOff()
{
  int pin = 2;
  for (int j = 0; j < 7; j++) {
    digitalWrite(pin++, num_array[10][j]);
  }
  delay(250);
}

```

You can also remove `turnOff` if you treat it like digit 10 but that is not so clear (or put the implementation of `digit` to another function and call it from `digit` and `turnoff`.

To solve your problem, print the values of each pin to the serial monitor. If they are correct, there is a problem in your circuit. If they are incorrect, there is a problem in your sketch. In the latter case, add more print statements until you found the exact problem.

**Update**

* Fixed void forward declaration to function call (see comment of chrisl)

If the `digit` function is never called, it means:

1. `((randVal >= 0) && (randVal <= 9))` is false, however, that is not possible since it is initialized to 0 and with the rand function it gets always values between 0 to 9.
2. pressVal is always TRUE.

So check the value of pressVal, also add (lots of) `print` statements, especiallya after each `if` and `else` so you know exactly the flow of your sketch. You will see it's very easy to find the error. If you pinpoint the problem to a `digitalRead` that is not the expected value, THAN there is high likely a problem with your circuit (a button that is never going to be LOW or HIGH). In that case, you probably forgot a pullup/pulldown resistor.
> 0 votes

---
Tags: arduino-uno, 7-segment
---


# Question
Title: ATmega328P - Problem using timer 2 for tone generation
I'm simply trying to use timer 2 for tone generation and what I get is a very faint and strange tone (almost like its modulated somehow as there is a "pulsing" to it). Here's my simple code:

```
#include <Arduino.h>

#define SPEAKER_PORT PORTC
#define SPEAKER_BIT 2

void setup()
{
  pinMode(A2, OUTPUT);

  TCCR2A = _BV(WGM21);  // CTC mode
  TCCR2B = _BV(CS20);   // clk/1

  OCR2A = 200;  // 8-bit timer, so keep less than 256
  bitSet(TIMSK2, OCIE2A);  // enable OCR2A interrupt
}

void loop()
{
  // NOP
}

ISR(TIMER2_COMPA_vect)
{
  SPEAKER_PORT ^= _BV(SPEAKER_BIT);
}

```

Any obvious mistakes? Thanks for your help!

# Answer
> 2 votes
I tried the code on an Uno and as you say, it does sound odd.

By my calculations, the frequency is 40kHz (16MHz/(200 x 2)), which is above the threshold of hearing. The sound we are actually hearing is probably the 3rd or 5th harmonic, at a reduced intensity and perhaps subject to jitter.

I tried changing

`TCCR2B = _BV(CS20); // clk/1`

to

`TCCR2B = _BV(CS21); // clk/8`

which should mean that the frequency is now 5kHz (16MHz/8/(200 x 2)).

It sounds cleaner.

# Answer
> 1 votes
Looks like my tone frequency was possibly just too high for the buzzer I was using, causing strange output.

Adjusting the clock divider fixed the issue. That is, I changed the following:

```
TCCR2B = _BV(CS20);   // clk/1

```

to

```
TCCR2B = _BV(CS22) | _BV(CS20);  // clk/128

```

and now I get reasonable-sounding tones.

Note that the clock divider you choose is ultimately driven by what frequency range you want to support, and the bit width of the timer. The formula is something like:

```
freq = 16000000 / d / n / 2

```

where `d` is the clock divider value (like 128), and `n` is the counter value at which to interrupt (what goes in `OCR2A` for instance). `n` must fit into the bit width of the specific timer (on ATmega328P timer 1 is 16-bits wide, and timer 2 is 8-bits wide).

Hope this is helpful for anyone else running into these issues. Thanks so much to Kartman over at AVRFreaks.net for pointing me in the right direction.

# Answer
> 0 votes
If you drive the speaker pin from an interrupt, you will inevitably have some jitter, as the interrupt request will sometimes fire while the CPU is processing another ISR. This can lead to one of the levels being held for longer than expected, which in turn leads to spurious frequencies in the output. Note that these are not really *harmonics* (harmonics always have frequencies higher than the fundamental), but rather *beating* between different interrupt sources. That's why you are able to hear something even though the fundamental is well above the hearing range.

If you want to have a clean PWM signal, you should instead generate it in hardware. Timer 2 for example can drive pins 11 (OC2A) and 3 (OC2B). See the bits COM2{A1,A0,B1,B0} in TCCR2A.

---
Tags: arduino-uno, interrupt, pwm, atmega328, timers
---


# Question
Title: Extract binary numbers from infrared sensor that uses I2C bus
I have an infrared sensor(OTI 301) which in order to display the desired temperature I need to apply a formula that depends on 3 binary numbers extracted from the sensor itself. I have tried different approaches but no success yet to extract these binary numbers. Please see link for the data sheet of the sensor where you can see useful information regarding the formula and the binary numbers. https://drive.google.com/file/d/1XMRDCNzY3fn0q6lkGejs5D-pqksfRuZ8/view also here is the code I have tried in the Arduino IDE. Also, attached picture are the needed commands to extract the data from the second data sheet, https://drive.google.com/file/d/1mmdkHkNbwC5VgQxGMrq07XolajNvgBkN/view.

```
#include <Wire.h>
byte val[2] = {0x20,0x80};
void setup() {
Wire.begin(0x20);        // join i2c bus (address optional for master)
Serial.begin(9600);  // start serial for output
}

void loop() {

  //master writter
  Wire.beginTransmission(0x20); // transmit to device
  Wire.write(val,2);
  //Wire.write(x);              // sends one byte
  Wire.endTransmission();    // stop transmitting

  //master reader
  Wire.requestFrom(0x20, 6);    // request 6 bytes from slave device

  while (Wire.available()) { // slave may send less than requested
  Serial.println("H");
  char c = Wire.read(); // receive a byte as character
}

delay(500);
}

```

# Answer
> 2 votes
There are likley two problems:

* An invalid device address is used. The device address is 0x10 and the Arduino Wire library expects it that way (and not in the shifted version with read/write bit).
* Your code uses two separate transactions, however the datasheet specifies a single transaction with a repeated START condition for separating the write and read part.

So an improved version looks like so:

```
#define DEVICE_ADDRESS 0x10

void loop() {
    Wire.beginTransmission(DEVICE_ADDRESS);
    Wire.write(0x80);  // readout command
    Wire.endTransmission(false); // stop sending without ending transaction (repeated START)
    Wire.requestFrom(DEVICE_ADDRESS, 6); // request 6 bytes
    uint8_t data[6];
    for (int i = 0; i < 6; i++) {
        data[i] = Wire.read();
    }
}

```

---
Tags: temperature, infrared
---


# Question
Title: How to use ATtiny pins that are usually 'reserved' for chip programming?
How to program an ATtiny45 to use the pins 1, 5, 6, 7 (i.e. PB5, PB0, PB1, PB2) as input or output?

```
pinMode(5, OUTPUT);
pinMode(0, OUTPUT);
pinMode(1, INPUT);
pinMode(2, INPUT);
digitalWrite(5, HIGH);
...

```

These pins are usually used **to program the ATtiny itself**, so how to avoid a conflict?

Of course, I could just avoid these 4 pins, but then as there are also pins for VCC and GND, **there would be only 2 pins left: PB3, PB4!**

Question: how to use the pins as input/output that are usually used for ATtiny programming?

Linked question:

* Should I connect pins 1, 5, 6, 7 of the ATtiny to the programmer
* Or should I connect pins 1, 5, 6, 7, **as well as 8 and 4 (VCC and GND)** of the ATtiny to the programmer?

If the second bullet is correct, when connecting VCC and GND, won't it make the ATtiny run the previously uploaded code?

# Answer
The ATTiny chips commonly used in Arduino-like boards, such as the Adafruit Trinket or the Digispark USB will usually have a bootloader which runs before your own code. The bootloader checks for a certain state on the USB port of the board, to see if something is waiting to write a new program to the chip.

The bootloader accepts new code from the host computer, if present, and writes it to a certain location in flash memory. If the bootloader does not find anything connected to the USB connector trying to load a new program, then it (the bootloader) starts executing from flash at the location where your program has been stored.

But, what if you want to write a new bootloader, or not have a bootloader? In that case, you can write new software using the MOSI, MISO, and SCK (clock) pins if the RESET pin is pulled to ground.

See: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85\_Datasheet.pdf#page=151

In order to make use of all 6 non-power pins as I/O for the Trinket or Digispark, a "fuse" is set in the ATTiny chip which disables the RESET pin's normal purpose of holding the chip in reset. This means you cannot pull RESET to ground and load a program the normal way.

If the RESET pin is disabled, and the bootloader is not present, then there is another method for loading software, called "High Voltage Serial Programming". Not to worry, the "high" voltage is is about 12V.

See: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85\_Datasheet.pdf#page=155

You can find schematics, or purchase kits/products that allow you to program an ATTiny chip in HV mode online. Many use the small 12V "A23" or "A27" batteries commonly found in RF remote control transmitters to get the 12V signal to put the chip in high-voltage programming mode.
> 1 votes

# Answer
You can just normally use all pins except for the reset pin (pin 0). When you want to program the Attiny, you just connect the programmer. It will reset the Attiny through the reset pin and put it into ISP programming mode. At that point your code hasn't run.

Note: If you want to program the Attiny while it still sits in its circuit, you have to be careful, that the connected circuit does not disturb the ISP communication. The safest way is to disconnect the Attiny from its circuit and then program it.
> 2 votes

---
Tags: programming, attiny, isp
---


title: Time counting using millis

text:
# Question
Title: Time counting using millis
I am trying to write a code where photoresistors (a or b) sense blinking of the light, and lights LED (k and d) simultaneosly with that blinking. And I want that when both photoresistors sense dark for more than 3 secs, the LEDs would light up and stay until one of them again gets lighting. But I cannot understand in which part should I put millis time count?

```
int k = 2;
int d = 3;
int fk = A0;
int fd = A1;
int a = 0;
int b = 0;

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  a = analogRead (fk);
  b = analogRead (fd);
  while (a < 1000 && b < 1000)
  {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    a = analogRead (fk);
    b = analogRead (fd);
  }
  if (a > 1000)
    digitalWrite(2, HIGH);
  else
    digitalWrite(2, LOW);
  if (b > 1000)
    digitalWrite(3, HIGH);
  else
    digitalWrite(3, LOW);
}

```

# Answer
This is one of those cases where the solution is simply to implement a finite state machine. Consider a state machine with these three states:

* `LIGH`: light has been detected by at least one of the sensors, the LEDs follow the light sensors
* `SHORT_DARK`: neither sensor sees light, both LEDs are off
* `LONG_DARK`: it has been at least three seconds since neither sensor saw light, both LEDs are on.

The transitions between those states can be depicted by the following state diagram:

where “darkness detected” means that no sensor sees light, and “light detected” means that at least one sensor sees light.

As a general rule, it is a good practice to always draw a state diagram before you start writing code. Once you are sure your diagram describes the desired behavior, it is almost trivial to translate it into code. Here is how I would code it:

```
void loop()
{
    bool light_k = analogRead(IN_K) >= 1000;
    bool light_d = analogRead(IN_D) >= 1000;

    static enum { LIGHT, SHORT_DARK, LONG_DARK } state;
    static uint32_t darkness_start;
    switch (state) {
    case LIGHT:
        digitalWrite(OUT_K, light_k ? HIGH : LOW);
        digitalWrite(OUT_D, light_d ? HIGH : LOW);
        if (!light_k && !light_d) {
            darkness_start = millis();
            state = SHORT_DARK;
        }
        break;
    case SHORT_DARK:
        if (light_k || light_d) {
            state = LIGHT;
        } else if (millis() - darkness_start >= 3000) {
            digitalWrite(OUT_K, HIGH);
            digitalWrite(OUT_D, HIGH);
            state = LONG_DARK;
        }
        break;
    case LONG_DARK:
        if (light_k || light_d) {
            state = LIGHT;
        }
        break;
    }
}

```
> 3 votes

# Answer
Millis gives you a measure of time. You can store that measure and compare to it later. I don't know what in your code represents a sense of dark/light in your code (resistors can be used to raise or lower the measured input depending on your circuit) so you will have to work the following in by replacing stuff in \<\>

```
unsigned long lastlight;
void loop()
{
    if (<isLitSensorA>) lastlight = millis();
    if (<isLitSensorB>) lastlight = millis();
    if(millis() - lastlight > 3000){ //3 sec since lastlight
        <LightsAlwaysOn>
    }
    else{
        <BlinkWithLights>
    }
}

```
> 2 votes

# Answer
Here is a more elegant way to do this. This program doesn't require you to actually count it has been dark, instead it just remembers the time it has last seen the light (how poetic ;). I also added some commentary alongside the code.

```
// All the variables
int k = 2;        // LED 1
int d = 3;        // LED 2
int fk = A0;      // photoresistor 1
int fd = A1;      // photoresistor 2
int lastLight = 0;

// Set up the LEDs
void setup() {
  pinMode(k, OUTPUT);
  pinMode(d, OUTPUT);
}

void loop()
{
  // Check the photoresitors
  int a = analogRead (fk);
  int b = analogRead (fd);
  if (a > 1000 || b > 1000)
  {
    // Turn LEDs on if one photoresitor senses light
    digitalWrite(k, HIGH);
    digitalWrite(d, HIGH);
    // Also set the last time it was bright to the current time
    lastLight = millis();
  }
  else if (abs(millis() - lastLight) > 3000)
  {
    // Turn LEDs on if it has been dark for more than 3 seconds (that is 3000 milliseconds)
    digitalWrite(k, HIGH);
    digitalWrite(d, HIGH);
  }
  else
  {
    // Turn LEDs off
    digitalWrite(k, LOW);
    digitalWrite(d, LOW);
  }
}

```
> 0 votes

---
Tags: led, millis, photoresistor
---


title: How do I split an incoming string?

text:
# Question
Title: How do I split an incoming string?
I am sending a list of servo positions via the serial connection to the arduino in the following format

```
1:90&2:80&3:180

```

Which would be parsed as:

`servoId : Position & servoId : Position & servoId : Position`

How would I split these values up, and convert them to an integer?

# Answer
> 98 votes
Contrarily to other answers, I'd rather stay away from `String` for the following reasons:

* dynamic memory usage (that may quickly lead to **heap fragmentation** and **memory exhaustion**)
* **quite slow** due to construction/destruction/assignment operators

In an embedded environment like Arduino (even for a Mega that has more SRAM), I'd rather use **standard C functions**:

* `strchr()`: search for a character in a C string (i.e. `char *`)
* `strtok()`: splits a C string into substrings, based on a separator character
* `atoi()`: converts a C string to an `int`

That would lead to the following code sample:

```
// Calculate based on max input size expected for one command
#define INPUT_SIZE 30
...

// Get next command from Serial (add 1 for final 0)
char input[INPUT_SIZE + 1];
byte size = Serial.readBytes(input, INPUT_SIZE);
// Add the final 0 to end the C string
input[size] = 0;

// Read each command pair
char* command = strtok(input, "&");
while (command != 0)
{
    // Split the command in two values
    char* separator = strchr(command, ':');
    if (separator != 0)
    {
        // Actually split the string in 2: replace ':' with 0
        *separator = 0;
        int servoId = atoi(command);
        ++separator;
        int position = atoi(separator);

        // Do something with servoId and position
    }
    // Find the next command in input string
    command = strtok(0, "&");
}

```

The advantage here is that no dynamic memory allocation takes place; you can even declare `input` as a local variable inside a function that would read the commands and execute them; once the function is returned the size occupied by `input` (in the stack) is recovered.

# Answer
> 45 votes
This function can be used to separate a string into pieces based on what the separating character is.

```
String xval = getValue(myString, ':', 0);
String yval = getValue(myString, ':', 1);

Serial.println("Y:" + yval);
Serial.print("X:" + xval);

```

Convert String to int

```
int xvalue = xval.toInt();
int yvalue = yval.toInt();

```

This Chunk of code takes a string and separates it based on a given character and returns The item between the separating character

```
String getValue(String data, char separator, int index)
{
    int found = 0;
    int strIndex[] = { 0, -1 };
    int maxIndex = data.length() - 1;

    for (int i = 0; i <= maxIndex && found <= index; i++) {
        if (data.charAt(i) == separator || i == maxIndex) {
            found++;
            strIndex[0] = strIndex[1] + 1;
            strIndex[1] = (i == maxIndex) ? i+1 : i;
        }
    }
    return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

```

# Answer
> 13 votes
You could do something like the following, but please take into account several things:

If you use `readStringUntil()`, it will wait until it receives the character or timeouts. Thus, with your current string, the last position will last a little longer, as it has to wait. You can add a trailing `&` to avoid this timout. You can easily check this behavior in your monitor, try to send the string with and without the extra `&` and you will see such timeout delay.

You actually do not need the servo index, you can just send your string of positions, and get the servo index by the value position in the string, something like: `90&80&180&`.

If you use the servo index, maybe you want to check it (convert to `int`, and then match the loop index i) to ensure that nothing went wrong with your message.

You have to check that the returning string from `readStringUntil` is not empty. If the function timeouts, you didn't receive enough data, and thus any attempt to extract your `int` values will produce strange results.

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

void loop() {
  for (int i=1; i<=3; i++) {
    String servo = Serial.readStringUntil(':');
    if (servo != "") {
      // here you could check the servo number
      String pos = Serial.readStringUntil('&');
      int int_pos=pos.toInt();

      Serial.println("Pos");
      Serial.println(int_pos);
    }
  }
}

```

# Answer
> 9 votes
You can use `Stream.readStringUntil(terminator)` passing a different terminator for each part.

On each part you then call `String.toInt`

# Answer
> 7 votes
Simplest solution is to use sscanf().

```
  int id1, id2, id3;
  int pos1, pos2, pos3;
  char* buf = "1:90&2:80&3:180";
  int n = sscanf(buf, "%d:%d&%d:%d&%d:%d", &id1, &pos1, &id2, &pos2, &id3, &pos3);
  Serial.print(F("n="));
  Serial.println(n);
  Serial.print(F("id1="));
  Serial.print(id1);
  Serial.print(F(", pos1="));
  Serial.println(pos1);
  Serial.print(F("id2="));
  Serial.print(id2);
  Serial.print(F(", pos2="));
  Serial.println(pos2);
  Serial.print(F("id3="));
  Serial.print(id3);
  Serial.print(F(", pos3="));
  Serial.println(pos3);

```

This give the following output:

```
n=6
id1=1, pos1=90
id2=2, pos2=80
id3=3, pos3=180

```

Cheers!

# Answer
> 4 votes
```
String getValue(String data, char separator, int index)
{
    int maxIndex = data.length() - 1;
    int j = 0;
    String chunkVal = "";

    for (int i = 0; i <= maxIndex && j <= index; i++)
    {
        chunkVal.concat(data[i]);

        if (data[i] == separator)
        {
            j++;

            if (j > index)
            {
                chunkVal.trim();
                return chunkVal;
            }

            chunkVal = "";
        }
        else if ((i == maxIndex) && (j < index)) {
            chunkVal = "";
            return chunkVal;
        }
    }
}

```

# Answer
> 4 votes
**See example at:** https://github.com/BenTommyE/Arduino\_getStringPartByNr

```
// splitting a string and return the part nr index split by separator
String getStringPartByNr(String data, char separator, int index) {
    int stringData = 0;        //variable to count data part nr
    String dataPart = "";      //variable to hole the return text

    for(int i = 0; i<data.length()-1; i++) {    //Walk through the text one letter at a time
        if(data[i]==separator) {
            //Count the number of times separator character appears in the text
            stringData++;
        } else if(stringData==index) {
            //get the text when separator is the rignt one
            dataPart.concat(data[i]);
        } else if(stringData>index) {
            //return text and stop if the next separator appears - to save CPU-time
            return dataPart;
            break;
        }
    }
    //return text if this is the last part
    return dataPart;
}

```

# Answer
> 3 votes
*jfpoilpret* provided great answer for parsing serial command on Arduino. However Attiny85 doesn't have bidirectional serial - SoftwareSerial has to be used. This is how you port same code for Attiny85

```
#include <SoftwareSerial.h>

// Calculate based on max input size expected for one command
#define INPUT_SIZE 30

// Initialize SoftwareSerial
SoftwareSerial mySerial(3, 4); // RX=PB3, TX=PB4

// Parameter for receiving Serial command (add 1 for final 0)
char input[INPUT_SIZE + 1];

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

void loop() {
  // We need this counter to simulate Serial.readBytes which SoftwareSerial lacks
  int key = 0;

  // Start receiving command from Serial
  while (mySerial.available()) {
    delay(3);  // Delay to allow buffer to fill, code gets unstable on Attiny85 without this for some reason
    // Don't read more characters than defined
    if (key < INPUT_SIZE && mySerial.available()) {
      input[key] = mySerial.read();
      key += 1;
    }
  }

  if (key > 0) {
    // Add the final 0 to end the C string
    input[key] = 0;

    // Read each command pair
    char* command = strtok(input, "&");
    while (command != 0)
    {
      // Split the command in two values
      char* separator = strchr(command, ':');
      if (separator != 0)
      {
        // Actually split the string in 2: replace ':' with 0
        *separator = 0;
        int servoId = atoi(command);
        ++separator;
        int position = atoi(separator);
      }
      // Find the next command in input string
      command = strtok(0, "&");
    }
  }
}

```

Attiny85 schematics for pin numbers

Sketch compiles into:

```
Sketch uses 2244 bytes (27%) of program storage space. Maximum is 8192 bytes.
Global variables use 161 bytes (31%) of dynamic memory, leaving 351 bytes for local variables. Maximum is 512 bytes.

```

So there is plenty of space and memory for the rest of code

# Answer
> 1 votes
Here is **Arduino** method to split a String as answer to the question "How to split a string in substring?" declared as a duplicate of the present question.

The objective of the solution is to parse a series of **GPS** positions logged into a **SD card** file. Instead of having a String received from `Serial`, the String is read from file.

The function is `StringSplit()` parse a String `sLine = "1.12345,4.56789,hello"` to 3 Strings `sParams[0]="1.12345"`, `sParams[1]="4.56789"` & `sParams[2]="hello"`.

1. `String sInput`: the input lines to be parsed,
2. `char cDelim`: the delimiter character between parameters,
3. `String sParams[]`: the output array of parameters,
4. `int iMaxParams`: the maximum number of parameters,
5. Output `int`: the number of parsed parameters,

The function is based on `String::indexOf()` and `String::substring()` :

```
int StringSplit(String sInput, char cDelim, String sParams[], int iMaxParams)
{
    int iParamCount = 0;
    int iPosDelim, iPosStart = 0;

    do {
        // Searching the delimiter using indexOf()
        iPosDelim = sInput.indexOf(cDelim,iPosStart);
        if (iPosDelim > (iPosStart+1)) {
            // Adding a new parameter using substring()
            sParams[iParamCount] = sInput.substring(iPosStart,iPosDelim-1);
            iParamCount++;
            // Checking the number of parameters
            if (iParamCount >= iMaxParams) {
                return (iParamCount);
            }
            iPosStart = iPosDelim + 1;
        }
    } while (iPosDelim >= 0);
    if (iParamCount < iMaxParams) {
        // Adding the last parameter as the end of the line
        sParams[iParamCount] = sInput.substring(iPosStart);
        iParamCount++;
    }

    return (iParamCount);
}

```

And the usage is really simple:

```
String sParams[3];
int iCount, i;
String sLine;

// reading the line from file
sLine = readLine();
// parse only if exists
if (sLine.length() > 0) {
    // parse the line
    iCount = StringSplit(sLine,',',sParams,3);
    // print the extracted paramters
    for(i=0;i<iCount;i++) {
        Serial.print(sParams[i]);
    }
    Serial.println("");
}

```

# Answer
> 1 votes
```
char str[] = "1:90&2:80&3:180";     // test sample serial input from servo
int servoId;
int position;

char* p = str;
while (sscanf(p, "%d:%d", &servoId, &position) == 2)
{
    // process servoId, position here
    //
    while (*p && *p++ != '&');   // to next id/pos pair
}

```

# Answer
> 0 votes
```
void setup() {
Serial.begin(9600);
char str[] ="1:90&2:80";
char * pch;
pch = strtok(str,"&");
printf ("%s\n",pch);

pch = strtok(NULL,"&"); //pch=next value
printf ("%s\n",pch);
}
void loop(){}

```

# Answer
> 0 votes
It's not an answer to your question but it may be useful for someone. If your string has a specific prefix, then you can use simply `startsWith` and `substring`. E.g.

```
void loop ()
  if(Serial.available()){
    command = Serial.readStringUntil('\n');
    Serial.println("Received command: " + command);
    if(command.startsWith("height")) {
      Serial.println(command.substring(7));
    }
  }
}

```

And then send `height 10` what will extract `10`.

---
Tags: serial, arduino-mega, string
---


# Question
Title: Can I use laptop USB port to power Nodemcu if every port used
I wonder if a laptop USB port is enough or I have to use an external power supply if the NodeMCU under heavy load. Here is my list of sensors and port used.

```
3.3V
3.3V
D1 to D7
A0
GND

```

Sensors: Turbidity sensor, Flow sensor, Temperature sensor, 4 led

# Answer
> 1 votes
standard current you can draw from a usb port is 500 mili ampere with 5 volt(you may get even more but it is not recommended) . so if you want to calculate

sensors are very low current about 1~2 mA(but you must check out datasheet)

turbidity for example draws 30 mA

temperature ds1820 is 1 mA

flow is up 2 mA

the LEDs based on resistors series with them you normally up to 3 mA for each(1k series to 3.3 volt)

if you sum up all of them

30+1+2+4\*3=45mA

but you should consider other consumers for example if you need 3.3 V you need a regulator such as ams1117 and it may waste some mili Ampere (not too much) and you certainly have a microprocessor and you should check data sheet but consider 100mA for that in worst case.

to count all of them the answer is YES

# Answer
> 0 votes
Sensors don't usually require that much current and a usb port should be able to handle 4 leds and the MCU without a problem. If you are using an Apple laptop it will disable the usb port temporarily if you draw too much current from it. Some PC laptops probably do the same.

---
Tags: power, nodemcu
---


# Question
Title: How to Measure many voltages (Uno) - Analog extenders a good option?
**I am trying to make a battery capacity tester** (3.7v li-ion 18650 battery) using arduino uno. If possible i'd like to test 20 or more batteries at the same time. **I need to measure the voltage of each battery every 1 second.**

The uno has 6 anolog inputs iirc so too little for this application. **I think using analog multiple extenders (connected using I2C) chained together to create enough analog inputs.** **For example this one**: https://nl.aliexpress.com/item/32858973834.html?spm=a2g0o.productlist.0.0.57206143DNgWKp&algo\_pvid=526d42f2-f7ee-4781-932b-947744ac631e&algo\_expid=526d42f2-f7ee-4781-932b-947744ac631e-0&btsid=89c452fa-1d7c-4ae9-9dd5-ed8fc9bff128&ws\_ab\_test=searchweb0\_0,searchweb201602\_8,searchweb201603\_52 **Do you think I'll be able to get relatively accurate voltage measurements using this approach?**

The purpose of the circuit is to measure the amount of mah (battery capacity) of the 18650 battery which is being discharged via the 10Ohm resistor. The battery will be discharged from 4.2volt (fully charged) to approx 2.5V using the 10ohm resistor, each second the voltage drop over the resistor will be measured and using it and the time passed the integral of time\*current will be calculated to determine the capacity.

**This is the basic circuit used to connect each 18650 battery**, the ANALOG1 pin will be connected to the input of the analog extenders:  (I based it off of the circuit from this video: https://www.youtube.com/watch?v=WScPyfQz\_f8) The idea is to measure the voltage drop over the 10Ohm10W power resistor and calculate the current using the known resistance value, calculate the integral of current\*time to get a capacity value for the battery.

**Is this a good approach? Would you recommend using analog extenders for this? If not what would be a better solution? Thank you very much!**

# Answer
Actually it is two separate questions and I answer your first question of reading multiple analog values using one ADC and the answer is Yes you can use this approach but you should give enough time for each channel to charge internal ADC capacitor when you change channel .so if you use more independent ADC you get more time for each channel and result is better
> 1 votes

---
Tags: arduino-uno, battery, voltage, analog
---


# Question
Title: Unable to use DHT11 with NodeMCU(esp8266)
I am trying to use a NodeMCU like an arduino,trying to read Temperature and Humidity using a DHT11,but when ever I check the serial monitor the it outputs : nan, Can anyone help me find the problem.(The data pin is D4 on NodeMCU)

```
    #include "DHT.h"

DHT dht2(2,DHT11);

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

    }

void loop()
{

    Serial.println("Temperature: ");
    Serial.println((dht2.readTemperature( )));
    Serial.println("Humidity");
    Serial.println((dht2.readHumidity( )));
    delay(5000);

}

```

# Answer
The esp8266 boot configuration pins 0, 2, 15 require a pull-up/pull-down to ensure the required state at boot. The board (NodeMCU in this case) has pull-up resistor on io0 and io2 and a pull-down resistor on pin 15. The MCU pins io0, io2 and io16 are the NodeMCU pin D3, D4 and D8. You can use this pins in the sketch, but only to attach devices which are not in conflict with the required boot state and are not disturbed by the pull-up/pull-down.

**NodeMCU and "Wemos D1 R2 and Mini" esp8266 pins and io overview**

---

**Serial**

RX io1 RX0

TX io3 TX0

---

**boot config pins** with pullup or pulldown on board

D3 io0 PULLUP (LOW for boot to flashing mode)

D4 io2 TX1 PULLUP (Serial1 TX. no RX for Serial1)

D8 io15 PULLDOWN (SS pin if esp8266 is SPI slave)

---

**untroubled GPIOs** with optional function for I2C or SPI bus:

D1 io5 default pin for I2C SCL

D2 io4 default pin for I2C SCA

D5 io14 SPI CLK

D6 io12 SPI MISO

D7 io13 SPI MOSI

---

**RTC pin** for timed deep sleep wake-up (if connected to reset pin)

D0 io16 - optional internal pulldown, internal pullup not available

---

**not useable**: S*x* pins io 6 to io 11 connect QIO SPI flash memory (in DIO flash mode the 2 QIO pins can be used as gpio) (in a very special setup the SPI bus can be used with other SPI device)

*note: most digital IO start as INPUT\_PULLUP*
> 1 votes

---
Tags: nodemcu, temperature-sensor
---


# Question
Title: Arduino Nano 33 IOT - Bluetooth Classic (Serial)
I've an arduino nano 33 iot and I'm working with the first time with bluetooth. So far BLE is working fine, I can use an app on my smartphone to check the services and characteristics. Is it possible to send data over serial via Bluetooth on this board ?

# Answer
This board has multiple processors on it. The main processor (SAMD) rus your arduino code. There is also an ESP32 based processor which runs the WIFI and the Bluetooth. There is a pretty featured library for controlling the WIFI called WIFININA. This library does NOT have any bluetooth functions though. Therefore, until someone writes a library which lets you control the bluetooth functions of that ESP32 chip, I don't think you'll be able to send arbitrary serial data via bluetooth. It is "possible" to do this but not without a lot of technical wizardry.

Here are some links to examples of what the code might look like if you were writing code directly to the ESP32 chip here https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
> 2 votes

---
Tags: serial, bluetooth
---


title: Servo Motor in function

text:
# Question
Title: Servo Motor in function
I have a project with 9 servo, I want to make a function to control each separate. Only that he is not accepting the servo as a parameter. Can someone tell me if it is possible to pass the servant as a parameter, and how? Thank you!! Example:

```
Servo s1,s2,s3;

void toMove(Servo obj,int inPosition, int forPosition){
var i = 0;
  for(i = inPosition; i<forPosition; i++){
    obj.write(i);
  }
}

void loop(){
  if(true){
     toMove(s1,0,180);
     toMove(s2,0,180);
  }
}

```

# Answer
> 1 votes
Yes, it is possible, and you've done it *almost* right. I made a minor correction in the `toMove()` function ("int" instead of "var"), and supplied the `setup()` function which you didn't show. It compiles without error. I didn't check it for correct operation as it looks like you had reduced your code to the minimum example necessary to demonstrate your question -- and thanks for that! Here is what I compiled:

```
#include <Servo.h>

#define SERVO1      9
#define SERVO2      10

/*****< External and Global Declarations >*****/
Servo s1, s2;
void toMove(Servo obj, int inPosition, int forPosition);

/*****< Local Function Prototypes >*****/

void toMove(Servo obj,int inPosition, int forPosition){
int i = 0;
  for(i = inPosition; i<forPosition; i++){
    obj.write(i);
  }
}

void setup()
{
    s1.attach(SERVO1);
    s2.attach(SERVO2);
}

void loop() {
   toMove(s1, 0, 180);
   toMove(s2, 0, 90);
}

```

# Answer
> 0 votes
You have not use attach() function:

```
 s1.attach(pin_1);
 s2.attach(pin_2);

```

See how to use servo motor

---
Tags: arduino-uno, servo
---


title: Keep motor moving

text:
# Question
Title: Keep motor moving
I have a problem on how to keep my stepper motor moving when button is released. It should only stop moving if I press the button again.

For now, stepper motor is only moving IF the button is constantly pressed.

```
//Constants won't change. They're used here to set pin numbers:
const int buttonPin = 4;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
const int dirPin = 8;        // the number of the motor direction pin
const int stepPin = 9;         // the number of the motor step pin

//Variables will change:
boolean flag = true;
int buttonState = 0;         // variable for reading the pushbutton status
int distance = 0;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(dirPin, OUTPUT);  //YELLOW
  pinMode(stepPin, OUTPUT); //ORANGE

  digitalWrite(buttonPin, LOW);
  digitalWrite(dirPin, HIGH);
  digitalWrite(stepPin, HIGH);
}

void loop() {
  buttonState = digitalRead(buttonPin); // Read the state of the pushbutton

  if (digitalRead(buttonPin) == LOW) {  // If pushbutton is pressed, buttonState is HIGH:
    digitalWrite(ledPin, HIGH);
    digitalWrite(dirPin, LOW);          // LOW=FORWARD DIRECTION
    digitalWrite(stepPin, HIGH);        // stepPin = MOTOR ON/OFF
    delayMicroseconds(100);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(100);
    distance++;
    if(distance > 21000){
      distance = 0;
      delay (3000);
      reverse();
    }
  }

  if (digitalRead(buttonPin) == HIGH){ // turn LED off:
    digitalWrite(ledPin, LOW);
    digitalWrite(dirPin, LOW);  //LOW = FORWARD DIRECTION
    digitalWrite(stepPin, LOW); //stepPin = MOTOR ON/OFF
    delayMicroseconds(100);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(100);
  }
}

void reverse() {
  digitalWrite(dirPin,HIGH); //HIGH = REVERSE DIRECTION
  digitalWrite(stepPin,HIGH);
  delayMicroseconds(100);
  digitalWrite(stepPin,LOW);
  delayMicroseconds(100);
  distance++;
    if(distance > 21000){
      distance = 0;
      delay(3000);
      return;
    }
  reverse();
}

```

# Answer
N.b. your code is unreadable, so I won't attempt to debug your program, but I will present some pseudo-code that could help.

> It should only stop moving if I press the button again ... \[as of\] now, \[the\] stepper motor is only moving IF the button is constantly pressed.

So what you need to do is save the state of your Motor, (MOVING, STOPPED, etc.) and base your code on that state.

You will also need to de-bounce your switch.

Your loop will have to:

* Read & de-bounce the switch
* Update the state based on switch
* Run the stepper based on state

pseudo-code:

```
// include libraries etc.
#include <Stepper.h>

// set up your buttons pins etc.
int button = <pin>;
Stepper = step(...); // pins etc.

void setup()
{
   // do setup stuff...
}

enum MOTORSTATES {
  STOPPED = 1,
  FORWARD = 2,
}

MOTORSTATES state = STOPPED;

// forward declare your functions
bool isPressedDebounce(int pin);
void doStep(Stepper&, MOTORSTATES);
MOTORSTATES changeState(MOTORSTATES);

// loop is now simple
void loop()
{
  if(isPressedDebounce(button))
    state = changeState(state);

  doStep(step, state);
}

// because we have broken our problem into pieces
bool isPressedDebounce(int pin)
{
  // proccess and de-bounce the switch
  // implementation left as exercise for reader
}

void doStep(Stepper& step, MOTORSTATES state)
{
  // based on the state move the stepper
  // implementation left as exercise for reader
  switch(state)
  {
    case STOPPED:
      // DO IT
      break;
    case FORWARD:
      // DO IT
      break;
  }
}

MOTORSTATES changeState(MOTORSTATES state)
{
  // n.b. I used this pattern because it is the beginning of a state machine!
  switch(state)
  {
    case STOPPED:
      return FORWARD;
      break;
    case FORWARD:
      return STOPPED;
      break;
  }
}

```

I structured the pseudo code such that it contains a simple state machine, and can be easily extended. State machine code is very useful for programming Arduinos!
> 1 votes

# Answer
There are two issues:

1. You SHOULD pull-up or pull-down the input pin when using pushbutton.
2. You should detect the "press" and "release" event.

Two above issues are mentioned in this tutorial
> 0 votes

---
Tags: motor
---


# Question
Title: Temperature and Humidity Sensor TinyShield (No device found on com5)
Hi i have recently started working on a Temperature and Humidity Sensor TinyShield (ASD2511-R-T) and faced the issue as shown in the image below: No device found on com5.

I have followed the tutorial as shown in the TinyShield webpage and worked through the steps. 1) Installed the Arduino IDE, 2) Installed the Si7021 Arduino Library, 3)Download the .zip file of the example program and open it in the Arduino IDE.

This is the following example code provided by the tutorial.

```
/*
  TinyCircuits Si7020 Temperature and Humidity Sensor TinyShield Example Sketch

  This demo shows the bare minimum to read temperature and humidity data from
  the Si7020 sensor using the Si7020 library written by Marcus Sorensen.

  This example is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Written 20 March 2016
  By Ben Rose
  Modified 07 January 2019
  By Hunter Hykes

  https://TinyCircuits.com
*/

#include <Wire.h>
#include <SI7021.h>

SI7021 sensor;

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  Serial.print("Initializing sensor... ");
  if(!sensor.begin()){
    Serial.println("Sensor not found!");
    while(true);
  }
  Serial.println("Success!");
}

void loop()
{
  int celcius=sensor.getCelsiusHundredths()/100;
  int relativeHumidity=sensor.getHumidityPercent();
  Serial.print(celcius);
  Serial.print(" deg Celsius\t");
  Serial.print(relativeHumidity);
  Serial.println("% relative humidity");

  delay(500);
}

```

However, when I proceed to upload the program, the following error had occurred. This is the first time i am working on a TinyShield product.

Any help is appreciated! Thanks!

Do let me know if i need to provide any further information.

The options for COM 5 the only one avaliable.

# Answer
The below was the issue, i was using the wrong broad and processor.

Thanks for the help!
> 0 votes

---
Tags: arduino-ide, temperature-sensor
---


title: Publish chipid to mqtt using ESP32-CAM

text:
# Question
Title: Publish chipid to mqtt using ESP32-CAM
I have been trying to push the data of temp, humidity, and pressure from a sensor to MQTT using ESP 32Cam, and was able to do using the following code:

```
pressure = bme.readPressure();

//Convert the value to a char array
char preString[16];
dtostrf(pressure, 1, 2, preString);
Serial.print("Pressure: ");
Serial.println(preString);
client.publish("esp32/pressure", preString);

```

When I started off with the following code for getting the mac address:

```
chipid=ESP.getEfuseMac();//The chip ID is essentially its MAC address(length: 6 bytes).
Serial.printf("ESP32 Chip ID = %04X",(uint16_t)(chipid>>32));//print High 2 bytes
Serial.printf("%08X\n",(uint32_t)chipid);//print Low 4bytes.

```

But when I tried to publish the Chip id, that I was getting on the serial monitor, to the MQTT, an error came up with this:

`call of overloaded 'String(uint64_t)' is ambiguous`

Here's my code that I tried:

```
char macValue[16];
String(ESP.getEfuseMac()).toCharArray(macValue,16);
client.publish("esp32/ChipID", macValue);

```

# Answer
> 2 votes
You would be better off formatting it nicely instead of relying on String...

```
char macValue[17]; // Don't forget one byte for the terminating NULL...
uint64_t mac = ESP.getEFuseMac();
sprintf(macValue, "%016x", mac);
client.publish("esp32/ChipID", macValue);

```

However, I'm not certain that sprintf can cope with a 64 bit value like that directly. If not, you can split it:

```
char macValue[17]; // Don't forget one byte for the terminating NULL...
uint64_t mac = ESP.getEFuseMac();
uint32_t hi = mac >> 32;
uint32_t lo = mac;
sprintf(macValue, "%08x%08x", hi, lo);
client.publish("esp32/ChipID", macValue);

```

---
Tags: c++, c, esp32, mqtt
---


# Question
Title: Converting each digit in an integer to its respective ASCII characters
For example what would be the process of converting the integer 1023 into ascii characters of

0x31 (1) 0x30 (0) 0x32 (2) 0x33 (3)

Not looking for any library functions (I know of Serial.print() and what not). I am trying to serially communicate an integer to the serial monitor, and I'd like to know what the process would be for an algorithm to take an integer and make each digit its corresponding ascii character

# Answer
> 3 votes
To convert a whole number to a char array in one go use the itoa function. That sounds like what you actually need.

To convert one digit from decimal to ascii just add '0', the ascii value for a 0. If you just want to try to understand what's going on, it's something like this.

```
char result[4] = {0};
int num = 345;

int digit = num % 10;  // get the 5 off the end
result[2] = digit + '0';  // convert to ascii and store
num /= 10;   // get rid of the 5
digit = num % 10;   // get the 4 off the end
result[1] = digit + '0';  // convert to ascii and store
num /= 10;   // get rid of the 4
digit = num % 10;   // get the 3 off the end
result[0] = digit + '0';  // convert to ascii and store

Serial.print(result);  // prints "345"

```

---
Tags: serial, softwareserial, algorithm
---


# Question
Title: Switch Case Return , Return not printing
I am trying to get the value of a key pressed and set it to return a value to use in a loop. In the code below the Print(t) does not show anything

```
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char hexaKeys[ROWS][COLS] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[ROWS] = {5, 4, 3, 2};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys),rowPins,colPins,ROWS,COLS;

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

void loop()
{
    int t;
    switch (customKeypad.getKey())
    {
    case 'A':
        t = 8;
        break;
    case '2':
        t = 9;
        break;
    }
    return t;
    Serial.print(t);
}

```

# Answer
You misunderstand the use of return. The loop function is declared void. That means it doesn't return anything. If you simply remove that return statement completely then your code will do what you want.

The return stops the loop. It throws away the value since the loop is defined as returning void, and code execution never reaches the print statement. Writing anything in a function after a return statement is useless.
> 3 votes

---
Tags: arduino-mega, keypad
---


# Question
Title: How do I download a sketch to an Arduino semi-permanently?
I will be working with Arduino(s), and I would like to find a way to download the sketches to the board semi permanently, in a way that I can remove the USB from the board, apply power, and still have the Arduino execute the code

I am planning to use Mega2960, Uno, and Nano. If there are any differences between the uploading process, please let me know.

P.S., I am using boards produced by Elegoo, not by Arduino, if that makes a difference.

# Answer
> 1 votes
1. Download the Arduino software (IDE, or Integrated Development Environment).

In our case, we only need to download and run Windows Installer and follow the pop up instructions. When asked if you want to install the Arduino driver, just press Yes.

2. Connect your Arduino Nano board to your computer.

In this step, Windows should automatically find the proper Arduino driver and install it, and your Nano board should be ready to use. If not, please refer to the above mentioned instruction for details on installing the drivers. Some compatible Nano boards such as DCCduino manufactured by a Chinese company use different USB-to-Serial chips so they require to install different drivers, but the installation should be quite straight forward once you have downloaded the proper drivers from internet.

3. Launch the Arduino application.
4. Open the blink example.

Open the LED blink example sketch: File \> Examples \> 01.Basics \> Blink.

For those who are not familiar with Arduino sketch, a sketch is simply a program with various instructions telling Arduino board what to do.

5. Select your board.

You’ll need to select what type of Arduino board you are using. In our case, simply select Tools \> Board \> Arduino Nano w/Atmega328.

6. Select your serial port

You also need to select the serial device of the Arduino board: Tools \> Serial Port. Usually the port number will be COM3 or higher (COM1 and COM2 are usually reserved for hardware serial ports). To find out, you can disconnect your Arduino board and re-open the menu; the entry that disappears should be the Arduino board. Reconnect the board and select that serial port.

7. Upload the program to Nano board

Now, simply click the “Upload” button in the environment. Wait a few seconds – you should see the RX and TX leds on the board flashing. If the upload is successful, the message “Done uploading.” will appear in the status bar.

A few seconds after the upload finishes, you should see the pin 13 (L) LED on the board start to blink (in orange). If it does, congratulations! You’ve gotten Arduino up-and-running.

Disconnect from your computer and connect to a power supply to see the blinking light.

---
Tags: uploading
---


# Question
Title: Arduino IDE with ATtiny85 error "multiple definition of `__vector_5"
I am having a problem compiling the code for my ATtiny85 circuit.

I am using the timer/counter0 in normal mode so that when it overflows it triggers the TIMER0\_OVF\_vect ISR. When I have that ISR in my code, it wont compile and gives this error:

```
wiring.c.o (symbol from plugin): In function `__vector_5':
(.text+0x0): multiple definition of `__vector_5'
sketch\Glove_heater_v1.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board ATtiny25/45/85.

```

## Maybe I just need to use a different name for the ISR?

```
My Code:

//Red LED on PB0
//Blue LED on PB1
//Pushbutton PB2
//Battery voltage divider PB3
//Mosfet control PB4

#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

volatile uint8_t checkVoltage = 0;

void setup() {

   DDRB = 0b0010011; //set PB0,PB1,PB4 as output, PB2,PB3 as input
   PORTB = 0b00000011; //set PB0,PB1 HIGH so LEDs are off, other pins LOW

   //Setup TC0 for overflow interrupt trigger
   TCCR0B |= 0b00000101; //clk/1024 prescaler
   TIMSK |= 0b00000010;  //set TOIE0 enable overflow interrupt
   sei();
}

void loop() { //do nothing in this test code

}

ISR(TIMER0_OVF_vect){ //Timer/counter0 interrupt check voltage
   checkVoltage = 1;
}

```

Any ideas are appreciated!

# Answer
The error message was:

> wiring.c.o \[...\]: multiple definition of \`\__vector\_5'
> Glove\_heater\_v1.ino.cpp.o \[...\]: first defined here

`__vector_5` is `TIMER0_OVF_vect`. So you have one definition of this ISR in your sketch, and another one in wiring.c. This wiring.c is part of the Arduino core. As KIIV puts it in a comment, it uses `TIMER0_OVF_vect` for timekeeping (`millis()`, `micros()` and `delay()`).

You have two options for solving this:

* you can use the other timer (Timer 1) in your sketch, and leave Timer 0 for the Arduino core
* since you are not using the Arduino core anyway, you can get rid of it by simply defining `main()` in your sketch instead of `setup()` and `loop()`.
> 2 votes

---
Tags: timers, attiny, isr, attiny85
---


title: Protect the Arduino make with Unique Id

text:
# Question
Title: Protect the Arduino make with Unique Id
I’d like to protect my arduino make with a unique serial number for every device I make. What are the proper ways to do it? Probably there are kind of best practices… Keep it in EEPROM is obviously a bad idea.

I believe that there is some chip that can be added to the circuitry.

The general idea is the following. Circuitry has a hardware which gives a unique id (serial number). Distributor/seller generates the signature using unique id and put it to the eeprom. Arduino program verifies this signature using hardware serial number. Arduino program is distributed in binary or within the device.

# Answer
I still suggest using the eeprom. It is the firmware's job to handle whether or not data in eeprom can be written. You could implement wrapper functions for the arduino which can only read/write after a defined offset. You can set this read-only data with the .eep-file when you upload your sketch. The eeprom file then may be generated programmatically.

Once you have to flash several individual devices with a final firmware version, there are no benefits in using the arduino ide. You can upload the firmware and the eeprom file using avrdude:

```
avrdude -P YOUR_PORT -b 115200 -p ATmega328P -e -U flash:w:YOUR_FIRMWARE.hex -U eeprom:w:YOUR_EEPROM.eep

```

It's up to you how to generate the eeprom file (bash/batch, make, pyhton,...).
> 2 votes

# Answer
I found a way! I can use DS2401 or DS2411.

These devices are 64-bit read only memory (ROM) "silicon serial number" devices which are programmed by the manufacturer with a unique 48 bit serial number, an 8 bit product family code, and an 8 bit CRC.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Can i combine an ultrasonic sensor and gps together?
I need to operate 2 different sensors by Arduino UNO: GPS module and Ultrasonic sensor. I have managed to run each one of them separately and I don't know how to manipulate the code;

## GPS MODULE

```
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

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

void loop()
{
  // This sketch displays information
  // every time a new sentence is correctly encoded.
  while (ss.available() > 0)
  {
    gps.encode(ss.read());
    if (gps.location.isUpdated())
    {
      Serial.print("Latitude= ");
      Serial.print(gps.location.lat(), 6);
      Serial.print(" Longitude= ");
      Serial.println(gps.location.lng(), 6);
    }
  }
}

```

### ULTRASONIC SENSOR

```
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;

// defines variables
long duration;
int distance;
void setup()
{
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(9600); // Starts the serial communication
}

void loop()
{
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  distance= duration*0.034/2;

  // Prints the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.println(distance);
}

```

# Answer
> 1 votes
That's easy. I have no possibility to try it. But if your code has been working, this will also. (Just copy/paste.) I had to change the while loop into a if block, because I was not sure, if the while blocks for a longer time. It could have been that the GPS sends and sends and sends ... That would block the ultrasonic sensor.

```
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

const int trigPin = 9;
const int echoPin = 10;

long duration;
int distance;

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

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop()
{
  // This sketch displays information
  // every time a new sentence is correctly encoded.
  if (ss.available() > 0)
  {
    gps.encode(ss.read());
    if (gps.location.isUpdated())
    {
      Serial.print("Latitude= ");
      Serial.print(gps.location.lat(), 6);
      Serial.print(" Longitude= ");
      Serial.println(gps.location.lng(), 6);
    }
  }

  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  distance= duration*0.034/2;

  // Prints the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.println(distance);
}

```

---
Tags: arduino-uno, gps, tinygps
---


title: publish json data to mqtt

text:
# Question
Title: publish json data to mqtt
I am trying to publish `JSON` data to mqtt with following code snippet

```
#include <Arduino_JSON.h>
JSONVar data;
data["temperature"] = temperature;
data["humidity"] = humidity;
data["pressure"] = pressure;
data["chipId"] = chipId;

String jsonString = JSON.stringify(data);
client.publish("esp32/data", jsonString);

```

But getting following error

```
/home/ubuntu/Arduino/libraries/PubSubClient/src/PubSubClient.h:144:12: note:   candidate expects 4 arguments, 2 provided
Multiple libraries were found for "PubSubClient.h"
 Used: /home/ubuntu/Arduino/libraries/PubSubClient
Multiple libraries were found for "Wire.h"
 Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/Wire
Multiple libraries were found for "Adafruit_BME280.h"
 Used: /home/ubuntu/Arduino/libraries/Adafruit_BME280_Library
Multiple libraries were found for "Adafruit_Sensor.h"
 Used: /home/ubuntu/Arduino/libraries/Adafruit_Unified_Sensor
Multiple libraries were found for "SPI.h"
 Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/SPI
Multiple libraries were found for "Arduino_JSON.h"
 Used: /home/ubuntu/Arduino/libraries/Arduino_JSON
Multiple libraries were found for "WiFi.h"
 Used: /home/ubuntu/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WiFi
 Not used: /opt/arduino-1.8.10/libraries/WiFi
exit status 1
no matching function for call to 'PubSubClient::publish(const char [11], String&)'

```

Whats is wrong here ?

# Answer
> 3 votes
What's your last error message?

```
no matching function for call to 'PubSubClient::publish(const char [11], String&)'

```

Read the documentation for the `publish()` method in `PubSubClient`:

> int publish (topic, payload)
>
> Publishes a string message to the specified topic.
>
> Parameters
>
> topic - the topic to publish to (const char\[\])
>
> payload - the message to publish (const char\[\])

Look at the parameters you're using. You're passing a `String` as `payload`. `publish()` expects `payload` to be a `char[]` (essentially the same thing as a `char*`) - a C language string. This is the error you're seeing.

Read the documentation for `String`. How do you get a `char*` from a `String`? The `c_str()` method.

You need to change

```
client.publish("esp32/data", jsonString);

```

to

```
client.publish("esp32/data", jsonString.c_str());

```

As for your other warnings, it looks like your Arduino libraries are a mess with multiple conflicting libraries installed; if you want to get rid of the warnings, clean up your libraries.

---
Tags: esp8266, esp32, json, mqtt
---


# Question
Title: How to set current position for the DC motor to zero + store current positions in an array and run it?
I would like to know how to set the current position for the DC motors to zero and store the current position in an array. after that I would like it to loop in the array to run all steps that was stored in the array?

Am using Genuino UNO board, I have 4 DC motors and each 2 wheels are connected to an H-bridge.

I have an application that have a "save" button and a "Run" button. For the save button, I would like it to set the current position for each wheel to zero first then store the positions of each wheel in an array. For the run button, I would like it to loop in the array that was made by the save button and show the output on each wheels.

basically what am trying to achieve is to make the robotic car that can move any direction I tell it to move in the same time I can control the wheel speed. all that move are being sent via Bluetooth as numbers.

I hope it's clear now

here is my code

```
#include <SoftwareSerial.h>

SoftwareSerial Bluetooth(0, 1); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)

// Define the motors and the pins
// Motor A1

int enA1 = 2;
int in11 = 3;
int in21 = 4;

// Motor B1

int enB1 = 5;
int in31 = 6;
int in41 = 7;

//other H-bridge

// Motor A2

int enA2 = 8;
int in12 = 9;
int in22 = 10;

// Motor B2

int enB2 = 11;
int in32 = 12;
int in42 = 13;

int wheelSpeed = 125;
int dataIn, m;
//lbw left back wheel / lfw left fron wheel / rbw right back wheel / rfw right front wheel
int lbw[50], lfw[50], rbw[50], rfw[50]; // for storing positions/steps
int index = 0;

void setup() {
  // put your setup code here, to run once:

  Bluetooth.begin(9600); // Default baud rate of the Bluetooth module
  Bluetooth.setTimeout(1);
  Serial.print("connected");
  Serial.print("-------------------");
  delay(20);

  pinMode(enA1, OUTPUT);
  pinMode(enB1, OUTPUT);
  pinMode(in11, OUTPUT);
  pinMode(in21, OUTPUT);
  pinMode(in31, OUTPUT);
  pinMode(in41, OUTPUT);
  pinMode(enA2, OUTPUT);
  pinMode(enB2, OUTPUT);
  pinMode(in12, OUTPUT);
  pinMode(in22, OUTPUT);
  pinMode(in32, OUTPUT);
  pinMode(in42, OUTPUT);
}

void loop() {
  // Check for incoming data

 if (Bluetooth.available() > 0) {
    dataIn = Bluetooth.read();  // Read the data

    if (dataIn == 0) {
      m = 0;
    }
    if (dataIn == 1) {
      m = 1;
    }
    if (dataIn == 2) {
      m = 2;
    }
    if (dataIn == 3) {
      m = 3;
    }
    if (dataIn == 4) {
      m = 4;
    }
    if (dataIn == 5) {
      m = 5;
    }
    if (dataIn == 6) {
      m = 6;
    }
    if (dataIn == 7) {
      m = 7;
    }
    if (dataIn == 8) {
      m = 8;

    }
    if (dataIn == 9) {
      m = 9;
    }
    if (dataIn == 10) {
      m = 10;
    }
    if (dataIn == 11) {
      m = 11;
    }

    if (dataIn == 12) {
      m = 12;
    }
    if (dataIn == 14) {
      m = 14;
    }
    // Set speed
    if (dataIn >= 16) {
      wheelSpeed = dataIn * 10;
      Serial.println(wheelSpeed);
    }
  }
  if (m == 4) {
    moveSidewaysLeft();
  }
  if (m == 5) {
    moveSidewaysRight();
  }
  if (m == 2) {
    moveForward();
  }
  if (m == 7) {
    moveBackward();
  }
  if (m == 3) {
    moveRightForward();
  }
  if (m == 1) {
    moveLeftForward();
  }
  if (m == 8) {
    moveRightBackward();
  }
  if (m == 6) {
    moveLeftBackward();
  }
  if (m == 9) {
    rotateLeft();
  }
  if (m == 10) {
    rotateRight();
  }

  if (m == 0) {
    stopMoving();
  }
  //Serial.println(dataIn);
  // If button "SAVE" is pressed
  if (m == 12) {
    if (index == 0) {
        digitalWrite(in11, LOW);
        digitalWrite(in21, LOW);
        digitalWrite(in31, LOW);
        digitalWrite(in41, LOW);
        digitalWrite(in12, LOW);
        digitalWrite(in22, LOW);
        digitalWrite(in32, LOW);
        digitalWrite(in42, LOW);

    }

    // save position into the array
  }
  //if (m == 14) {
   // runSteps();
    //if (dataIn != 14) {
      //stopMoving();
      // Clear the array data to 0
   // }
  //}

}

//method to read the array from what was saved by the save button and run it step by step
//void runSteps() {}

void moveForward() {
        digitalWrite(in11, HIGH);
        digitalWrite(in21, LOW);
        digitalWrite(in31, HIGH);
        digitalWrite(in41, LOW);
        digitalWrite(in12, HIGH);
        digitalWrite(in22, LOW);
        digitalWrite(in32, HIGH);
        digitalWrite(in42, LOW);
        Serial.println("Motor: move Forward");
}

void moveBackward() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, HIGH);
        digitalWrite(in31, LOW);
        digitalWrite(in41, HIGH);
        digitalWrite(in12, LOW);
        digitalWrite(in22, HIGH);
        digitalWrite(in32, LOW);
        digitalWrite(in42, HIGH);
        Serial.println("Motor: move Backward");
}

void moveSidewaysLeft() {
        digitalWrite(in11, HIGH);
        digitalWrite(in21, LOW);
        digitalWrite(in31, LOW);
        digitalWrite(in41, HIGH);
        digitalWrite(in12, LOW);
        digitalWrite(in22, HIGH);
        digitalWrite(in32, HIGH);
        digitalWrite(in42, LOW);
        Serial.println("Motor: move Sideways Left");
}
void moveSidewaysRight() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, HIGH);
        digitalWrite(in31, HIGH);
        digitalWrite(in41, LOW);
        digitalWrite(in12, HIGH);
        digitalWrite(in22, LOW);
        digitalWrite(in32, LOW);
        digitalWrite(in42, HIGH);
        Serial.println("Motor: move Sideways right");
}

void moveRightForward() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, LOW);
        digitalWrite(in31, HIGH);
        digitalWrite(in41, LOW);
        digitalWrite(in12, HIGH);
        digitalWrite(in22, LOW);
        digitalWrite(in32, LOW);
        digitalWrite(in42, LOW);
        Serial.println("Motor: move Right Forward");
}

void moveLeftBackward() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, LOW);
        digitalWrite(in31, LOW);
        digitalWrite(in41, HIGH);
        digitalWrite(in12, LOW);
        digitalWrite(in22, HIGH);
        digitalWrite(in32, LOW);
        digitalWrite(in42, LOW);
        Serial.println("Motor: move left Back ward");
}

void moveLeftForward() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, LOW);
        digitalWrite(in31, LOW);
        digitalWrite(in41, HIGH);
        digitalWrite(in12, LOW);
        digitalWrite(in22, HIGH);
        digitalWrite(in32, LOW);
        digitalWrite(in42, LOW);
        Serial.println("Motor: move Left Forward");
}

void moveRightBackward() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, HIGH);
        digitalWrite(in31, LOW);
        digitalWrite(in41, LOW);
        digitalWrite(in12, LOW);
        digitalWrite(in22, LOW);
        digitalWrite(in32, LOW);
        digitalWrite(in42, HIGH);
        Serial.println("Motor: move Right Backward");
}

void rotateLeft() {
        digitalWrite(in11, HIGH);
        digitalWrite(in21, LOW);
        digitalWrite(in31, LOW);
        digitalWrite(in41, HIGH);
        digitalWrite(in12, HIGH);
        digitalWrite(in22, LOW);
        digitalWrite(in32, LOW);
        digitalWrite(in42, HIGH);
        Serial.println("Motor: rotate Left");
  }

void rotateRight() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, HIGH);
        digitalWrite(in31, HIGH);
        digitalWrite(in41, LOW);
        digitalWrite(in12, LOW);
        digitalWrite(in22, HIGH);
        digitalWrite(in32, HIGH);
        digitalWrite(in42, LOW);
        Serial.println("Motor: rotate Right");
  }

void stopMoving() {
        digitalWrite(in11, LOW);
        digitalWrite(in21, LOW);
        digitalWrite(in31, LOW);
        digitalWrite(in41, LOW);
        digitalWrite(in12, LOW);
        digitalWrite(in22, LOW);
        digitalWrite(in32, LOW);
        digitalWrite(in42, LOW);
        Serial.println("Motor: off");
  }

```

# Answer
As I understood it from your comments, your aim is not really to store the actual positions of the wheels or your robot, but to save and repeat the actions, that the robot did. (Meaning you don't have a "position" here, but only a measurement of wheel speed)

If that is true, then you can save this in a 2-dimensional array with the element form `{speed_wheel_1, speed_wheel2, duration}`. So each action is defined by the speeds of both wheels and the duration of the action, for example:

```
Driving forward at full speed for 3s, turn on the spot to the left with half speed for 1.5s, drive a curve with motor left full speed and motor right half speed for 5s

```

This would translate to the following elements:

```
{100, 100, 3000}
{-50, 50, 1500}
{100, 50, 5000}

```

The speeds have to be read in percent here and the durations in milliseconds.

---

Obviously you are controlling the robot over serial. I don't completely understand your code (also as you didn't show us the full code), so I will give some hints, how you can go on from here:

You are obtaining the speeds from serial into the variable `wheelSpeed`. We cannot see, how you are using this variable later, but you can use it in some way to set the speed fields of a new array element.

Then you need the duration. The Arduino framework has a function for that: `millis()`. It will return the number of milliseconds since the startup, much like a clock. When an action starts (when the corresponding serial command is received), you have to set a timestamp:

```
unsigned long timestamp;
...
timestamp = millis();

```

When the action ends (either because it actually only had a limited duration, or because another command is received), you calculate the difference between the current millis value and the timestamp. This is the duration.

So the corresponding code parts will look like this:

```
unsigned long timestamp = 0; // Define timestamp at global scope
unsigned int current_element = 0; // A variable to keep track of the current array element
int actions[10][3]; // Array to hold up to 10 actions

void start_action(byte speed_left, byte speed_right){
    actions[current_element][0] = speed_left;
    actions[current_element][1] = speed_right;
    timestamp = millis();
    // Start the action with the provided speeds here
}

void end_action(unsigned int element_index){
    actions[current_element][2] = millis() - timestamp;
    current_element++;
    if(current_element >= 10){
        // Do something to prevent more actions. Maybe just disable recording.
}

```

For repeating the actions, you just have to cycle over the array and set the corresponding speeds for the corresponding time.

If you want to go fancy, you can ditch the 2-dimensional array and instead define a struct for an action:

```
struct Action{
    int speed_left;
    int speed_right;
    unsigned long duration;
};

```

Then you can create a simple array of the `Action` objects and reference the fields by name:

```
Action actions[10];
...
actions[1].duration = millis() - timestamp;

```
> 1 votes

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


# Question
Title: How to choose SDA/SCL pair on Arduino Due?
On Arduino Due, there are two pairs of SDA/SCL pins that I can use for I2C. There is SDA0 and SCL0 at, respectively, pins 20 and 21 and another near AREF. How do I choose which one of them I use? I also read that pins 20 and 21 have built-in pull-up resistors, is that true?

# Answer
> 3 votes
Pins 20 and 21 are the default I2C pins. A lot of libraries assume you use these, and would require some extra work to get working with SDA1/SCL1.

They also have their pullup resistors already present on the board of the Due (see schematic).

So just use pins 20 and 21, unless you have a good reason to use the other.

# Answer
> 2 votes
How to choose SDA/SCL pain on due from software. wire.h has two instances of TwoWire i.e. Wire and Wire1.

Wire uses

```
#define PIN_WIRE_SDA         (20u)
#define PIN_WIRE_SCL         (21u)

```

and Wire1

```
#define PIN_WIRE1_SDA        (70u)
#define PIN_WIRE1_SCL        (71u)

```

observe which instance is used by your library e.g.

```
#define WIRE Wire1 or #define WIRE Wire

```

if library is using Wire then its default i2c at pin 20 and 21.

if library is using Wire1 then its i2c at pin 70 and 71 near AREF.

make changes accordingly. if you want to use default i2c use "Wire" instance or if you want to use i2c near AREF use "Wire1".

most important don't forget to modify Wire1.begin() or Wire.begin() accordingly.

as mentioned in earlier comment second i2c (pin 70 and 71 near AREF) doesn't have pullup resistor handle it while using second i2c.

---
Tags: i2c, arduino-due
---