title: easy_install pip on Arduino Yun fails

text:
# Question
Title: easy_install pip on Arduino Yun fails
I want to install `pip` on the Yún which is running **Linino OS** but every time I execute the standard steps for `opkg` i.e.

```
# opkg update
# opkg install distribute
# okpg install python-openssl
# easy_install pip

```

**Error**

```
Searching for pip
Reading http://pypi.python.org/simple/pip/
Couldn't find index page for 'pip' (maybe misspelled?)
Scanning index of all packages (this may take a while)
Reading http://pypi.python.org/simple/
No local packages or download links found for pip
error: Could not find suitable distribution for Requirement.parse('pip')

```

What is the reason behind this?

**Kernel Information**

```
Linux Arduino 3.3.8 #1 Fri Nov 14 08:57:34 CET 2014 mips GNU/Linux

```

# Answer
Found this Arduino Forum Thread helpful.

```
# wget \
https://pypi.python.org/packages/source/p/pip/pip-6.0.8.tar.gz#md5=2332e6f97e75ded3bddde0ced01dbda3\
  --no-check-certificate
# easy_install pip-6.0.8.tar.gz

```

Apparently the PyPi Package Site is now **HTTPS** and hence `--no-check-certificate` option should be used. Also **MD5 Checksum** of the package needs to attached in the link in order to avoid a **HTTP 404 Error**
> 3 votes

# Answer
Try:

```
sudo wget https://pypi.python.org/simple/pip/pip-6.0.8.tar.gz
sudo tar xzvf pip-6.0.8.tar.gz
cd pip-6.0.8
python setup.py

```
> 0 votes

# Answer
Try to use:`opkg update` `opkg install python-pip`

# or python-pip3
> -1 votes

---
Tags: arduino-yun, python, linux
---


# Question
Title: How to execute commands over desired amount of time
I have a program that receives 4 commands on 4 channels to change the color of an LED using mqtt communication. Lets just focus on two of the channels, the time and the red.

I am sending a length of time that I would like to complete the color change by, and a new color value.

I have ran my test runs to calculate the amount of time it seems to take to update a single value. I calculate this by setting the intervalRed value to 0.01 with a duty cycle of 1024, commanding the led to go from its starting value to its ending value of fully on, by the interval value would be 10,240 ticks. when I send that command, take the resulting execution time ( 287ms ) and calculate the time to update a single tick I get a value of 0.028027 ms to complete a single increment. When I set the hardcoded tickTime to that value: 0.028027 and I send a color change from off to on/vice-versa with a requested completion time of 1000ms, the actual execution time varies.

the larger the requested execution time varies, causes a greater difference between the actual and requested time.

I ran many test trials with a set interval to gain a value for the length of time for a single tick but no matter when value I use, there are still discrepancies. I dont believe using a hardcoded value for the length of time for a single tick is the correct way to assure the color change will occur over a given time.

I am happy to provide the terminal output for any attempts to show the output of values used in my calculations if needed (But I believe I need a difference approach all together)

What is the best way to assure the color change completes in the requested amount of time? Perhaps some calculation based on the amount of time passed rather then calculating a hardcoded value for the time of a single tick?

```
    #include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define CLIENT_NAME "ESP8266_1" // just a name to identify this client
WiFiClient wifiClient;
PubSubClient mqttClient("10.0.0.131", 1883, wifiClient);

//set rgb led pins
int pinGreen = 4;
int pinBlue = 12;
int pinRed = 14;

float currentRed = 1024;
float currentGreen = 1024;
float currentBlue = 1024;

int nextRed = -1;
int nextGreen = -1;
int nextBlue = -1;

float intervalRed = -1;
float intervalGreen = -1;
float intervalBlue = -1;

//the float time was calculated by
//IntervalValue(set to 0.01)/Value Change (1024 when going from on to off) = 10,240 ticks
//ExecutionTime (beginning time - end time) /# of ticks = 0.0347643
// I seem to be getting varying execution times so I have tried values between 0.028 and 0.04
float tickTime = 0.028027;
int executionTime = 1;
int showTime = 1;
int beginningReceivedData;

void setup()
{
  Serial.begin(9600);
  //set rgb led pins to output

  pinMode(pinRed, OUTPUT);
  pinMode(pinGreen, OUTPUT);
  pinMode(pinBlue, OUTPUT);
  digitalWrite(pinRed, HIGH);
  digitalWrite(pinGreen, HIGH);
  digitalWrite(pinBlue, HIGH);

  mqttClient.setCallback(callback);
  WiFi.begin("partyHouse", "whatsthepassword");
  connectToWiFiAndBroker();
}

void connectToWiFiAndBroker()
{
  Serial.print("\nConnecting to WIFI");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("Connected to WIFI!");

  Serial.println("Connecting to broker");
  while (!mqttClient.connect(CLIENT_NAME))
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("Connected to broker!");

  mqttClient.subscribe("InterestingTopics/#");
}

void loop()
{
  if (!mqttClient.connected()) {
    connectToWiFiAndBroker();
  }
  mqttClient.loop();

  updateColors();
}
//------------------------------------------------------------------------------------------------------------------------
//The CallBack for processing incoming data
//------------------------------------------------------------------------------------------------------------------------
//the topic is the path based on the subscription
void callback(char* topic, byte* payload, unsigned int length)
{
  //for tracking the time it takes to process the data, as well as the time it takes to complete updating the colors over the desired time
  beginningReceivedData = millis();
  char commandValue[length+1];
  for (int i = 0; i < length; i++)
  {
    commandValue[i] = (char)payload[i];
  }
  commandValue[length+1] = '\0';
  if (strcmp(topic, "InterestingTopics/time") == 0) {
    executionTime = atoi(commandValue);
  }
  if (strcmp(topic, "InterestingTopics/red") == 0) {
    showTime = 1;
    nextRed = atoi(commandValue);
    intervalRed = (nextRed - currentRed)/(executionTime/tickTime);
    //manual Interval value used for calculating the tickTime
    if (nextRed < currentRed) {
      intervalRed = -0.1;
    } else {
      intervalRed = 0.1;
    }

    Serial.print("next: ");
    Serial.print(nextRed);
    Serial.print(" Current: ");
    Serial.print(currentRed);
    Serial.print(" Interval: ");
    Serial.println(intervalRed, 10);

    Serial.print("time to process incoming single value (red): ");
    Serial.println(millis() - beginningReceivedData);
  }
  if (strcmp(topic, "InterestingTopics/green") == 0) {
    nextGreen = atoi(commandValue);
    intervalGreen = (nextGreen - currentGreen)/(executionTime/tickTime);
  }
  if (strcmp(topic, "InterestingTopics/blue") == 0) {
    nextBlue = atoi(commandValue);
    intervalBlue = (nextBlue - currentBlue)/(executionTime/tickTime);
  }
}

void updateColors() {
  //------------------------------------------------------------------------------------------------------------------------
  //Updating the Red
  //------------------------------------------------------------------------------------------------------------------------
  if (currentRed != nextRed && nextRed > -1) {
    currentRed = currentRed + intervalRed;
    //if value decreasing and it passes the next value, set values equal to prevent passing
    if (intervalRed < 0 && currentRed < nextRed) {
      currentRed = nextRed;
    }
    if (intervalRed > 0 && currentRed > nextRed) {
      currentRed = nextRed;
    }
    analogWrite(pinRed, (int)currentRed);
    //this else exists just to print the different in time from receiving the value to the time it took to update
  } else if (currentRed == nextRed && nextRed > -1 && showTime == 1) {
    //showTime set to zero to only print the time once
    showTime = 0;
    Serial.print("full color change has completed taking this much time: ");
    Serial.println(millis() - beginningReceivedData);
  }
  //------------------------------------------------------------------------------------------------------------------------
  if (currentGreen != nextGreen && nextGreen > -1) {
    currentGreen = currentGreen + intervalGreen;
    //if value decreasing and it passes the next value, set values equal to prevent passing
    if (intervalGreen < 0 && currentGreen < nextGreen) {
      currentGreen = nextGreen;
    }
    if (intervalGreen > 0 && currentGreen > nextGreen) {
      currentGreen = nextGreen;
    }
    analogWrite(pinGreen, (int)currentGreen);
  }
  if (currentBlue != nextBlue  && nextBlue > -1) {
    currentBlue = currentBlue + intervalBlue;
    //if value decreasing and it passes the next value, set values equal to prevent passing
    if (intervalBlue < 0 && currentBlue < nextBlue) {
      currentBlue = nextBlue;
    }
    if (intervalBlue > 0 && currentBlue > nextBlue) {
      currentBlue = nextBlue;
    }
    analogWrite(pinBlue, (int)currentBlue);
  }
}

```

# Answer
Don't assume an update takes a fixed time and blast constant changes. Write code that calculates change/millisecond. Then record the starting millis() value when you begin a sequence, and each time through your loop, calculate `float(millis()-startTime)/sequenceTime`. That will give you the % of color change to apply now. Then use that percentage to calculate the interpolated color value.

That will give you an adaptive system that will set the color value to the approximate desired color for the current stage in your animation, regardless of how long each iteration the loop takes. If the loop lags for some reason, you will get more coarse changes between color values, but it will still track your desired pacing.
> 1 votes

---
Tags: time, millis, mqtt, calculation
---


# Question
Title: How to connect Big Dome Button with arduino
I am quite new to arduino and for a project I want to use big dome button which when pressed it will count how many times has been pressed.It is using 12 volts.The button is this https://www.sparkfun.com/products/9181

# Answer
As others have said, the 12V powers the switch's internal LED.

---

## EDIT:

Switches don't need power. If you skip **all** power to the switch it will still work but it won't light up.

## End of edit:

---

If you want the switch to light up, connect the V in to 12V, or if you connect it to 5V, it will be dim, but -probably- still light. (You are certain to have a 5V pin on your Arduino board. Using that means you don't need a separate 5V supply.)

Now connect one lead of the switch to a digital input, and the other lead to ground.

Then set your switch pin to `INPUT_PULLUP` mode. Now your switch will read HIGH until it's pressed, then it will read LOW.

create a variable at the top of your code called buttonState:

```
byte buttonState = HIGH;

```

Also define an unsigned long variable nextReadMillis:

```
unsigned long nextReadMillis = 0;

```

and a pressCount variable:

```
unsigned int pressCount = 0;

```

And define a debounceTime:

```
#define debounceTime 50

```

In your loop, do something like this:

```
void loop() {
    //Get the new millis(value)
    unsigned long newMillis = millis();

    //only look at the new button value if enough time has elapsed.
    if (newMillis >= nextReadMillis) {
       byte newButtonState = digitalRead(buttonPin);

       //Only do something if the button state has changed
       if (buttonState != newButtonState) {
          buttonState = newButtonState;
          nextReadMillis = newMillis + debounceTime;
          //If the button is now in the pressed (LOW) state, increment the count
          if (buttonState == LOW) {
              pressCount++;
          }
       }
    }
}

```

That's pseudo-code. It likely has syntax errors. It's not meant to be copy/pasted. Use it as a guide for your project.

The code using `millis()` is a version of "software debouncing." Electrical switches tend to "jitter" or "bounce" between their on and off states very rapidly when they are first pressed/released. By only checking for state changes after a brief delay, you ignore the jitter in the readings.

Note that if you want your LED to only light when the button is pressed, you could control it with another digital pin. You'd assign a different pin to controlling the LED output, set that pin to OUTPUT mode, and switch the pin based on button state inside the body of the `if (buttonState != newButtonState)` if statement.

If your LED draws ≤20mA at 5V, you could connect it directly to your output pin. If it draws more than that, you will need a transistor to drive it so you don't draw too much current from your output pin and burn it out. Wiring a transistor driver is beyond the scope of this post however.
> 1 votes

---
Tags: arduino-uno, button
---


# Question
Title: How to prevent counter increment when holding the button
I am a newbie and also a noobie. Kindly assist this poor boy over here. I am looking for a way to increment a variable by one each time a button is pressed. Current approach is the following :

```
void buttonLoop() {
  int win = 0;
  while (win ==0) {
  display.setCursor(0, 0);
  //getButtons() function can be used to test if any button is pressed, or used like:
  //getButtons(TSButtonUpperLeft) to test a particular button, or even like:
  //getButtons(TSButtonUpperLeft|TSButtonUpperRight) to test multiple buttons
  //results are flipped as you would expect when setFlip(true)
  if (display.getButtons(TSButtonUpperLeft)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
  display.setCursor(0, 54);
  if (display.getButtons(TSButtonLowerLeft)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
  display.setCursor(95 - display.getPrintWidth("Pressed!"), 0);
  if (display.getButtons(TSButtonUpperRight)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
  display.setCursor(95 - display.getPrintWidth("Pressed!"), 54);
  if (display.getButtons(TSButtonLowerRight)) {
    display.println("Pressed!");
    score++;
    updateScore();
  } else {
    display.println("          ");
  }
}
}

```

In my case, the counter will keep increasing if I do not let go of the button. How do I make it so that the counter will only increase by 1 even if i continue holding onto the button.

Thank you for all the kind souls in this society :)

# Answer
See my answer in this thread:

How to connect Big Dome Button with arduino

That thread explains how to wire up a switch and write code that increments a counter each time a button is pressed.

The bits you care about:

Connect one lead of the switch to a digital input, and the other lead to ground.

Then set your switch pin to `INPUT_PULLUP` mode. Now your switch will read HIGH until it's pressed, then it will read LOW.

create a variable at the top of your code called buttonState:

```
byte buttonState = HIGH;

```

Also define an unsigned long variable nextReadMillis:

```
unsigned long nextReadMillis = 0;

```

and a pressCount variable:

```
unsigned int pressCount = 0;

```

And define a debounceTime:

```
#define debounceTime 50

```

In your loop, do something like this:

```
void loop() {
    //Get the new millis(value)
    unsigned long newMillis = millis();

    //only look at the new button value if enough time has elapsed.
    if (newMillis >= nextReadMillis) {
       byte newButtonState = digitalRead(buttonPin);

       //Only do something if the button state has changed
       if (buttonState != newButtonState) {
          buttonState = newButtonState;
          nextReadMillis = newMillis + debounceTime;
          //If the button is now in the pressed (LOW) state, increment the count
          if (buttonState == LOW) {
              pressCount++;
          }
       }
    }
}

```

That's pseudo-code. It likely has syntax errors. It's not meant to be copy/pasted. Use it as a guide for your project.

The code using `millis()` is a version of "software debouncing." Electrical switches tend to "jitter" or "bounce" between their on and off states very rapidly when they are first pressed/released. By only checking for state changes after a brief delay, you ignore the jitter in the readings.

You can adjust the value of debounceTime up or down a little. A value of 50 is 1/20th of a second, which should make your button presses quite responsive, but still debounce the switch well. If you find your count sometimes increases by more than one for a button press, you can increase the value to 100 or even 500, although at 500 (1/2 second) the button won't respond to really rapid presses
> 0 votes

---
Tags: arduino-ide
---


title: Position Feedback for Stepper Motor

text:
# Question
Title: Position Feedback for Stepper Motor
I want to rotate a gearwheel with a stepper motor. While Arduino is on everything is well.

My gearwheel transfer its power to a gear worm. The worm will go 10th cm and back repeatedly. When I cut the power, Stepper Motor stops where its last step and position. When the power is on Stepper starts from last position but steps starts from the first step.

Assume that 2038 steps are rotating the Motor one revolution. For example, when 1500 step pass and power cut. Worm is on 6th cm now. And the power is on. Stepper is working from 6th cm and is going 2038 steps. Now it is on 16th cm.

If I use servo, when the power is on, I can write the motor to the 0 position. But I have to use stepper motor. How can I fix this?

Stepper Motor: 28 BYJ 48 Driver: ULN2003A

The cod is here;

```
int State;
int Wait;

void setup() {

  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);

  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
  digitalWrite(11,LOW);
  State = 8;
  Wait = 2;
}

void loop() {

  turnRight(2038);
  delay(1000);
  turnLeft(2038);
  delay(1000);

  }

void turnRight(int Step) {
    for (int i = 0; i < Step ; i++){
      digitalWrite(State,HIGH);
      delay(Wait);
      digitalWrite(State,LOW);
      IncreaseState();
    }
}

void IncreaseState() {
  State++;
  if (State==12){
    State=8;
  }
}

void turnLeft(int Step) {
for (int i = 0; i < Step ; i++){
      digitalWrite(State,HIGH);
      delay(Wait);
      digitalWrite(State,LOW);
      DecreaseState();
    }

}

void DecreaseState() {
  State--;
  if(State==7){
    State=11;
  }
}

```

# Answer
> 1 votes
There are multiple ways to to this. The easiest and most commonly used way is to use a limit switch as home position sensor. At startup the device will first drive the motor in the direction of the limit switch, until the switch get's activated. Now the the absolute position on this axis is known and you can go on from there. (CNC machines and 3D printers mostly work that way. Often they retract again from the limit switch and approach the switch again with less speed, to increase the accuracy). For this you just need a micro switch on the axis and connect it to one input pin. In `setup()` you are driving the stepper motor in the direction of the limit switch, until it gets activated. Then you are on position zero and can go on with your sketch.

A more difficult way is to introduce a measurement of position into your device. A servo incorporates a potentiometer connected to the axis. By measuring the voltage on this potentiometer (it is basically a voltage divider), the servos electronics can always know, where it currently is. There are also fader potentiometers, where you don't rotate a knob, but you slide a fader over a linear rail. You might find a fader potentiometer, that fits your scale (10cm is not that much, there might be some).

Or you could save the current position to a non-volatile memory (like EEPROM) and retrieve it, when you start up. But since a power-cut during writing of the position may corrupt the data, you would have to go a more complex way. Something like sensing, that the power was cut, providing the Arduino with power through a big capacitor, so that, when it senses power loss, it still has enough time to write the current position to a non-volatile memory. (This is also better for the EEPROM, than continuously writing to it, since EEPROM has limited write cycles).

All in all I would suggest using the first mentioned method (limit switch). It is used in many devices for a reason. Though it depends on your exact project requirements.

# Answer
> 1 votes
Another answer chrism didn't mention is to use an "absolute position rotary encoder". It's a device that outputs a bit pattern using "gray code" or "grays binary" that tells you the position of the shaft. The more bits in the encoder, the more precisely you can measure the position. The "gray code" bit pattern enables you to read the changing position without false reading due to contact/sensor bounce.

However, if you want to uniquely detect 2038 separate steps you'd need a 12 bit rotary encoder, which would be a little expensive and take a lot of interface pins.

---
Tags: motor, servo, stepper
---


# Question
Title: How to program Arduino LCD shield with Python?
so I want to run a Arduino LCD shield with Python code..But after having some research on the Internet, I can not found any tutorial, some just give some basic code with LED.

And one things that how can I add a LCD library (LyquidCrystal.h in Arduino code) if i program in Python.

Thank you guys very much.

# Answer
It's like @chrisl wrote in the comments. You cannot program Arduino with python.

You can however upload an open source Firmata protocol implementation onto the Arduino and then write python code on your PC that will send commands to the Arduino by USB cable to tell it what to do.

This way you actually execute your code on PC, but control Arduino pins. Only drawback is that you need to have a PC connected to the Arduino at all times. This is not very practical.

There is a really nice tutorial here

Example python code looks like this:

```
import pyfirmata
import time

board = pyfirmata.Arduino('/dev/ttyACM0')
while True:
    board.digital[13].write(1)
    time.sleep(1)
    board.digital[13].write(0)
    time.sleep(1)

```

I'm afraid that only solution to controlling LCD shield this way without writing any C is to write the entire LCD library in python basing on pyfirmata calls to control the Arduino pins. It's not as hard as it sounds, and even a beginner could easily succeed.
> 1 votes

---
Tags: arduino-uno, lcd, python
---


# Question
Title: How to retrieve a page from a web-server using ESP8266 with the program running on Arduino instead of the ESP module?
I have connected an ESP8266-01 module to an Arduino as in the following schematic with the RX and TX pins changed to pins 8 and 9 instead of 0 and 1:

I am using the ESP8266wifi library at the following link:

https://github.com/ekstrand/ESP8266wifi

I have looked at the ESP8266HTTPClient library but that is for the ESP8266 board. **I want my code to run on the Arduino Uno and not on the ESP8266!** I have written the following code:

```
#include <SoftwareSerial.h>
#include <SerialESP8266wifi.h>

const String API_PASSWORD = "stn1234";

#define RX_PIN          8   // RX of Arduino (connected to TX of ESP8266)
#define TX_PIN          9   // TX of Arduino (connected to RX of ESP8266)
#define ESP_RESET_PIN   12

#define SERVER_IP           "192.168.43.234"
#define SERVER_PORT         "80"
#define WIFI_SSID           "MyWIFI"
#define WIFI_PASSWORD       "myWifiPassword"

uint8_t wifi_started = false;

const char RST[] PROGMEM = "RST";
const char IDN[] PROGMEM = "*IDN?";

#define CHANGE_DELAY        5000

void initializeWifi();
void transmitData(String);
String getResponse();
void transmitStatus();

SoftwareSerial swSerial =  SoftwareSerial(RX_PIN, TX_PIN);
SerialESP8266wifi wifi(swSerial, swSerial, ESP_RESET_PIN, Serial);

void setup()
{
    Serial.begin(9600);
    Serial.println("Initializing...");
    initializeWifi();
    Serial.println("Initialization complete");
}

void loop()
{
    transmitStatus();
    Serial.print("Transmission complete, ");
    int s = (CHANGE_DELAY/1000);
    Serial.print(s);
    Serial.println("s until next cycle");
    delay(CHANGE_DELAY);
}

void transmitStatus()
{
    int a = (int)random(100);
    int b = (int)random(100);
    String url = "/LocalWebProject/api/testConnection.php?a=" + String(a) + "&b=" + String(b);

    transmitData(url);
    String response = getResponse();
    Serial.print("Reply received: ");
    Serial.println(response);
}

void initializeWifi()
{
    swSerial.begin(115200);
    Serial.println("Starting Wifi");
    wifi.setTransportToTCP();
    wifi.endSendWithNewline(false);     // Will end all transmissions with a newline and carrage return ie println.. default is true

    wifi_started = wifi.begin();
    if(wifi_started)
    {
        Serial.println("Wifi started, connecting to AP...");
        wifi.connectToAP(WIFI_SSID, WIFI_PASSWORD);
        Serial.println("Connected to AP");
    } else {
        Serial.println("ESP module not working");
    }
}

void transmitData(String url)
{
    Serial.println("Connecting to server...");
    wifi.connectToServer(SERVER_IP, SERVER_PORT);

    String data = String("GET ") + url + " HTTP/1.1\r\n" +
           "Host: " + wifi.getIP() + "\r\n" +
           "Connection: close\r\n\r\n";

    Serial.println("Connected. Transmitting data...");
    wifi.send(SERVER, data);
}

String getResponse()
{
    while(1)
    {
        Serial.println("Waiting for response...");
        WifiMessage in = wifi.listenForIncomingMessage(6000);
        if(in.hasData)
        {
            if(in.channel == SERVER)
            {
                Serial.print("Reply received from the server: ");
                Serial.println(in.message);
                return in.message;
            }
        }

        delay(1000);
        Serial.print("Retrying, ");
    }
}

```

I have an Apache server running on Ubuntu 18.10 with a PHP project running on port 80. The testConnection.php page takes 2 GET parameters (integers) and returns the sum.

Problem: It says that ESP module is not working. The AP in my case is a local hotspot on my mobile.

I have tried running the given example "SerialESP8266\_library\_test" and confusingly enough, it prints that it has successfully connected to my AP, but on my phone I do not see it connected. Only 1 device is visible as connected, which is my laptop which is running the Apache server and the web project. Also connectToAP returns 1, and connectToServer returns 0.

What am I doing wrong? I know that the ESP module requires power and the Arduino 3V3 is insufficient but I am just testing the code right now and I will do the required changes later on. Due to this, I am placing my Android phone just beside the ESP module so that it has no problems connecting to it.

Any help would be greatly appreciated! Thanks in advance.

# Answer
> 0 votes
Finally it is working by setting baud rate to 9600 and shortening the GET URL. Maybe there is a length restriction in the library.

---
Tags: esp8266
---


# Question
Title: Why are embedded C codes are ending with "while(1)"?
I always see while(1); at the end of the C codes such as:

```
#include <stdio.h>

int main(void)
{

    //Some code here...

    while(1);

}

```

If I'm not wrong that it always exists, what is the function of that?

edit:

```
#include <stdio.h>

int main(void)
{

     while(1);
    //Some code here...

}

```

# Answer
It's because in non-embedded systems, when `main()` finishes it returns to the operating system and the program is removed from memory. In embedded systems there's no operating system to return to, and the program can't be removed from memory. So... what do you do when the program is finished? Simple: you do nothing. Forever. And that's what `while(1);` does.

Some compilers and C libraries automatically add `while(1);` in the `exit()` routine, but not all do - so it's better to do it explicitly than rely on something that may or may not be there.
> 2 votes

# Answer
```
while(1);

```

should actually be read as

```
while(true)
{
  // No statements
}

// Statements following here will never be executed

```

The result is: while the condition is true, it performs no statements. Since the condition `true` is always true, it keeps performing the statements within the { and }, which are no statements, resulting that no statement is executed but it will also not executing statements after the while.
> 0 votes

# Answer
The line while(1) in a C program creates an infinite loop- this is a loop that never stops executing. It executes over and over and over again, unless the program is intentionally stopped or there is some condition under this loop that gets met that takes the program out of this infinite loop.

Let's take the following C program.

include

void main() { printf("Hello World"); while(1); }

This program prints the words "Hello World" to the standard output, which is most likely a serial port.

After it prints it, it goes to execute the next line, while(1). This line makes the microcontroller sit and wait, forever or until the microcontroller is reset.
> 0 votes

---
Tags: avr
---


title: Why NRF24L01+ pipe has 5 byte address

text:
# Question
Title: Why NRF24L01+ pipe has 5 byte address
I am studying NRF24L01+ module. I see, that only 6 receivers can be connected with the transmitter, via their unique pipes. What I can’t get is why the pipe id (address) has 5 long bytes.

As to me,1 byte would be much more than enough. What is the purpose in 5-byte address in 5 bidirectional communications?

# Answer
5 bytes = more than 1 million million unique addresses, although not all addresses (as the nRF24L01 datasheet points out) are advised, for instance because they mimic the nRF's preamble packet.

**So what is the purpose of addresses?**
The purpose is to ensure that radio transmissions are received at the intended radio module. Consider a radio network where you have 1 transmitter (TX) and 3 receivers (RXs) within range of one another, all using the same radio frequency (channel). Now all receivers will detect a message sent by the transmitter, but only act upon it, such as raising an interrupt flag, it if the TX and RX addresses match. To avoid chaotic communication, failed packets or on-air collisions you need each receiver to have a unique address. Consider these like a postal address. You should have an intuition of what would happen to your mail if both you and your neighbor had the exact same address. Since the 2.4 GHz band can be extremely busy in public places with WiFi and Bluetooth traffic (which as an aside, Bluetooth is based on the nRF protocol), having 40 address bits seems quite sensible, as the probability of matching addresses by chance is almost zero.

**So what are pipes?**
If you read the nRF datasheet, you will see that in TX mode the radio can only send on using one address. In RX mode, the radio will listen for messages on up to 6 different addresses. Why 6? This is likely arbitrary - a balance between register memory allocation, most probable number of nRF modules being used simultaneously and the likelihood of more efficient network topologies (such as star/tree networks) that do not require huge numbers of pipes. A pipe represents one of these 6 addresses that a radio can receive the message and send and an ACK packet if requested. That's all.

I hope this answer clears any confusion you had between nRF addresses and pipes.
> 2 votes

# Answer
> I see, that only 6 receivers can be connected with the transmitter,

That depends on how you define "connected". It is only possible for one transmitter to, at any one time, send data to up to 6 other devices (one per pipe). However, that is something that is very rarely done.

In practice no more than 2 pipes are needed for you to communicate with thousands of devices.

In general:

* Pipe 0 is the pipe you send data on
* Pipe 1 is the pipe you listen for incoming data on

You should always send on pipe 0 because that is the pipe that any ACK messages will be received on (set pipe 0's address to the address you are sending to).

With pipe 1 set to the receive address you are always ready to receive data from elsewhere.

The transmitter doesn't need to know about *every* other device - only the one device it is sending data to at any one moment in time.

You can set up multiple addresses on other pipes if you want to receive data that is being sent *to* different addresses, though there's not many circumstances where you'd want to do that (such as if you want to communicate with different pipe widths to different groups of nodes, effectively bridging between two separate networks).

In summary:

* Pipe 0's address changes all the time depending on who you are *sending* to (assuming you are using Auto ACK)
* Pipe 1's address is static and is *your* address that you will receive on.

To illustrate it more:

* Node A has address "NODEA".
* Node B has address "NODEB".
* Node C has address "NODEC".

---

* Node A has pipe 1 address set to "NODEA".
* Node B has pipe 1 address set to "NODEB".
* Node C has pipe 1 address set to "NODEC".

---

* Node A sets pipe 0 address to "NODEC"
* Node A sends a packet through pipe 0
* Node C receives the packet on pipe 1 since it's addressed to "NODEC"
* Node C responds with an ACK to its own address ("NODEC")
* Node A receives the ACK on pipe 0 since it's address is "NODEC".

---

* Node A sets pipe 0 address to "NODEB"
* Node A sends a packet through pipe 0
* Node B receives the packet on pipe 1 since it's addressed to "NODEB"
* Node B responds with an ACK to its own address ("NODEB")
* Node A receives the ACK on pipe 0 since it's address is "NODEB".

---
> 0 votes

---
Tags: nrf24l01+
---


# Question
Title: Will an Arduino UNO operating at 16mHz communicate with UART / I2C with an STM32 operating at a different frequency?
I plan to connect Arduino UNO via I2C / UART with a controller based on STM32F334K8T6, whose frequency will be about 20mHz or higher.

Tell me, does the difference in clock frequencies of microcontrollers affect the operation of buses between them?

The tire speed will be equal. (UART 115200 Baud / I2C 100kHz)

# Answer
> Tell me, does the difference in clock frequencies of microcontrollers affect the operation of buses between them?

No it doesn't. Or not much any way. It may affect the *accuracy* of clock generation1, which may have an affect at very high asynchronous baud rates, but other than that, no.

For synchronous communication it's all synchronised to the communication protocol's clock, so processor clocks are irrelevant.

---

1: Baud rates are usually generated as an integer division of the system clock. Different system clocks give different results for baud rate divisor calculations, yielding marginally different baud rates. Different baud rates will have different *error percentages* on different system clocks. At low speeds this has no noticeable affect. At high speeds (millions of bits per second) it can cause errors to creep in.
> 3 votes

---
Tags: arduino-uno, frequency
---


title: Understanding analog pins in pinMode

text:
# Question
Title: Understanding analog pins in pinMode
When passing the pin number in pinMode its possible to use A0 - A7, does it apply only to that methode? How can pinMode expect a number (is it int?) type in case of digital pin another (is it then string?) in case of analog pin? I want to use that in my class methode, is there a way to use that and have my code more readable or should I use the pin numbers? P.S. I have tried to read the source code but I don't understand the uin8\_t (I know its a byte, but not how it can understand A5 as an int)

Tnx a lot

# Answer
> 1 votes
pinMode is actually declared as `void pinMode(uint8_t, uint8_t);` in arduino.h

A0 is a defined as a number (somewhere depending on the actual hardware), on an Uno/Nano it translates to 14, and when executing pinMode it translates to the appopriate bit in the correct DDRx register.

---
Tags: pins
---


# Question
Title: 4:1: error: expected initializer before 'void'
```
int button

void setup()
{
 pinMode(13, OUTPUT);
 pinMode(12, OUTPUT);
 button 4;
 pinMode(4=INPUT);
}

void loop()
{
  if(digitalRead(4)== LOW);
  {
  digitalWrite (13, HIGH);
  delay (250);
  digitalWrite (13, LOW);
  digitalWrite (12, HIGH);
  delay (250);
  digitalWrite (12, LOW);
  }
 }

```

# Answer
There's significant syntax errors in your code. I think I've caught them all.

```
   //int button;

   void setup() {
     pinMode(13, OUTPUT);
     pinMode(12, OUTPUT);
     // button 4;
     pinMode(4, INPUT);
   }

   void loop() {
     if (digitalRead(4) == LOW) {
       digitalWrite (13, HIGH);
       delay (250);
       digitalWrite (13, LOW);
       digitalWrite (12, HIGH);
       delay (250);
       digitalWrite (12, LOW);
     }
   }

```
> 0 votes

---
Tags: arduino-uno, pins, button, error
---


title: srd-05vdc-sl-c and coil operating time

text:
# Question
Title: srd-05vdc-sl-c and coil operating time
I'm using Arduino UNO to control an imatic relay board with 16 relays model srd-05vdc-sl-c. I use all the relays to control some linear actuators and everything is working fine.

My only question is: are the coils used for these relays for **continuous** use? I mean, can I continue to give power to some coils for more than 30 minutes? Or will they be destroyed? Should I write a specific Arduino routine to power off all the coils when not used, or can I leave them powered for 30 or more minutes?

I checked the relays and they do not overheat.

# Answer
You can leave them energized for more than 30 minutes. My 16 year old car with 250,000 km still has the original fuel pump relay. I can't imagine how many hours of continuous use it received over this period of time. The relay in my car is not the same make / model as the relays you are using, so you should check with the manufacture to see if there is a "service lifetime" specification.
> 1 votes

---
Tags: relay
---


# Question
Title: Gas Sensor output voltage to concentration
I am using figaro tgs gas sensor (2600, 2602 and 2620) to sense breath from human. What I obtained is the output voltage. However, I would like to convert the voltage to concentration in ppm? Since these gas sensors can sense more than one gas. Is there any way?? Thanks.

# Answer
> 1 votes
> I would like to convert the voltage to concentration in ppm?
>
> Is there any way??

the datasheet for those devices would have the answers for you. Generally, you read the datasheet BEFORE deciding on using them or not. not that otherway around.

# Answer
> 1 votes
This is one of the datasheet. I have calibrated it using the clean air factor in datasheet and got the Rs/R0 ratio. However, from there, I not sure how to find the concentration for each gas.

# Answer
> 0 votes
If you want to measure concentrations of individual gases you would have to separate them and detect them separately using a chromatography column. In the case of gases this is known as gas chromatography (GC) and for liquids it's LC, with the most popular one being HPLC (high performance liquid chromatography, or sometimes called high pressure liquid chromatography). This is actually a really fun thing to do as a project and I stumbled on this question because I want to make my own GC using the sensor you mentioned.

The principle is fairly simple. Most modern GCs have a carrier gas, usually an inert gas like nitrogen or helium, at a steady flow rate and it passes through a column. You inject your sample into this carrier gas flow and then your sample also passes through that column. Most columns are packed with a material like silica gel or long alkanes (usually around 18 carbon atoms). Silica has more affinity for polar compounds (like alcohols) while alkanes have more affinity for non-polar compounds like butane, hexane, etc. If you have a mixture of compounds, like in human breath or lighter fuel, they pass through that column at different rates depending on affinity for your stationary phase (the column) and also size of the molecules (heavier molecules like hexane pass through it more slowly than the lighter propane just due to size). At the end of the column you get the gases coming out separately, depending on the quality of your separation with the ones being less retained by the column coming out first.

A small problem with this is that the separation takes time and can take up a lot of time depending on conditions. Most GCs operate at about 200 degrees Celcius to increase the speed but also to make sure that everything actually is in the gas phase.

For a hobby project I just want to do it at ambient temperature first using lighter gas (which I know is a gas at room temperature) and for a column I will use bentonite clay, which they used back in the old days before silica and it's cheap. Kitty litter is made from bentonite clay as well so it's easily available. As a carrier gas just normal air using for example an aquarium pump or other small membrane pump.

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


# Question
Title: Undefined reference to Class::function()
I have three files:

1. `main.cpp`
2. `RotaryEncoder.h`
3. `RotaryEncoder.cpp`

Note that the `RotaryEncoder` class acts as a wrapper to the `Encoder` library. I am getting the following build report and I haven't been able to find the bug for the past couple days:

**Build output from PlatformIO on VS Code**

```
Processing uno (platform: atmelavr; board: uno; framework: arduino)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/uno.html
PLATFORM: Atmel AVR 1.15.0 > Arduino Uno
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 31.50KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduinoavr 4.1.2
LDF: Library Dependency Finder
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 7 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Encoder>
Building in release mode
Compiling .pio/build/uno/src/main.cpp.o
Linking .pio/build/uno/firmware.elf
/var/folders/t1/fyh283nd1m7dxbrjlkjtf_kc0000gn/T//ccZN56Tq.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x2dc): undefined reference to `RotaryEncoder::getCount()'
collect2: error: ld returned 1 exit status
*** [.pio/build/uno/firmware.elf] Error 1

```

**Explicit Error**

> In function 'main': :(.text.startup+0x2dc): undefined reference to 'RotaryEncoder::getCount()'.

---

**main.cpp**

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

#define cartEncoderPhaseA 3
#define cartEncoderPhaseB 4
#define pendulumEncoderPhaseA 2
#define pendulumEncoderPhaseB 5

// Initialize encoders
const double ENCODER_PPR = 2400.0;
RotaryEncoder cartEncoder(cartEncoderPhaseA, cartEncoderPhaseB, ENCODER_PPR);
RotaryEncoder pendulumEncoder(pendulumEncoderPhaseA, pendulumEncoderPhaseB, ENCODER_PPR);

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

void loop()
{
  long cartCount = cartEncoder.getCount();
}

```

**RotaryEncoder.h**

```
#pragma once

#include <Encoder.h>

class RotaryEncoder
{
private:
    Encoder encoder;
    double encoderPPR;
    double angleLowerBound;
    double angleUpperBound;

    double convertEncoderCountToRadians(long encoderCount);
    double normalizeAngle(double angle);

public:
    RotaryEncoder(int phaseA, int phaseB, double encoderPPR);
    long getCount();
    double getRadiansAndOffsetBy(double angleOffset);
    void setAngleLowerAndUpperBounds(double lowerBound, double upperBound);
};

```

**RotaryEncoder.cpp**

```
#include "RotaryEncoder.h"

RotaryEncoder::RotaryEncoder(int phaseA, int phaseB, double encoderPPR)
: encoder(phaseA, phaseB), encoderPPR(encoderPPR)
{}

inline long RotaryEncoder::getCount()
{
    return encoder.read();
}

inline double RotaryEncoder::getRadiansAndOffsetBy(double angleOffset)
{
    long encoderCount = getCount();
    double angleInRadians = angleOffset + convertEncoderCountToRadians(encoderCount);
    angleInRadians = normalizeAngle(angleInRadians);

    return angleInRadians;
}

inline double RotaryEncoder::convertEncoderCountToRadians(long encoderCount)
{
    return ((double)encoderCount / (encoderPPR)) * (2.0 * PI);
}

inline double RotaryEncoder::normalizeAngle(double angle)
{
    // Constrain an angle between [-pi, pi). Output is in radians
    // see: https://stackoverflow.com/questions/11498169/dealing-with-angle-wrap-in-c-code

    angle = fmod(angle + PI, 2 * PI);

    if (angle < 0)
        angle += 2 * PI;

    return angle - PI;
}

inline void RotaryEncoder::setAngleLowerAndUpperBounds(double lowerBound, double upperBound)
{
    angleLowerBound = lowerBound;
    angleUpperBound = upperBound;
}

```

# Answer
The inline modifier doesn't make a sense for methods definitions in separate cpp file. And obviously it makes the code compilable but methods aren't recognized as methods definitions and also it's not recognized as error (that's kinda weird).

Anyway, if you wan't inline methods, do it directly inside of class definition.
> 3 votes

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


# Question
Title: need to compare if a byte is less than 80 hex
I am using an infrared sensor called OTI301. In its data sheet it says that in order to obtain object temperature and ambient temperature values I need to extract the binary information from the sensor and use the binary information in given formulas. I have done all that but for some reason I am not getting the right values for the object temperature. The ambient temperature seems to work well but when I put a hot object, more than 320 F, the formula returns a random negative number. Also the the sensor can go up to 780 F so I know the temperature has not been capped. Please see pictures for important data sheet information, or here are the links for the complete data sheets https://drive.google.com/file/d/1XMRDCNzY3fn0q6lkGejs5D-pqksfRuZ8/view?usp=sharing. https://drive.google.com/file/d/1mmdkHkNbwC5VgQxGMrq07XolajNvgBkN/view?usp=sharing. Lastly, here is the part of the code where I extract the information and apply formulas.

```
     void loop()
 {
   if (Wire.read()) // On success, read() will return 1, on fail 0.
   {
     buttonState = digitalRead(button);
     //Serial.println(buttonState);
     Wire.beginTransmission(DEVICE_ADDRESS);
     Wire.write(0x80);  // readout command
     Wire.endTransmission(false);
     Wire.requestFrom(DEVICE_ADDRESS, 6); // request 6 bytes
     uint8_t data[6];
     for (int i = 0; i < 6; i++) {
         data[i] = Wire.read();
     }

      //Calculate Object Temperature
     if(data[5] < 0x80) {
       TA = (data[3]+ data[4]*256+data[5]*65536)/200;
     }
     else {
       TA = (((data[3]+ data[4]*256+data[5]*65536)) - 16777216) /200;
     }

     //Calculate Ambient Temperature
     if(data[2] < 0x80) {
       TA = (data[0]+ data[1]*256+data[2]*65536)/200;
      }
     else {
       TA = (((data[0]+ data[1]*256+data[2]*65536)) - 16777216) /200;
     }

```

# Answer
> 1 votes
You said "I defined TA as a float." That doesn't matter. In C/C++, expressions are only "promoted" to a larger/different data type AFTER they are evaluated. Your calculations are being done using 16-bit ints, which overflow, and **then** cast to a float.

(C/C++ evaluates expressions from the inner-most outward, and if one of the operands to an operator is a larger type, it will "promote" the other operand to the larger type before doing a calculation. It **won't** notice that a calculation will overflow and promote the operands to fix that problem however.)

Try this:

```
   TA = (data[3]+ data[4]*256+uint64(data[5])*65536)/200;

```

That version of the code forces data\[5\] to an unsigned long **before** multiplying it by 65536.

Do the same thing to the value that you multiply by 65536 in all of your expressions and you should avoid overflow.

# Answer
> 1 votes
The rules of integer arithmetics are tricky in C++. There are rules that give the type of integer literals:

* `256` and `200` are of type `int`, which is the default type for integer literals. On the Nano, this type is 16-bits, and covers the range from −32,768 to +32,767.
* `65536` being too large for the `int` type, it is implicitly considered a `long int`. This type is 32-bits on the Nano, and covers roughly ±2.15×109.

Then there are rules for the types used in arithmetic operations. No computation is ever done on a type smaller than `int`: anything smaller is promoted to `int`. Then, if you combine two operands of different types, the larger type “wins” and the compiler implicitly converts the other operand to the larger type. Note that if two types have the same bit size, the unsigned one is considered “larger”.

Let's go now through your formula, and see the types of the different terms:

```
data[3]       = uint8_t
data[4]*256   = uint8_t * int → int
data[5]*65536 = uint8_t * (long int) → long int

```

Now you may see the problem. Your calculation will eventually overflow, but the overflow is *not* in `data[5]*65536`, as one may naively expect. What happens is than when the temperature reaches 163.84 °C (≈ 327 °F), `data[4]` becomes 128, and `data[4]*256` is 32,768, just too large for an `int`. The result overflows to −128, hence the negative values you see.

The simplest solution is to force 256 to be a `long int`, by appending the `L` suffix to the number. Then the multiplication will be performed with the `long int` type, and there will be no overflow:

```
TA = (data[3] + data[4]*256L + data[5]*65536) / 200;

```

---

On a final note, it is worth noting that the numbers 256, 65536 and 16777216 used in the formula are all powers of two. Even powers of 256. You may notice that, save for the division by 200, what this formula describes is the coding of an integer as a 24-bit, little-endian, two's complement number. This format (two's complement little-endian) is exactly what the Arduino uses internally for representing numbers. You could then avoid all those calculations and get your result by just telling the compiler that what those memory cells are actually holding is a 24-bit integer:

```
float TA = *(__int24*)&data[3] / 200.0;

```

This works for both positive and negative temperatures, but it has the drawback of breaking some C++ rules (aliasing rules), and using the non-standard type `__int24`. A safest way to achieve the same is to build a 32-bit integer by putting the bits in place using bitwise operations. But note that then a sign-extension byte is needed to convert the 24-bit number to 32 bits:

```
uint8_t sign_extension = data[5] & 0x80 ? 0xff : 0x00;
int32_t reading = (uint32_t) data[3] <<  0
                | (uint32_t) data[4] <<  8
                | (uint32_t) data[5] << 16
                | (uint32_t) sign_extension << 24;
float TA = reading / 200.0;

```

---
Tags: arduino-nano, temperature, bit, bytes
---


# Question
Title: need at least 5 volts but 3.7 lithium polymer battery does not supply enough Voltage
I am building a device using an Arduino Nano, an OLED display and infrared thermometer sensor. I want to make it rechargeable so I am using a 1 cell lipo battery and a tp4056 circuit protection board, which cuts power at 4.2 V and 2.5 V. The OLED runs in the 5.0 V port and the sensor runs in the 3.3 V port in the Arduino. Of course the system does not work since the battery only delivers 3.7 V and when I measure the voltage in the Nano, it is actually seeing around 2.6 volts in each port (I'm assuming this drop is due to internal resistance of the cables and the protection circuit). Having said that I was thinking about using a boost converter but everything I find online says that the input voltage for the boost converter should be at least 3.5 V for it to deliver a constant 5.0 V output. This would not work since as I mentioned, the protection circuit will cut the power at 2.5 V which is well below the 3.5 V mark. Is there another practical solution I could use for this system to work with 1 cell lipo battery. I don't want to use 2 cell battery pack since it would make it more expensive and bigger in size. Also, I ran the project with a 9.0 V battery and it worked perfectly fine.

# Answer
> 1 votes
This is exactly why the typical LiPO battery shield includes a boost converter.

I'm not sure where you saw the unusually high (3.5V) low-voltage limit, but that isn't typical of most converters.

# Answer
> 0 votes
I would recommend using a display that does not require 5v to run. Using a lower voltage display like an led based one will simplify the system. My favorite thing to use is the adafruit feather huzzah8266 with the charlieplex display board on top. They fit together via header pins and it has a built in lipo charging circuit and battery connector. You can then wire your sensor in and voila.
https://www.adafruit.com/product/2821 https://www.adafruit.com/product/3134

---
Tags: arduino-nano, voltage-level, voltage, voltage-protection, lipo
---


# Question
Title: Global variables use to much space in the dynamic memory
I use two simple libraries (see , ) I found online for my code on the Arduino Uno, unfortunately I also use ROS and all those libraries take away to much space, when I compile my code I get this error:

```
Global variables use 2,112 bytes (103%) of dynamic memory, leaving -64 bytes for local variables. Maximum is 2,048 bytes.

```

I shortened my Strings, but it was not enough. How can I change the code in the libraries to achieve less used memory?

I think I don't understand the concept of global variables completely. For example I changed all `double` variables in the libraries to `float` variables, but it did not change dynamic memory use at all. How can I use less memory?

# Answer
> 2 votes
When you write a program, some memory can be determined in compilation time, due to it's predefinition, (`float` and `double` in Arduino - not Due model - use 4 bytes each - in Due, `double` uses 8 bytes for 64 bit precision).

But there is some memory that only can be known at runtime; where we are talking about objects (or arrays determined by user input). In these cases, programs need to dynamically allocate memory, for which the C++ language integrates the operators `new` and `delete`. More info at: Dynamic memory.

You should control the creation of objects and arrays (those are created with `new` and then deleted with `delete`).

If your requirements are greater than the resources of any Arduino (except Arduino Due), you should change to the Due model, which has more memory space and computing power (but changes the 5 V to 3.3 V, be careful).

# Answer
> 2 votes
@jonas I had a similar problem not quite exceeding the limit. One item you can do is move the strings to Flash. `<pgmspace.h>` there is the definition of PSTR which will place the literal in flash the patternname, which we normaly just use strcpy, we need to use strcpy\_P. strcpy\_P states the string will come from Flashmemory and copy it into SRAM space. Once it is in SRAM sapce we can maniputate it all we want. for example:

```
setPatternName((char*)PSTR("My PatternName"));

void setPatternName(const char* text) {
  memset(patternName, MAX_PATTERN_NAME_LEN + 1, 0 );
  strcpy_P(patternName, text);
  int length = strlen(patternName);
}

```

This should have a significant reduction in mem usage.

# Answer
> 1 votes
```
char buf[50];

char* tm1Txt (byte num){
  if (num == 0){strcpy_P(buf, (char*) F("t1 - Задepжka koмaнды xoд"));}
  if (num == 1){strcpy_P(buf, (char*) F("t2 - Bpeмя cepвoфиkcaции "));}
  if (num == 2){strcpy_P(buf, (char*) F("t3 - Bpeмя дoтягивания   "));}
  if (num == 3){strcpy_P(buf, (char*) F("t4 - Bpeмя тopмoжeния    "));}
  if (num == 4){strcpy_P(buf, (char*) F("t5 - Наложениe тормоза   "));}
  if (num == 5){strcpy_P(buf, (char*) F("t6 - Снятия нагр воздуха "));}
  return buf;
}

```

---
Tags: arduino-uno, programming, library, memory-usage
---


# Question
Title: What Arduino and shield components are worth recycling?
I'm building up a nice collection of smoked or otherwise bricked Arduino boards. I would like to save bits that might be useful later. I've desoldered a barrel plug to use when I want to separate the power supply to a motor shield. Is there something I could do with the ATmega328 processor, and how would I verify that it is still functional? Any other bits that you rescue?

# Answer
> 3 votes
You can reuse everything what is not damaged, but it can be tricky to properly desolder multi-pin SMD parts.

It's hard to verify if a processor is still working, but it propably is not anymore if you applied a too high voltage on one of the input pins or drew to much current.

Parts like regulators are always handy. I would skip capacitors and resistors.

But you can try to desolder everything, it will teach you how to use e.g. solder wick properly. This will come handy in the future, if you need to replace parts properly! :)

---
Tags: atmega328, components
---


# Question
Title: MQTT on nano with Ethernet shield not working
I'm using an arduino nano with an ethernet shield (ENC28J60), and ethernet eem to be working (I can create a webserver with **Ethercard** library).However, i'm stuck when i try to connect to a MQTT server.

I tried **NanodeMQTT** (stuck at waitforlink), **Adafruit MQTT Library** \+ Ethernet.h ( MQTT\_connect() : Connection failed, endlessly retrying), **PubSubClient** \+ Ethernet.h (client.connect return 0) and some others.

At this point i am wondering if i am doing the right configuration each time:

> when asked an ip, i set the static one i want for my arduino : 192.168.1.50
>
> when asked an gwip, i set one of wy internet router : 192.168.1.254
>
> when asked for a server, i set it to my mqtt server ipv4 : 192.168.1.185 (and port is 1883)
>
> when asked for a mac adress, i keep the one in the example, or just write a random one

Do you know what can cause the ethernet.h or mqtt library to fail, but still ethercard is working fine ?

# Answer
> 2 votes
Thanks to Juraj pointing me that UIPEthernet is just a replacement for the Ethernet library, I finnally found this article Which works just fine.

---
Tags: ethernet, ethernet-shield, mqtt
---


title: Two Reed switch in two way directions

text:
# Question
Title: Two Reed switch in two way directions
Hi im a student having problem in coding I want to set two reed switch in two direction. Example : 1. Reed switch 1 detect then reed switch 2 detect - led turns to yellow 2.If reed switch 2 detect first then reed switch 1 detect - led turns to red It should play in sequentially form. Can help me in coding? So far i have done this..

```
const int REED_PIN1 = 2; // Pin connected to reed switch const int REED_PIN2 = 3; // Pin connected to reed switch

const int RED = 9; // LED pin - active-high const int GREEN = 10; // LED pin - active-high const int YELLOW = 11; // LED pin - active-high

int up = 0; int down = 0;

void setup() { Serial.begin(9600); // Since the other end of the reed switch is connected to ground, we need // to pull-up the reed switch pin internally. pinMode(REED_PIN1, INPUT_PULLUP); pinMode(REED_PIN2, INPUT_PULLUP);

pinMode(RED, OUTPUT); pinMode(GREEN, OUTPUT); pinMode(YELLOW, OUTPUT);

digitalWrite(RED, LOW);
digitalWrite(GREEN, HIGH);
digitalWrite(YELLOW, LOW);
}

void loop() { int proximity1 = digitalRead(REED_PIN1); // Read the state of the switch int proximity2 = digitalRead(REED_PIN2); // Read the state of the switch while (proximity1 == LOW) // If the pin reads low, the switch is closed. {

up  = up  + 1;
Serial.print(up);
Serial.print("        ");
Serial.println(down);

if(down < 1){
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);

delay(1000);
}

else {
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);

delay(1000);
}
} while (proximity2 == LOW) // If the pin reads low, the switch is closed. { up = up - 1; Serial.print(up); Serial.print(" "); Serial.println(down); if(up < 1 && down < 1){ digitalWrite(RED, LOW); digitalWrite(GREEN, LOW); digitalWrite(YELLOW, HIGH);

delay(3000);      }
else{
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);

delay(1000);
}
} while (proximity2 == LOW) // If the pin reads low, the switch is closed. { down = down + 1; Serial.print(up); Serial.print(" "); Serial.println(down);

if(up > 1){
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, HIGH);

delay(1000);
}

else {
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);

delay(1000);
}
delay(1000);
}
while (proximity1 == LOW) ;// If the pin reads low, the switch is closed. { down = down - 1; Serial.print(up); Serial.print(" "); Serial.println(down); if(up < 1 && down > 1){ digitalWrite(RED, HIGH); digitalWrite(GREEN, LOW); digitalWrite(YELLOW, LOW);

delay(5000);      }
else{
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
delay(5000);} } }

```

# Answer
Sorry, but your code is complete nonsense. The following code gives you an example. I have no access to a compiler at the moment, so there might be syntax errors and it is completely untested. Also, you gave no complete description of the things you want to do. e.g when to switch on the green LED or what the up and down variables are for.

And there might also be timing problems. In order not to miss a reed state change, you should avoid adding `delay`s and slow serial print outs.

I'm pretty sure, I did your homework. So my advice is to learn programming and try to understand. Homework was not ( only ;-) ) invented to enjoy the teacher, they help you through tests. ;-)

Your problem is similar to the decoding of a rotary encoder, so information about this subject might help you also.

```
const int REED_PIN1 = 2;
const int REED_PIN2 = 3;

// LED pins - active-high
const int RED    =  9;
const int GREEN  = 10;
const int YELLOW = 11;

int fixedState1 = HIGH;
int fixedState2 = HIGH;

void setup()
{
   // If the pin reads low, the switch is closed.
   pinMode(REED_PIN1, INPUT_PULLUP);
   pinMode(REED_PIN2, INPUT_PULLUP);

   pinMode(RED, OUTPUT);
   pinMode(GREEN, OUTPUT);
   pinMode(YELLOW, OUTPUT);

   digitalWrite(RED, LOW);
   digitalWrite(GREEN, HIGH);
   digitalWrite(YELLOW, LOW);
}

void loop()
{
  // AS LONG AS BOTH SWITCHES ARE ON AT THE SAME TIME,
  // THE PROGRAM FLIPS OUT ;-)
  int reedState1 = digitalRead( REED_PIN1 );
  int reedState2 = digitalRead( REED_PIN2 );

  if ( readState1 == LOW && fixedState1 == HIGH )
  {
    if ( fixedState2 == LOW )
    {
      digitalWrite( RED,    HIGH );
      digitalWrite( YELLOW, LOW  );
      digitalWrite( GREEN,  LOW  );

      fixedState2 = HIGH;
    }
    else
    {
      // setting the green LED is just a guess
      digitalWrite( RED,    LOW  );
      digitalWrite( YELLOW, LOW  );
      digitalWrite( GREEN,  HIGH );

      fixedState1 = LOW;
    }
  }

  if ( readState2 == LOW && fixedState2 == HIGH )
  {
    if ( fixedState1 == LOW )
    {
      digitalWrite( RED,    LOW  );
      digitalWrite( YELLOW, HIGH );
      digitalWrite( GREEN,  LOW  );

      fixedState1 = HIGH;
    }
    else
    {
      // setting the green LED is just a guess
      digitalWrite( RED,    LOW  );
      digitalWrite( YELLOW, LOW  );
      digitalWrite( GREEN,  HIGH );

      fixedState2 = LOW;
    }
  }
}

```
> 1 votes

# Answer
Your code is so badly formatted it makes it very difficult to follow.

A couple of things that jump out at me:

You never set REED\_PIN1 or REED\_PIN2 to INPUT\_PULLUP mode. You should do that in setup.

You have the code that deals with REED\_PIN2 commented out so that can't possibly work.

I took a first crack at improved code formatting. There result is below:

```
const int REED_PIN1 = 2; // Pin connected to reed switch const
int REED_PIN2 = 3; // Pin connected to reed switch

const int RED = 9; // LED pin - active-high
const int GREEN = 10; // LED pin - active-high
const int YELLOW = 11; // LED pin - active-high

int up = 0; int down = 0;

void setup() {
    Serial.begin(9600);
    // Since the other end of the reed switch is connected to ground, we need
    // to pull-up the reed switch pin internally.
    pinMode(REED_PIN1, INPUT_PULLUP);
    pinMode(REED_PIN2, INPUT_PULLUP);

    pinMode(RED, OUTPUT); pinMode(GREEN, OUTPUT); pinMode(YELLOW, OUTPUT);

    digitalWrite(RED, LOW);
    digitalWrite(GREEN, HIGH);
    digitalWrite(YELLOW, LOW);
}

void loop() {
    int proximity1 = digitalRead(REED_PIN1); // Read the state of the switch
    int proximity2 = digitalRead(REED_PIN2); // Read the state of the switch while (proximity1 == LOW) // If the pin reads low, the switch is closed.

    up  = up  + 1;
    Serial.print(up);
    Serial.print("        ");
    Serial.println(down);

    if(down < 1) {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, LOW);

        delay(1000);
    }

    else {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, LOW);

        delay(1000);
    }
} while (proximity2 == LOW) { // If the pin reads low, the switch is closed.
    up = up - 1;
    Serial.print(up);
    Serial.print(" ");
    Serial.println(down);
    if (up < 1 && down < 1) {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, HIGH);

        delay(3000);
    }
    else {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, LOW);

        delay(1000);
    }
} while (proximity2 == LOW) { // If the pin reads low, the switch is closed.
    down = down + 1;
    Serial.print(up);
    Serial.print(" ");
    Serial.println(down);

    if(up > 1) {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, HIGH);

        delay(1000);
    }

    else {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, LOW);

        delay(1000);
    }
    delay(1000);
}
while (proximity1 == LOW) { // If the pin reads low, the switch is closed.
    down = down - 1;
    Serial.print(up);
    Serial.print(" ");
    Serial.println(down);
    if (up < 1 && down > 1) {
        digitalWrite(RED, HIGH);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, LOW);
        delay(5000);      }
    else{
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
        digitalWrite(YELLOW, LOW);
        delay(5000);

    }
}

```

## EDIT:

After a first pass at code formatting I found the lines that are supposed to set up your REED\_PIN1 and REED\_PIN2 as inputs. That code got swallowed into a comment, so I didn't see it. (Everything after a `//` until the end of the line is a comment. You can't put the opening curly brace for a `while` or an `if` statement after a comment.)

Don't put statements on the same line as an opening brace. Don't put multiple statements on a line. Every time you enter a new level of scope (inside another set of curly braces) increase your indentation level)

These are pretty firm conventions for code formatting. There's some debate on the margins for things like where to put your braces and how many blank lines to use, but your code violates the basics of readability all over the place.
> 0 votes

---
Tags: c++, electronics
---


# Question
Title: How Can I convert my arduino code to C/C++ embedded code
For example I have an code for arduino but I want to change it to embedded C to create more professional project with different hardware. is there any tutorial? I know the logic and the most of the codes are the same. I just wanna know about libraries or pin definitions for LCD and buttons.

# Answer
> 1 votes
Arduinos use a standard C++ compiler. The supposed "Arduino Language" doesn't exist; it is C++. *Except* that the Arduino IDE will permit you some shortcuts that the compiler doesn't. The two biggies are:

1. The IDE will notice that your are trying to use libraries (ones it recognizes, anyway) and insert the necessary `#include <SOMELIBRARY.H>`, if you didn't do it.
2. The IDE will notice when you make forward reference to a function not yet defined nor declared, and provide the necessary forward declaration.

But if you manage these for yourself, as you would have to in any other C++ environment, your code *structure* will be portable.

The remaining source of incompatibility is hardware dependence. Writing embedded systems software is almost always hardware dependent. It has to be dependent on the external hardware, and quite likely is dependent on specifics of the MCU. The latter dependencies can usually be written around. Function calls or direct references to the processor's I/O registers, for example, which, on another processor, will map differently, maybe even to memory addresses instead of to registers at all.

Another processor will very likely have an entirely different set of pins with different characteristics and capabilities from the original one. Libraries to drive external hardware will likely have been designed for a given processor or processor-family and may not map gracefully to another.

If processor independence is a design-goal of the project, then you'd probably define a hypothetical set of features that you'd expect all processors to share, and hand code for anything outside of that basic set. If you wanted to take advantage of certain features if they were available on a given processors, then, in addition to the hand-coded features you wish to have, you'd also provide conditionally compiled, optimized-for-the-processor code that you could enable when you compile for that processor, and disable for all others.

# Answer
> 1 votes
If you would to write more professional code, you could try to use a different editor instead the basic arduino editor. Possible choices are, for example:

* Visual Studio Core with platformio plugin.
* Eclipse With Sloeber plugin.

Since arduino already use C/C++ Languange, the only difference is the way you write and organize the code.

---
Tags: c++, lcd, button
---


# Question
Title: ESP32 saving data to SD card in .csv doesnt format correctly
i want to save a vector to a .csv file on a SD Card.

I watched this tutorial on how to do it and it describes it perfectly even though its kinda dated.

My Problem is that everything is saved into the first cell of the .csv file so it gets constantly overwritten. It should save only the first vector into the first cell, then the second vector into the second cell and so on. I just get all three vectors with the commas into the first vector like this:

8, 9, 10

Also the header which should appear at the top is also gone.

I would really appreciate some help. Thanks!

Here is my setup and loop:

```
#include <iostream>
#include <string>
#include <vector>
#include "SD.h"
#include "SPI.h"
#include "EKG_data_transmision.h"

#define CS_Pin 5 // Chip Select Pin

EKG_data_transmision EKG_data_transmision;

std::vector<unsigned short> vector_1 = {1,2,3,4,5,6,7,8,9,10};
std::vector<unsigned short> vector_2 = {2,3,4,5,6,7,8,9,10,11};
std::vector<unsigned short> vector_3 = {3,4,5,6,7,8,9,10,11,12};
unsigned int for_x = 0;

void setup() {
  // open serial
  Serial.begin(9600);
  Serial.print("Init SD Card...");
  pinMode(CS_Pin, OUTPUT);

  if(!SD.begin(CS_Pin))
  {
    Serial.println("Card failed or not present");
    return;
  }

  EKG_data_transmision.vectorData = SD.open("/data.csv", FILE_WRITE);  //erstelle data.csv datei

  if(EKG_data_transmision.vectorData)
  {
    EKG_data_transmision.vectorData.println(", , , ,");
    String header = "ID, Value, Time, Whatever";
    EKG_data_transmision.vectorData.println(header);
    EKG_data_transmision.vectorData.close();
    Serial.println(header);
    Serial.println("card init sucess");
  }
  else
  {
    Serial.println("Couldnt open vector data file");
  }

}

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

  while(for_x <= 8){
    for_x++;
    EKG_data_transmision.write_vector_to_SD(vector_1, vector_2, vector_3);
    delay(1000);
  }

  delay(10000);
}

```

Here is my function that should save everything to the SD Card:

```
bool  EKG_data_transmision::write_vector_to_SD(std::vector<unsigned short> vector_ADC_1, std::vector<unsigned short> vector_ADC_2, std::vector<unsigned short> vector_ADC_3) // Übertrage
{
  dataString = String(vector_loc) + "," + String(vector_ADC_1[vector_loc]) + "," + String(vector_ADC_2[vector_loc]) + "," + String(vector_ADC_3[vector_loc]); // + "\r\n"

  vectorData = SD.open("/data.csv", FILE_WRITE);

  if(vectorData){
    //sd karte immer noch da und schau ob data.csv exisitiert
    vectorData.println(dataString);
    Serial.println("This is vector:");
    Serial.println(vector_loc);
    Serial.println("Im actually writing this:");
    Serial.println(dataString);
    vectorData.close(); // close the file
    }

  else{
    Serial.println("Error writing to file !");
}
  vector_loc++;

  return 0;
}

```

# Answer
In Arduino SD library FILE\_WRITE constant instructs the function to open the file for append, but in the esp32 SD library it opens the file for rewrite. Use FILE\_APPEND to open the file for append.

```
File file = SD.open(path, FILE_APPEND);

```
> 1 votes

---
Tags: sd-card, esp32, datalogging
---


# Question
Title: Sim900a AT+HTTPREAD does not get fully answer
changed the firmware on SIM900B

try to send get request http://dummy.restapiexample.com/api/v1/employee/1 `AT+HTTPACTION=0`returned `+HTTPACTION:0,200,98`

but, when I try to read (`AT+HTTPREAD` or `AT+HTTPREAD=0,98`)the response data I got broken response

expected result:

```
+HTTPREAD:98
{"id":"1","employee_name":"Shibani","employee_salary":"999","employee_age":"0","profile_image":""}

```

and actual results:

```
+HTTPREAD:98
{"id":"1","employee_name":"Shibani","employee_salary":"999","empe_"0"olme"

+HTTPREAD:98
{"id":"1","employee_name":"Shibani","employee_salary":"999","empe_"0"fea"}

+HTTPREAD:98
{"id":"1","employee_name":"Shibani","employee_salary":"999""pea:,piig"

+HTTPREAD:98
{"id":"1","employee_name":"Shibani","employee_salary":"999",moeg""reae}

```

my Arduino code looks like that

```
void setup() {
  Serial.begin(9600);
  mySerial.begin(57600);
  delay(5000);
  mySerial.println("AT");
  Serial.println("End of the setup");
}

void loop() {
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

```

# Answer
> 2 votes
Apparently you were running software serial at too high of a baud rate (57600) and bringing it down to 9600 fixed the issue.

---
Tags: arduino-nano, gsm, http
---


# Question
Title: How can I use Methods in digitalWrite(): digitalWrite(int, "methodHere")?
When creating a piece of code to operate a 7-segment display, I ran into a problem:

The seven segment display on TinkerCad (I was using this at the time) requires you to pull down the inputs to turn a segment on, while the one that I have turns on when I pull up the inputs.

Instead of completely rewriting the code for the display that I had, I wanted to make my code more universal for if I need to use it in the future.

I cannot find a way to make the method digitalWrite(int pin, int val) work with a method that returns and int in the place of "int val"

This is the code that will not work:

```
int F = 11;
int G = 10;
int E = 9;
int D = 8;
int C = 7;
int DP = 6;
int B = 5;
int A = 4;
int type = 1;

 int highLow(int highOrLow)
{

  int digOutput;

  if(type = 1)
  {

    if(highOrLow = 1)
    {

      digOutput = 1;

    }
    if( highOrLow = 0)
    {

      digOutput = 0;

    }

  }
  if(type = 0)
  {

    if(highOrLow = 0)
    {

       digOutput = 0;

    }
    if( highOrLow = 2)
    {

      digOutput = 1;

    }

  }
  return digOutput;
}

void zero()
{
  digitalWrite(F, highLow(0));
  digitalWrite(G, HIGH);
  digitalWrite(E, LOW);
  digitalWrite(D, LOW);
  digitalWrite(C, LOW);
  digitalWrite(DP, HIGH);
  digitalWrite(B, LOW);
  digitalWrite(A, LOW);
}

setup
{
pinMode(F, OUTPUT);
pinMode(G, OUTPUT);
pinMode(E, OUTPUT);
pinMode(D, OUTPUT);
pinMode(C, OUTPUT);
pinMode(DP, OUTPUT);
pinMode(B, OUTPUT);
pinMode(A, OUTPUT);
zero();
}

```

Note : I am just using pin f to test.

Also, my etiquette is not very well defined or tested, so please keep it rather simple if you can.

If it matters, I am going to be using to using an Arduino Mega2560 produced by Elegoo.

Thanks for any help!!

# Answer
> 0 votes
In this situation it is far more efficient to use `#define` and conditional compilation.

```
// Uncomment this for tinkercad
// #define INVERTED

#ifdef INVERTED
#  define ON HIGH
#  define OFF LOW
#else
#  define ON LOW
#  define OFF HIGH
#endif

```

Then just use ON or OFF in place of HIGH and LOW.

```
digitalWrite(3, ON);

```

But the reason you have a problem is not because you are trying to use a function as the value to `digtalWrite()` \- the problem is actually in your basic C syntax.

You are using the assignment operator (`=`) when you should be using the comparison operator (`==`). For example here:

```
if(highOrLow = 0)

```

you should have:

```
if(highOrLow == 0)

```

---
Tags: arduino-ide, simulator
---


# Question
Title: cast from 'char*' to 'char' loses precision
Bit of a noob here. Im trying to use the sensor number (float) in my mqtt topic, but cant seem to get this right. Any help would be appreciated. Keep getting this error (cast from 'char\*' to 'char' loses precision)

```
      char buffer2[5];

       dtostrf(sensor.sensor_no, 4, 2, buffer2);
     char* buffer4 = mqtt_topic + char(buffer2);

  dtostrf(sensor.dht22_t,0, 0, buffer);
     client.publish(buffer4, buffer); //Topic name

```

# Answer
> 1 votes
By adding strings together you are actually adding together the addresses in memory where those strings are.

Instead you need to create a new empty buffer and fill it with the contents of the other strings.

```
char buffer4[32]; // <-- Enough room for both strings and a NULL character

strcpy(buffer4, mqtt_topic);  // Copy in the first string
strcat(buffer4, buffer2); // concatenate the second string

```

---
Tags: esp8266, mqtt
---


# Question
Title: How to connect 2 Fingerprint Sensor to Arduino Mega? Please help
My project was to open the door from inside and outside the room using fingerprint sensors, currently I used separate arduino on 2 different fingerprint sensor. Please help, my arduino detected only 1 fingerprint sensor when I try to connect them both on 1 arduino. ps: I connected the fingerprint sensor to digital pins (2,3) and (10,11) of the arduino mega. Thank you in advance...

```
//Here is my code

//for Relay

int in1 = 8; //pin for opening door

int in2 = 9; //pin for buzzer

 #include (<)Adafruit_Fingerprint.h>

//it (<) i use only to post the code

//Arduino Mega

SoftwareSerial mySerial1(2, 3); //for fingeprint sensor outside

SoftwareSerial mySerial2(10, 11);//for fingeprint sensor inside

Adafruit_Fingerprint finger1 = Adafruit_Fingerprint(&mySerial1);

Adafruit_Fingerprint finger2 = Adafruit_Fingerprint(&mySerial2);

void setup()
{

Serial.begin(115200);

pinMode(in1, OUTPUT);

 pinMode(in2, OUTPUT);

 digitalWrite(in1, HIGH);

 digitalWrite(in2, HIGH);

  while (!Serial);

delay(100);

  finger1.begin(57600);

finger2.begin(57600);

  if (finger1.verifyPassword() and finger2.verifyPassword()) { //To verify if 2

fingerprint sensor is working

 Serial.println("Found fingerprint sensors!");

} else {

 Serial.println("Did not find any fingerprint sensor!");

while (1) { delay(1); }

 }

  finger1.getTemplateCount(); //To show the numbers of enrolled fingerprint in sensor

 finger2.getTemplateCount();

  Serial.print("Fingerprint Sensor1 contains ");

Serial.print(finger1.templateCount); Serial.println(" templates");

 Serial.print("Fingerprint Sensor2 contains ");

Serial.print(finger2.templateCount); Serial.println(" templates");

Serial.println("Waiting for valid finger...");

}

void loop()
{

 //for fingeprint sensor outside the door
  getFingerprintID1();
  delay(50);

//for fingeprint sensor inside the door
  getFingerprintID2();
  delay(50);
}

uint8_t getFingerprintID1() {

uint8_t p = finger1.getImage();

switch (p) {

 case FINGERPRINT_OK:

//Serial.println("Image taken");

 break;

case FINGERPRINT_NOFINGER:

// Serial.println("No finger detected");

  return p;

 case FINGERPRINT_PACKETRECIEVEERR:

 //  Serial.println("Communication error");

  return p;

 case FINGERPRINT_IMAGEFAIL:

 //Serial.println("Imaging error");

return p;

 default:

 //Serial.println("Unknown error");

  return p;

 }

// OK success!

  p = finger1.image2Tz();

switch (p) {

case FINGERPRINT_OK:

 //Serial.println("Image converted");

  break;

case FINGERPRINT_IMAGEMESS:

 //Serial.println("Image too messy");

 return p;

case FINGERPRINT_PACKETRECIEVEERR:

 // Serial.println("Communication error");

 return p;

case FINGERPRINT_FEATUREFAIL:

// Serial.println("Could not find fingerprint features");

 return p;

case FINGERPRINT_INVALIDIMAGE:

 // Serial.println("Could not find fingerprint features");

  return p;

default:

 //Serial.println("Unknown error");

  return p;

}

  // OK converted!
  p = finger1.fingerFastSearch();

if (p == FINGERPRINT_OK) {

 Serial.println("Found a print match!");

digitalWrite(in1, LOW);  //Door will open for 5 seconds

 delay(5000);

 digitalWrite(in1, HIGH);

 delay(1000);

 Serial.print(finger1.fingerID);

 } else if (p == FINGERPRINT_PACKETRECIEVEERR) {

  //Serial.println("Communication error");

  return p;

} else if (p == FINGERPRINT_NOTFOUND) {

 Serial.println("Did not find a match");

 digitalWrite(in2,LOW); //if the fingerprint did not recognize buzzer will be ON

delay(1000);

 digitalWrite(in2,HIGH);

return p;

 } else {

//Serial.println("Unknown error");

 return p;

 }

return finger1.fingerID;

}

uint8_t getFingerprintID2() {

uint8_t p = finger2.getImage();

switch (p) {

case FINGERPRINT_OK:

 //Serial.println("Image taken");

  break;

 case FINGERPRINT_NOFINGER:

// Serial.println("No finger detected");

   return p;

case FINGERPRINT_PACKETRECIEVEERR:

//  Serial.println("Communication error");

  return p;

 case FINGERPRINT_IMAGEFAIL:

 //Serial.println("Imaging error");

  return p;

 default:

 //Serial.println("Unknown error");

   return p;

 }

  // OK success!
  p = finger2.image2Tz();

 switch (p) {

 case FINGERPRINT_OK:

  //Serial.println("Image converted");

  break;

case FINGERPRINT_IMAGEMESS:

 //Serial.println("Image too messy");

  return p;

 case FINGERPRINT_PACKETRECIEVEERR:

// Serial.println("Communication error");

  return p;

case FINGERPRINT_FEATUREFAIL:

 // Serial.println("Could not find fingerprint features");

 return p;

case FINGERPRINT_INVALIDIMAGE:

 // Serial.println("Could not find fingerprint features");

  return p;

default:

  //Serial.println("Unknown error");

 return p;

}

  // OK converted!

 p = finger2.fingerFastSearch();

if (p == FINGERPRINT_OK) {

 Serial.println("Found a print match!");

digitalWrite(in1, LOW);

 delay(3000);

digitalWrite(in1, HIGH);

 delay(1000);

 Serial.print(finger2.fingerID);

} else if (p == FINGERPRINT_PACKETRECIEVEERR) {

 //Serial.println("Communication error");

  return p;

  } else if (p == FINGERPRINT_NOTFOUND) {

 Serial.println("Did not find a match");

 digitalWrite(in2,LOW);

 delay(1000);

 digitalWrite(in2,HIGH);

 return p;

 } else {

 //Serial.println("Unknown error");

  return p;

 }

 return finger2.fingerID;

}

```

# Answer
I guess your problem is, that you are using SoftwareSerial. Doing Serial in software means, that you can only listen at one interface at a time, thus only one of the fingerprint sensors work at a time.

But you are using the Arduino Mega, which has 4 hardware Serial interfaces. They are named `Serial` and `SerialX` (with X being 1,2 or 3). You can give a reference to these Serial interfaces to the Adafruit library just like you are doing it with the SoftwareSerial interfaces. You are doing:

```
Adafruit_Fingerprint finger1 = Adafruit_Fingerprint(&mySerial1);

```

Instead you could do:

```
Adafruit_Fingerprint finger1 = Adafruit_Fingerprint(&Serial1);

```

That will give a reference of the second hardware serial interface (first whould be `Serial`) to the Adafruit library, which will then use it to communicate with the sensor. Hardware and Software Serial implement the same interface, they just work differently under the hood, so you can easily exchange them at this level.
> 0 votes

---
Tags: arduino-mega, arduino-ide, adafruit
---


# Question
Title: ADXL345 Arduino UNO data_ready interrupt
I would like the sensor values to be updated each 10ms(100Hz) and then run the algorithm and repeat the same process. However, after timing the algorithm it is taking only 2ms, I think the data\_ready interrupt is not working as expected. Physical hardware connection is from INT1 of ADXL345 to pin2 of the UNO.

edit:

I have configured the accelerometer to have a data rate of 100Hz. I have set up an interrupt with data\_ready to run the algorithm present in the loop each time a new sample comes that is each 10ms. However each sample is coming every 2ms which shows the interrupt is not working and I would like to know why. I have timed the interrupt with the millis(); function before and after calling the interrupt, also I have stored the samples in an array and printed it on the serial interface and the samples were repeated as it was updated every 2ms instead of 10ms. The algorithm I have developed needs the sampling rate to be 100Hz.

```
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <avr/io.h>
#include <avr/power.h>

#define F_CPU 16000000UL

volatile int sensor_update=0;

//-----------------------------------------------------------------------------------     -----------
//Write to ADXL345 registers
void writeTo(int device, byte address, byte val) {
Wire.beginTransmission(device); //start transmission to device
Wire.write(address);        // send register address
Wire.write(val);        // send value to write
Wire.endTransmission(); //end transmission
}

//----------------------------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////////////////////

//ISR function

void interrupt(void){
sensor_update=1;

}

//////////////////////////////////////////////////////////////////////////////////////////////////

void buzz(int targetPin, long frequency, long length) {
long delayValue = 1000000/frequency/2; // calculate the delay value between     transitions
//// 1 second's worth of microseconds, divided by the frequency, then split in half since

  //// there are two phases to each cycle
  //// calculate the number of cycles for proper timing
  long numCycles = frequency * length/ 1000;

  //// multiply frequency, which is really cycles per second, by
  //// the number of seconds to get the total number of cycles to produce
  for (long i=0; i < numCycles; i++){ // for the calculated length of time...
    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram
    delayMicroseconds(delayValue); // wait for the calculated delay value
    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram
    delayMicroseconds(delayValue); // wait againf or the calculated delay value
  }
}

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

void setup(void)
{
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  Serial.begin(9600);
  //Serial.println("Accelerometer Test"); Serial.println("");

  pinMode(4, OUTPUT);// buzzer output pin

  /* Initialise the sensor */
  if(!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    //Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);
  accel.setDataRate(ADXL345_DATARATE_100_HZ);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);

  //Create an interrupt that will trigger when a tap is detected.
  attachInterrupt(0, interrupt, RISING);

  writeTo(0x1D, 0x2E, 0);
  writeTo(0x1D, 0x2F, 0);
  writeTo(0x1D, 0x2E, 128);
  writeTo(0x1D, 0x2F, 127);
}

void loop(void)
{

  if(sensor_update==1 ){
    //When sensor_update is set to 1 in the ISR,the algorithm process the data from the accelerometer being updated every 10ms(100Hz)
     sensor_update=0;//reset
  }
}

```

# Answer
According to the data-sheet:

> The interrupt functions are latched and cleared by either reading the data registers (Address 0x32 to Address 0x37) until the interrupt condition is no longer valid for the data-related interrupts or by reading the INT\_SOURCE register (Address 0x30) for the remaining interrupts.

Therefore, an ISR that just sets a flag will not be called a second time. At the very least, you need to read the INT\_SOURCE register. If you are using the SparkFun ADXL345 library, then this would be a call of the form:

```
ADXL345 adxl = ADXL345();
void setup() {
  adxl.powerOn();
  adxl.setInterruptBitLevel(true); // active low
  attachInterrupt(digitalPinToInterrupt(interruptPin), isr, LOW);
  pinMode(interruptPin, INPUT);
  adxl.singleTapINT(1);
  ...
}

void isr(void) {
  detachInterrupt(digitalPinToInterrupt(interruptPin));
  interrupts();
  byte source = adxl.getInterruptSource();
  ...
  attachInterrupt(digitalPinToInterrupt(interruptPin), isr, LOW);
}

```

Note that I use a level-triggered interrupt here and re-enable interrupts before calling `adxl.getInterruptSource()`. The issue is that this call may take some time to talk over the I2C bus. To ensure that there are no reentrant calls, I detach the interrupt first. Without this, the level-triggered mode causes an interrupt loop.

The use of a level-triggered interrupt makes sense because the ADXL won't produce another interrupt until you read from `INT_SOURCE`. It also avoids the problem of missing an edge detection, which tends to cause subtle bugs that are hard to find.

I was unsure about the soundness of turning on interrupts within the ISR and so asked a question about this - What is the right way to query an I2C device from an interrupt service routine?
> 1 votes

# Answer
Been bashing my head with this one. And have searched the internet for a solution And tried for hours to program a solution. From my tests the problem seems to be the Register 0x30—INT\_SOURCE is populated with triggers. But the INT pin is only triggered when the Register 0x30—INT\_SOURCE is read. This means that firstly the Arduino can't be woken from sleep by the INT1 or INT2 pins because they don't change unless the Arduino is already awake and reading the Register 0x30—INT\_SOURCE Second problem is to trigger an interrupt INT pin to jump to the ISR interrupt service routine you have to read Register 0x30—INT\_SOURCE. And if you are going to do that then you might as well forget the interrupt and just jump into the ISR() and check registers in that. Which is how the example in the Sparkfun\_ADXL345\_Example for arduino ended up with the ADXL\_ISR(); call in the main loop. To sum up. Unless some one knows away to get the ADXL345 to change state on its INT pins without the need to read Register 0x30—INT\_SOURCE, then the device is useless for use with the INT pins. I have given up on it and looking for another device to wake my ESP32 from sleep. Such as the BMI160 - Bosch which looks like a contender and has a arduino library for.
> 0 votes

---
Tags: arduino-uno, interrupt
---


# Question
Title: Do i must have capacitors when using L7805CV voltage regulator?
I am creating a small waterpump (5v) controled by arduino.

And i want to reduce voltage from 9v to 5v.

Do i must use capacitors when using L7805CV voltage regulator?

# Answer
> 0 votes
Look at the datasheet:

https://datasheet.octopart.com/L7805CV-STMicroelectronics-datasheet-7264666.pdf

It's not necessary but I advise to use capacitors on the inputs aswell as on the outputs. It will improve stability.

Another thing: the regulator could get quite warm, depending on how much current the motor consumes. Why don't you use a 5V power supply? You could power the Arduino with it aswell.

At your schematic you are feeding 9V into the **Vin** pin of the Arduino, this might be a bad idea (I'm not 100% sure), but I think it bypasses the regulator on the Arduino -\> it will kill your Arduino.

---
Tags: arduino-uno, electronics
---


# Question
Title: How to Control 2-wire Rotary-Gear Linear Actuator
Any ideas how to control a 2-wire DC 5V 10mm Stroke Mini Linear Actuator based Rotary Gear Motor? Most linear actuators (aside from solenoids) are controlled via 3-4 wires. Do I need a separate motor controller for the actuator to control it via an Arduino Uno?

# Answer
> 1 votes
I suspect that's little more than a geared brushed DC motor with a fancy "nut" on it. So yes, you will need any standard motor driver rated for the correct voltage / current (an H-bridge).

---
Tags: arduino-uno, motor
---


title: MP3 File through ARDUINO

text:
# Question
Title: MP3 File through ARDUINO
Hey question is that it is possible to play MP3 file in arduino without changing it into .wav file if possible ,then your suggestions are welcome Thanks

# Answer
> 0 votes
This little device is really good and easy to set up.
https://www.dfrobot.com/product-1121.html

You can use a pin and set it to ground with a resistor between to change songs if you don't need something fancy.

---
Tags: arduino-uno, esp8266, arduino-pro-mini, audio
---


# Question
Title: Measure Natural Gas Pressure with arduino?
I am looking to measure Gas pressure in order to turn off Gas Heater when there is low gas. As in Pakistan alot of deaths occur when flame turns off because of low pressure of gas and then gas comes back. People suffocate into CO2. So to measure that gas what kind of sensor should i use with arduino? Thanks

# Answer
It sounds like death would be caused by gas poisoning, not CO2 (carbon dioxide) or CO (carbon monoxide) poisoning. If the flame goes out and then gas pressure is restored, un-burnt gas would be vented into the room. Unless gas is burning no CO or CO2 would be released. Further, our bodies detect excess CO2 and it causes us to feel short of breath and seek fresh air. CO on the other hand binds to the hemoglobin in our blood and prevents our blood from carrying oxygen, so we suffocate without knowing anything is wrong.

Natural gas is both poisonous and can cause explosions if it is lit with a spark. In most countries there is a scent added to the gas in the lines so we can smell it and know something is wrong. The scent is not enough to wake you up however.

The usual way to handle gas heater safety is with a pilot light and a thermocouple powered valve. The pilot light uses a tiny amount of gas to keep a small flame lit. That flame heats a thermocouple, which generates enough current to keep an electrically controlled gas valve open. If the pilot light goes out, the heat source to the thermocouple is removed, and the valve closes.

If the gas pressure drops enough, the pilot light goes out, the valve closes, and the heater turns off. If the gas pressure is restored, the user has to hold a button down to manually open the valve while re-lighting the pilot light.

In the U.S. gas heaters are required to have safety systems like I describe above. It sounds like the heaters in your country don't have safety systems like this.

Measuring gas pressure would be harder, as others have said in their answers. You'd need a sensor that is approved for use in gas appliances, as well as the fittings to attach it. The same goes for the valve that you would use to turn off the flow of gas when the pressure drops too low.

You'll need a pressure sensor approved for use with the type of gas you are dealing with, and that measures the pressure ranges in your gas lines. We can't know those things from the outside. You could probably find them out from the gas company that provides gas service.

In most countries working on gas lines and gas appliances requires special training and permits, since doing it wrong can cause explosions, fires, and gas poisoning.
> 2 votes

# Answer
This is a fantastic idea, but you should be a bit more informed before you start the project.

I do not think the people suffocate into CO2 because CO2 is not inflammable under normal conditions so it is not used to feed the heaters. It's produced by the heater while it burns. Most probably the heater uses methane (CH4), ethane (C2H6) or propane (C3H8).

To measure the pressure, you have to insert the sensor within the gas pipe. If this is done incorrect, there is much more danger. So you have to find a fool proved method to add the sensor.

The selection of the sensor depends also on the pressure that can be considered as normal. Another value you have to find out is: how much decreases the pressure if the burner (or more burners) are switched on. i.e at which pressure do you assume the burner's flame to go out. This value must be well known.

When you know the max and min pressure values, you can look for a sensor that can safely measure this values. It should also be included in an enclosing that can be attached to the gas pipeline.

Attention: If the pressure drops just for a small moment, the flame might go off and the sensors might not be aware of that event.

Do you know, there are alternatives to measure the pressure?

A Gas Sensor in the room checks, if there is methane, ethane or propane in the air in the room. ( this is the most secure method ) There are cheap gas sensors from china, (e.g. MQ-02), but I do not know much about them. You can also combine them with a CO2 and/or CO sensors to sense whether the chimney is clogged.

A high temperature sensor near the flame recognizes if the flame is out. But this is difficult to accomplish, because you have to build the sensor into the heater.

**EDIT**

I want to point you to the comment of @Gerben. Checking the light of the pilot flame or the flame might also be interesting.

Having thought about this a bit, I still find that measuring the air with gas sensors and starting a acoustic signal is the best way of doing it. If you want to close a valve in case you detect gas, the Arduino can start a siren and control the valve.

Attention: Again, working with gas installations is nothing a beginner should do. You want to save life ...
> 1 votes

---
Tags: arduino-mega
---