title: Pattern detection in sensor data

text:
# Question
Title: Pattern detection in sensor data
I'm using a heart rate sensor along with an Arduino for a project of mine. I have to determine whether the heartbeat is following a particular pattern (eg: when when heartbeat regularizes a lot after a period of increased or largely varying, I need to trigger an alarm to show that it has regularized).

Can anyone give me suggestions on how I can go about doing this? Are there any libraries or software for doing basic statistical analysis on data like this?

# Answer
This Arduino topic is an over-simplification and not very robust, but it presents in code the basic principle of threshold detection and the subtraction of adjacent pulse times (period). BPM = 60.0 / period in seconds.

If you want something that would work under a larger range of conditions, you can add the three primary missing features used by medical instrumentation.

1. Automated zeroing, which can be accomplished with an analog filter and pull-up or with a digital high pass filter that attenuates frequencies below 0.3 Hz. This can be done with a series capacitor leading to the analog input being sampled, with a pull up resistor to V+ and another resistor to ground to center the Voltage to an appropriate positive steady state value.
2. Attenuation of frequencies above those representing a pulse to avoid false triggers from high frequency noise, cross-talk, or transients, which can be accomplished with an analog filter or with a higher sample rate and a digital low pass filter that attenuates frequencies above 100 Hz 1.
3. Dynamic range compression, which detects the trend in pulse amplitude and continuously adapts the trigger threshold accordingly to avoid false indication of beats or the missing of weaker but legitimate beats.

To do the filtering digitally, you may want to read up on DSP (digital signal processing). There are several great books on it, and you can search for simple algorithms for both low pass filters and high pass filters in GitHub or elsewhere in the open source community.

---

\[1\] Wikipedia's article on low pass filters
> 1 votes

---
Tags: arduino-uno, sensors, arduino-ide, datalogging
---


title: Delaying an action inside a function

text:
# Question
Title: Delaying an action inside a function
My current function is supposed to play a sound effect, then after the sound effect is done (14 seconds), perform the next action (`digitalWrite(CONTROLLINO_R1, LOW)`).

```
if (digitalRead(CONTROLLINO_A8) == HIGH && !skeleLatch) {
  skeleLatch = 1;
  wTrig.trackPlayPoly(2);
  unsigned long currentMillis = millis();
  if((currentMillis-previousMillis) >= 14000) {
    digitalWrite(CONTROLLINO_R1, LOW);
    previousMillis = millis();
  }
}

```

As it is, it performs both at the same time. I do not know how to correctly implement the delay so that it waits.

Any help would be appreciated. Thank you.

# Answer
```
  unsigned long triggerMillis = 0;

  if (digitalRead(CONTROLLINO_A8) == HIGH && !skeleLatch)
  {
    skeleLatch = 1;
    wTrig.trackPlayPoly(2);
    triggerMillis = millis();
  }

  if (millis() - triggerMillis >=14000 && skeleLatch)
  {
    digitalWrite(CONTROLLINO_R1, LOW);
    skeleLatch = 0;
  }

```

This should work, depending on how long your CONTROLLINO\_A8 is staying high you might want to invest some more time to set up an interrupt on that pin, to make sure you don't miss a trigger.
> 2 votes

# Answer
If your code does not need to be re-entrant (work within a multitasking environment), the simpler solution is Arduino's delay function, designed specifically for waiting a specific number of milliseconds.

```
delay(14000)

```
> 0 votes

---
Tags: millis
---


title: How to find gain for this device?

text:
# Question
Title: How to find gain for this device?
I am doing a project with Arduino to find CO2 in an environment. For this purpose, I bought a breakout board with an MG811 sensor on it. I bought it from eBay and it came with no datasheet. I searched on the internet and found the datasheet for the MG811.

With the help of the datasheet, I also found the formula to convert the input voltage to PPM. But later I realized that the device also has an amplifier on it, which is giving me higher voltages. I searched thoroughly and found the original device on Taobao.

Can someone please tell me how can I determine the gain so that I can convert the values I read to original values?

One more question. On the given web link, I also found that this device comes with a pin called TCM and with Google translate, I found that it shows temperature compensated output. Can you please explain me the use of this pin as well? If it is more advantageous for me, I'll use this instead of the normal analog output pin.

# Answer
> 0 votes
The MG811 spec gives you the range of measurement, but without the values and connections of the surface mount op amp on the board the only way to determine the voltage output for each CO2 concentration is with a Voltmeter and an already calibrated CO2 PPM meter, which you could perhaps borrow from a lab or university. Once you have the CO2 values and Voltages that correspond, you can build a formula or function to convert the digital values to voltages and then to CO2 concentrations.

The other option is to trace the tracks on the PCB and create a schematic and then post the spec above and the schematic with resistor values included on the electronics Stack Exchange.

---
Tags: sensors
---


# Question
Title: Should all unused analog input ports be tied to ground for accurate A2D measurements?
I am using the A0 port on my Arduino Uno to read the voltage output from an LM35 temperature sensor. I observed that the reading fluctuates a lot if I leave the remaining analog input ports A1 to A5 floating. Would floating analog inputs affect the accuracy of readings on input ports connected to some signals.

# Answer
Any floating pin will act as an antenna, and may interfere with values around it, this is one of the major disadvantages of using analog.

To get the most accurate readings with minimal amount of interference, you can pull all unused inputs to ground.

The accuracy will not change, as the accuracy is determined by the sensor itself. However it will reduce the amount of noise / interference, which will give you more accurate readings.

These pull to grounds can be accomplished by configuring the unused analog pins as digital outputs, and setting them low.

```
pinMode(A1, OUTPUT);
digitalWrite(A1, LOW);

```
> 13 votes

# Answer
Even if setting the unused pins to OUTPUT/LOW consumes a little bit less power than INPUT with PULLUP enabled, i guess the second option is more save.

To quote somebody else:

> If you accidentally touch a hot wire to an output set low you short-circuit your processor and frie it. If you accidentally touch a ground wire to an output set high you short-circuit your processor and frie it. If you accidentally touch either wire to an input with pull-up you won't even notice.
> 1 votes

---
Tags: arduino-uno, pins
---


# Question
Title: How to detect the absence of an RFID tag?
I have installed an MFRC522 RFID reader in my house. The main use so far is to tell the house I've arrived using an RFID keychain, by leaving it in the key holder.

I would also like for the house to detect when I'm gone, and I was thinking that, if I can detect when a tag is present, I should also be able to detect when it is not. However, this poses some challenges like the following:

* Should I be constantly reading the tag until it disappears from range? (when I take it from the key holder).
* What if I have more than one RFID Keychain/Tag in the range of the reader? (because there could be other keychains in the same key holder). Would I get multiple readings or could one tag interfere with another in some way?

I realize that maybe this is not the typical RFID scenario when the tag is scanned and then moved away from the reader. I've been searching about "RFID tag absence detection" but I've only found what seemed to me like very theoretical papers.

Do you have any advice or experience in implementing something like this?

Thanks!

# Answer
> 2 votes
I don't think it is particularly practical, unless you make your own RFID scanner. The off-the-shelf ones generally only respond once when a particular card is in range, so you can't even detect if the card is left next the reader, or not.

Also, as the range is usually quite limited (a few cm) I don't see how it could tell the difference between you being out of the house, or taking a bath.

What might work better would be to have an active transmitter (eg. a nrf24l01) in your pocket, which every minute or so sent a "I'm home!" message to a central place. The absence of such a message after 10 minutes could indicate you are out.

The other approach would be to "check out" with your RFID scanner. I did an RFID event management system a little while back. You use a special "admin" card to indicate that a person was leaving an event for a while (a pass-out). You could do that, or have a button by the door, which you press. The "I am leaving" button.

# Answer
> 0 votes
Oh Yes it is possible. I did a project which allows to transmit data from RFID card to a bluetooth device.
You can use below code to identify presence & gone:

```
#include <SPI.h>
#include <MFRC522.h>
#include <SoftwareSerial.h>

#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

SoftwareSerial BTserial(0, 1); // RX | TX
int sensorPin = A0;
int sensorValue = 0;
String lastBlock="";
void setup() {
    Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin();            // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
//mfrc522.setPassiveActivationRetries(0x9A); // for example
//Serial.println("Scan PICC to see UID and type...");
BTserial.begin(9600);
Serial.println("Scan PICC to see UID and type...");
}
boolean flag=false;
int counter=0;
void loop() {
// Look for new cards
BTserial.println("Scan PICC to see UID and type...");
if ( !mfrc522.PICC_IsNewCardPresent()) {
  if(mfrc522.PICC_IsNewCardPresent()){
    if(!flag){
    byte sector         = 1;
byte blockAddr      = 4;
byte dataBlock[]    = {
    0x01, 0x02, 0x03, 0x04, //  1,  2,   3,  4,
    0x05, 0x06, 0x07, 0x08, //  5,  6,   7,  8,
    0x08, 0x09, 0xff, 0x0b, //  9, 10, 255, 12,
    0x0c, 0x0d, 0x0e, 0x0f  // 13, 14,  15, 16
};

byte trailerBlock   = 7;
byte status;
byte buffer[18];
byte size = sizeof(buffer);
status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
dump_byte_array(buffer, 16);

    flag=true;
    }
  }
  else{
    if(flag){
    flag=false;
    }
  }
      return;
}
}

void dump_byte_array(byte *buffer, byte bufferSize) {
String a=String((char)buffer[9]);
String b=String((char)buffer[10]);
String c=String((char)buffer[11]);
String d=String((char)buffer[12]);
String str="";
str+=a;
str+=b;
str+=c;
str+=d;
lastBlock=str;
Serial.println(str);
BTserial.println(str);
}

```

---
Tags: rfid
---


# Question
Title: Using millis() function to start at potentiometer reading
I am trying to use the `millis()` function to start a countdown of 3 seconds when I turn my potentiometer to high travel. My code so far starts the timer at the beginning of the loop or when reset is hit or when the sketch is uploaded to the board. I need the countdown to start when the potentiometer reaches high travel.

The goal of the program is that when the potentiometer reaches high travel, PumpOne starts (HIGH) and if the potentiometer does not reach low travel before 3 seconds, PumpTwo will come on (HIGH). I am trying to simulate a water tank with two pumps (LEDs in this case) and the potentiometer high and low travel representing the high and low levels of the tank respectively.

**I've updated the code since the original post but the timer still starts from the beginning of the program and not when L \> Plim1.**

Here's the code:

```
int Pump1 = 3; // Declare Blue LED in pin 3 to simulate Pump 1
int Pump2 = 4; // Declare Green LED in pin 4 to simulate Pump 2
int Alarm = 2; //Delcare Red LED in pin 2 to simulate Alarm
int TDCRPot = A0; // Declare Potentiometer(TDCRPot) an int and assign to pin A0

int L; //Declare L a variable to read the High and Low
//travel of the potentiometer

float Plim1 = 1000; // pot reading for pump 1 turn on
float Plim2 = 1000; // pot reading for pump 2 turn on
float Llim = 100; //pot reading to turn both pumps off
unsigned long T; // current time
unsigned long T1 = 0; // P1  on time
boolean P1 = false;
boolean P2 = false;
boolean Alarmstate = false;
unsigned long Tlim = 3000;

void setup() {
  Serial.begin(9600); //Turn on Serial monitor for troubleshooting
  //purposes and set to 9600 baud
  pinMode(Pump1, OUTPUT); //Declare Blue LED(PumpOne) an output
  pinMode(Pump2, OUTPUT); //Declare Green LED(PumpTwo) an output
  pinMode(Alarm, OUTPUT); //Declare Red LED(Alarm) an output
  pinMode(TDCRPot, INPUT); //Declare Potentiometer(TDCRPot) an input
}

void loop() {
  L = analogRead(TDCRPot); //Read the voltage from the Potentiometer pin
  if (!P1 && L > Plim1) {
    T = millis();
    digitalWrite(Pump1, !P1);
  }
  if (Pump1 != P1 && T - T1 > Tlim && L > Plim2) {
    digitalWrite(Pump2, !P2);
  }
  if (Pump1 != P1 && L < Llim ) {
    digitalWrite(Pump1, P1);
    digitalWrite(Pump2, P2);
  }
}

```

# Answer
> 1 votes
The statement `TDCRLevel = analogRead(TDCRPot);` will almost always set `TDCRLevel` to a non-zero value; hence the `&& TDCRLevel` term of your last `if` statement almost always is satisfied. The only time it won't be satisfied is when `TDCRLevel` is exactly zero.

When `TDCRLevel >= 1000` is first satisfied, it's likely to be true for some while; during that time, each pass through `loop()` will toggle `Bluestate` and set `previousMillisBlue = currentMillis`. This happens many times per millisecond while `TDCRLevel` has a high value. Whether `Bluestate` is on or off when `TDCRLevel` goes below 1000 is a fairly random outcome.

To handle the process properly, set up a state machine, using either one state-number variable or several variables to maintain state. Change states when conditions tied to state, `TDCRLevel`, and time are met.

More simply, something like the following might work.

```
loop:
  if !P1 and L > Plim1:
    Set P1; record T1
  if P1 and T-T1 > Tlim and L > Plim2:
    Set P2
  if (P1 or P2) and L < Llim:
    Turn off pumps, clear P1 and P2

```

where P1, P2 represent pump states; T represents current time and T1 represents time that P1 most recently turned on; L = analogRead(TDCRPot); Plim1 and 2 are pot levels for pump turnons; Llim = low level for pump turnoffs; Tlim = desired time delay before pump 2 comes on.

---

*Edit 1:* The above is pseudocode, rather than any simulacrum of valid C or C++. As such, you may need to add sets of parentheses and brackets, substitute meaningful variable names, etc.

Note that the constants `Plim1, Plim2, Tlim, Llim` should be declared via either `const int` declarations, or via `enum {}` constructs (`enum` declares only integer constants), if they are integers rather than floats. For example, do like either of

```
const int Plim1 = 1000; // level for pump1 turnon
const int Plim2 = 1000; // level for pump2 turnon
//etc

```

or

```
enum { Plim1=1000, Plim2=1000, Tlim=3000, Llim=100};

```

The phrase “Set P1; record T1” corresponds to code like

```
P1 = true;
digitalWrite(Pump1, HIGH);
T1 = millis();

```

in braces. If you don't set P1 and record T1 as current time, the process won't work. P1 and P2 represent state variables, not constants.

The phrase “if P1 and T-T1 \> Tlim and L \> Plim2: Set P2” corresponds to code like

```
if (P1 && (T - T1 > Tlim) && (L > Plim2)) {
  P2 = true;
  digitalWrite(Pump2, HIGH);
}

```

The phrase “if (P1 or P2) and L \< Llim: Turn off pumps, clear P1 and P2” corresponds to code like

```
if((P1 || P2) && (L < Llim)) {
  P1 = P2 = false;
  digitalWrite(Pump1, LOW);
  digitalWrite(Pump2, LOW);
}

```

---
Tags: millis, potentiometer
---


# Question
Title: Figuring out IR sensor PWM frequency with Arduino
I'm trying to verify the pulse width of an IR receiver I "borrowed" from one of those cheap RGB controllers (like thisone) with an arduino nano. But the data I'm getting right now is about 3.4KHz and not the 38KHz I expected.

I'm trying to measure it by connecting the data pin of the IR on INT0 and listening for any change, if the pin goes low I start a measurement, if it goes high I stop the measurement and read out the value.

I'm using Timer1 and no prescaling

My code is as followes

```
#include <util/delay.h>

#define inpin 1 << PIND2
#define timeron 1 << CS10 //timer no prescale

bool wasTiming = false;
short i = 0;

volatile short timings[20];
volatile bool print = false;

volatile short seconds = 0;

int main()
{
    USART.begin();

    _delay_ms(500);
    USART.writeln("Arduino online");

    DDRD = 0;

    TCCR1A = 0; //no compares, normal counter mode
    TCCR1B = 0; //clock off

    EICRA = 1 << ISC00; // Any change INT0 (PD2)
    EIMSK = 1 << INT0; // INT0 interrupt enable

    sei();

    char buff[20];
    for (;;)
    {
        if (print)
        {
            print = false;

            for (short j = 0; j < 20; j++)
            {
                sprintf(buff, "% 6d ticks", timings[j]);
                USART.writeln(buff);
            }
        }
    }
    USART.end();

    return 0;
}

ISR(INT0_vect)
{
    if (PIND & inpin) //pin high
    {
        if (wasTiming)//
        {
            TCCR1B = 0; //timer clock off
            timings[i] = TCNT1;
            TCNT1 = 0; //empty timer register
            wasTiming = false;

            i++;
            if (i == 20)
            {
                print = true;
                i = 0;
            }
        }
    }
    else // pin low
    {
        if (!wasTiming)
        {
            TCCR1B = timeron; //timer clock on
            wasTiming = true;
        }
    }
}

```

and the output data is

```
 13902 ticks
  8865 ticks
  9961 ticks
  8877 ticks
  9968 ticks
  9842 ticks
  8506 ticks
  9896 ticks
  9585 ticks
  9865 ticks
  9541 ticks
  8853 ticks
  9545 ticks
  8888 ticks
  9885 ticks
  9954 ticks
  8515 ticks
  9885 ticks
  8909 ticks
  9874 ticks

```

on average that looks like about 9500 ticks, which leads me to the following calculation: `(16,000,000 / 9,500) * 2 = 3,368.4Hz`

Am I doing something wrong here? Or is the data that I'm getting correct, in which case, how would I go about turning that into 1's and 0's?

I'm not really looking for off-the-shelf solutions, half the fun of doing this is figuring it out myself. Eventually I'm gonna build my own RGB controller with this to replace that cheapo thing I already have (it has a few flaws I would like to correct).

# Answer
> 0 votes
You mistakenly believe that the *carrier frequency* of 38 kHz should be available at the data output pin of the infrared detector chip. These chips provide a logic output indicating *the presence of 38 kHz*. Most are frequency-selective, being more sensitive at **one frequency** somewhere between 35 kHz - 60 kHz.
A data sheet pulled at random specifies typical pulse bursts that might be used to encode digital data (pulse burst timing highlighted in red):
In your case, \\$f\_o\\$ might be close to 38 kHz. No fewer than six cycles \\$t\_{pi}\\$ are recommended for the length of one *baud*. Perhaps your transmitter includes a few more cycles (ten or eleven?) to be safe. The receiver circuitry requires about five cycles before commit, \\$t\_d\\$. Hopefully, a similar delay at end-of-pulse occurs, but the graph at right suggests the end-of-pulse extends a little longer than \\$t\_d\\$. However, pulse width is impressively constant over five magnitudes of infrared intensity.
Note that the presence of a burst of 38 kHz from the transmitter most often sends the output of the receiver to a logic low. No optical signal yields a logic high at receiver output, sometimes with a fast false-detect glitch (which should be rejected if its length is short). A large-value pull-up resistor added between output pin and Vdd may be required to ensure that an idle receiver goes to logic high.
You will still have to determine how these pulse bursts are encoded into logical bits. Many protocols exist, some use pulse position, others use pulse length encoding.

---
Tags: infrared
---


# Question
Title: How do you connect parts once all GPIO ports are used?
I have a rather ambitious project in mind. Lots of buttons, sensors, feedback.

If I run out of GPIO ports to attach stuff to my Arduino, what's next? Do you have to buy a separate Arduino to run the extra parts, and then link the two arduinos somehow?

Thanks for any direction you can give.

# Answer
> 1 votes
Yes, it is one possible way, another are using some kind of multiplexing as input shift registers, Charlieplexing http://www.instructables.com/id/Charlieplexing-7-segment-displays/?ALLSTEPS, button matrix http://pcbheaven.com/wikipages/How\_Key\_Matrices\_Works/ or i2C bus, which can connects up to 127 different i2c devices

---
Tags: arduino-zero
---


# Question
Title: How do I specify a particular pin to use as output for the Print class?
all.

I'm attempting to write a class that inherits from the Print class. I only need serial output.

However, I'm having difficulty locating any reference on how to specify which pin on the ATMega my class will use as output of the write(...) functions.

How does the Print class know where to send output to ??

Thanks in advance.

# Answer
You need to do far more than just "specify a pin". You need to write the software that transmits data through that pin in your chosen format.

You cannot send data through a pin. You can only set a pin HIGH or set a pin LOW. It is the sequence (and most importantly the *timing*) of setting a pin HIGH and LOW that constitutes sending data.

So you have to write the software that sets the pin HIGH and LOW in the right way and at the right time.

Fortunately sending is far simpler than receiving, as you can see if you look at the source code to SoftwareSerial.

Specifying the pin itself though is simple:

```
class MyClass : public Print {
    private:
        uint8_t _pin;

    public:
        MyClass(uint8_t pin);
        size_t write(uint8_t data);
};

MyClass::MyClass(uint8_t pin) {
    _pin = pin;
}

size_t MyClass::write(uint8_t data) {
    // In here you do whatever you have to in order
    // to manipulate _pin in the right way to send your data.

    // Don't forget to return the number of bytes written (there
    // is only one, so either 1 for "it got sent" or 0 for "it
    // didn't get sent".
    return 1;
}

```

It can be quite useful to have a `begin()` function for setting things up, such as configuring the right `pinMode()` for `_pin`, and maybe setting a baud rate like `Serial` does (although for simplicity you may choose to just have a single fixed baud rate, which means you can pre-calculate delay loops etc).
> 1 votes

# Answer
The parent class (your class, in this case) provides read() and write() functions which in turn, know what ports to use. Presumably those were provided to the parent class' constructor. Now the Print class just has to know the standard function names.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Using 8-bit instead of 16-bit in Adafruit library
I tried to modify the Adafruit\_GFX and Adafruit\_ST7735 libraries to make the color variable( as shown in code below) to use 8-bit instead of 16-bit for displaying 8-bit color on LCD screen.

```
void Adafruit_ST7735::pushColor(uint16_t color) {
 #if defined (SPI_HAS_TRANSACTION)
   SPI.beginTransaction(mySPISettings);
 #endif
  *rsport |=  rspinmask;
  *csport &= ~cspinmask;

   spiwrite(color >> 8);
   spiwrite(color);

   *csport |= cspinmask;
 #if defined (SPI_HAS_TRANSACTION)
   SPI.endTransaction();
 #endif
}

```

I changed it to the below

```
void Adafruit_ST7735::pushColor(uint8_t color) {
  #if defined (SPI_HAS_TRANSACTION)
   SPI.beginTransaction(mySPISettings);
  #endif
   *rsport |=  rspinmask;
   *csport &= ~cspinmask;

   //spiwrite(color);
   spiwrite(color);

   *csport |= cspinmask;
#if defined (SPI_HAS_TRANSACTION)
  SPI.endTransaction();
#endif
}

```

I have made similar changes in other portions of the code. This time nothing was displayed in the LCD(it was blank). However, when the spiwrite(color) is written twice i.e. the comment is removed, the code works fine. Why is there a need to write 'spiwrite' function twice even in case of 8-bit color?

The original Adafruit library files are also attached. drive.google.com/open?id=0B3x\_NfKXnhtHR0VBcTNZbk5WT0E

# Answer
Did you read the datasheet of the LCD screen? The LCD expects you to send the data in a specific format, and you should comply with that format rather than invent your own and expect it to magically understand it. If the LCD expects you to send 16 bits, you should do so. Or maybe it has a 8 bit mode and there is a way for you to tell it “I'm switching to 8-bit mode”. Read the datasheet to be sure.

If you want to display 8-bit color on an LCD expecting 16-bit, you should find a way to map the 8-bit values into 16-bit values. The most obvious way to map the range \[0, 255\] to \[0, 65535\] is to multiply the 8-bit numbers by 65535/255 = 257. Which is the same as sending the byte twice.
> 1 votes

# Answer
I think you / someone asked an identical question here recently.

you didn't say a reason why you want to change a 16-bit type to 8-bit type.

with that said, this should work:

```
void Adafruit_ST7735::pushColor(uint8_t color_msb, uint8_t color_lsb) {
   ...
   spiwrite(color_msb);
   spiwrite(color_lsb);
   ...

```

basically, the original code.
> 0 votes

---
Tags: spi
---


# Question
Title: Arduino ATmega 2560 frequency measurement
I would like to measure frequency with an Arduino 2560 board. The approach is to use a timer interrupt set to one second and pin interrupt to count interrupts in one second.

The problem I have is that I get the wrong frequency. On my frequency generator I set up a frequency of 1000 Hz in my program I get 1006 Hz instead of 1000 Hz.

What am I doing wrong?

Here is my program. In the stup method I have declared a timer. When the signal comes on pin 2, the counter is increased by 1. After one second passed the flag bData is raised. If the flag is true then I print out a frequency on serial port.

```
#include <SPI.h>
#include <Ethernet.h>
#include <Math.h>

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
const byte interruptPinTemp = 2;
const byte interruptPinSlanost = 3;
//konstante za SBE-3
const double g = 4.85442486e-003;
const double h = 6.77300393e-004;
const double i = 2.65502731e-005;
const double j = 2.06782794e-006;
const double f = 1000.0;
volatile int cnt = 0;
volatile int cnt1 = 0;
volatile double slanost = 0;
volatile double slanost1 = 0;
int timer1_counter;
boolean bData = false;
volatile int dvesek = 1;

void beriTemperatura() {
  cnt++;
}

void beriSlanost() {
  slanost++;
}

double calcTemp(double frekvenca) {
  double logRes = log(f / frekvenca);
  return 1.0 / (g + (h * logRes) + (i * pow(logRes, 2.0)) + (j * pow(logRes, 3.0))) - 273.15;
}

void setup() {
  Serial.begin(9600);       // inicializacija serijskega porta
  noInterrupts();           // disable all interrupts
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  pinMode(interruptPinTemp, INPUT_PULLUP);
  pinMode(interruptPinSlanost, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPinTemp), beriTemperatura, CHANGE);
  attachInterrupt(digitalPinToInterrupt(interruptPinSlanost), beriSlanost, CHANGE);
  TCCR1A = 0;
  TCCR1B = 0;
  timer1_counter = 34286;   // preload timer 65536-16MHz/256/2Hz
  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 << CS12);    // 256 prescaler
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();
}

//Timer interrupt na 1 sekundo
ISR(TIMER1_OVF_vect) {
  // interrupt service routine
  TCNT1 = timer1_counter;   // preload timer
  cnt1 = cnt ;               // prepisemo vrednost v cnt1
  bData = true;             // postavimo flag
  cnt = 0;  // resetiramo counter
}

void loop() {
  // če je postavljen flag, da so podatki jih izpišemo ali naredimo karkoli drugega
  if (bData == true) {
    bData = false;
    Serial.println(calcTemp(cnt1), 3);
    Serial.println(cnt1);
  }
}

```

Here is the frequency from my generator:

And here is a frequency measured with my board:

What is wrong that I get 1006 Hz instead of 1000 Hz?

If I raise the frequency for example to 5 kHz then I get 5032 Hz in my program (32 Hz to0 much).

Thank you for any advice.

# Answer
> TCNT1 = timer1\_counter; // preload timer

When you load the offset (timer1\_counter), there are some values in the timer1 prescaler (and potentially TCNT1 if the prescaler isn't sufficient large, or the input pulse train is fast). By assigning a value to TCNT1, you would have written over the values in the prescaler / TCNT1 -\> read the datasheet on that.

The solution?

1. Optimal: use a timer with auto-reload function. a timer with output compare can be adopted here as well.
2. Increment the counter: `TCNT1 += timer1_counter; // preload timer`, if timer has a 1:1 prescaler.

Or to use the timer to count the pulse and another to provide the time base.
> 1 votes

# Answer
The Arduino Mega 2560 is clocked off a ceramic resonator, which should typically have about 0.5% frequency tolerance. Your readings are off by 0.6%, which is slightly more than the typical resonator tolerance. I would them assume there is something wrong with your code, check dannyf's answer.

Now, if you want significantly better accuracy, I would argue than relying on the Arduino's internal clock is not a good idea. Even if your code is perfect you cannot expect good accuracy. You could have better results if you calibrate that clock instead of just assuming it runs at 16 MHz. But even then, ceramic resonators are notorious for having a very significant frequency drift. Or you may get an Arduino clocked off a quartz crystal instead, as these are far more stable.
> 1 votes

---
Tags: timers, frequency
---


# Question
Title: How to setup HC05 Module to be distinguishable
I'm not sure if this is a dumb question, but here goes :

I am developing an Android app that uses a custom Bluetooth device as a companion. I'm using an HC05 module to interface the device with my app. What I need is a way for me to distinguish my HC05 module from, say, some other HC05 module that might be in range.

The obvious way of doing this would be to set the device name in a certain format. But I was wondering if there was a more better approach to this.

On searching, I found that UUID's are used for a similar purpose (i.e. service discovery), but I couldn't find any further info. Is it at all possible to set a custom UUID for the HC05 module so that I can filter devices in my Android app based on that?

# Answer
Your options are:

1. As you guessed, you could set the name with `AT+NAME=`, and only use the names matching some pattern. It would work if you're only user so you just want to ignore other BT devices, but is problematic if you're having multiple independent users (each with its different set of \*HC05\*s) who might be in range (you could set different pattern for each user, though).
2. build a database of addresses (read-only with `AT+ADDR?`), and only access those devices that are belonging to that user. It would avoid problem above with multiple users, but would require some logistics on your part (for example, when you sell user the app and HC05s, in the registration process you'll need to assign exactly which HC05 address that user my access. Or you might want to allow user to pick which devices are his, by having him specify specify PIN for pairing set with `AT+PSWD=`)
3. third way is to use custom Inquire Access Code instead of GIAC so only that set of devices is scanned. HC05 allows setting it with `AT+IAC=`. However, as it is more complex and nonstandard that (2), and you'd probably still need to registration to differentiate which user is allowed which IAC, I'd recommend you do (2) instead.
> 3 votes

# Answer
As frarugi87 recommended in the comments, you need to change the device's name. Changing the device name will allow you to identify it by a custom name that you come up with. To do this you need to use something called AT Commands. Here is a guide that contains many of the system parameters that you can check and change via AT Commands: http://www.instructables.com/id/Modify-The-HC-05-Bluetooth-Module-Defaults-Using-A/?ALLSTEPS

Here is a brief summary about how to change the device name, quoted from the above Instructable:

First switch the device into command mode

> For the HC-05 module to switch to AT command mode, the HC-05 pin 34 (often referred to as the Key pin) needs to pulled HIGH but in a certain order of events explained below. When the HC-05 enters the AT command mode, it will communicate at 38400 baud rate. Follow these steps in the stated order to switch to the HC-05 to AT command mode.
>
> 1. Wire the HC-05 and Arduino Uno per instructions.
> 2. BEFORE YOU CONNECT THE ARDUINO TO THE USB remove the VCC (power) red wire from the HC-05 so it's not getting any power from the Arduino. All other wires are still connected.
> 3. Now connect the Arduino Uno to the USB cable extended from your PC.
> 4. Make sure the HC-05 module is NOT PAIRED with any other Bluetooth device.
> 5. Re-connect the Arduino Uno 5V wire to the HC-05's VCC (5V power) pin.
> 6. The HC-05 LED will blink on and off at about 2 second intervals. Now the HC-05 is in AT command mode ready to accept commands to change configuration and settings.
> 7. To test if everything is wired correctly, open the Serial Monitor from the 8. Arduino IDE and type "AT" and click SEND. You should see an "OK" If you don't see an "OK" check your wiring.

Next run this program on your Arduino

```
/*

AUTHOR: Hazim Bitar (techbitar)
DATE: Aug 29, 2013
LICENSE: Public domain (use at your own risk)
CONTACT: techbitar at gmail dot com (techbitar.com)

*/

#include <SoftwareSerial.h>

SoftwareSerial BTSerial(10, 11); // RX | TX

void setup()
{
  pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
  BTSerial.begin(38400);  // HC-05 default speed in AT command more
}

void loop()
{

  // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTSerial.available())
    Serial.write(BTSerial.read());

  // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
    BTSerial.write(Serial.read());
}

```

Finally (the quotes aren't part of the command)

> To change device name from the default HC-05 to let's say MYBLUE enter: "AT+NAME=MYBLUE"
> 1 votes

---
Tags: serial, bluetooth, hc-05
---


# Question
Title: Why is my code only reading the change of the encoder's pin A?
I am writing code for reading in a quadrature encoder. I used attachInterrupt on pin 2 and 3, but by using the same ISR.

```
    int encAPin= 2;
    int encBPin= 3;
    volatile int encAValue= 0;
    volatile int encBValue= 0;
    volatile int encCount= 0;

    void setup() {
      // put your setup code here, to run once:
      pinMode(encAPin, INPUT);
      pinMode(encBPin, INPUT);
      attachInterrupt(digitalPinToInterrupt(encAPin),encUpdate, CHANGE);
      attachInterrupt(digitalPinToInterrupt(encBPin),encUpdate, CHANGE);
      Serial.begin(9600);
    }

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

    void encUpdate() {
      if(digitalRead(encAPin)==RISING){
        if(digitalRead(encBPin)==LOW){
          encCount++;
        }else if(digitalRead(encBPin)==HIGH){
          encCount--;
        }
      }
      if(digitalRead(encAPin)==HIGH){
        if(digitalRead(encBPin)==RISING){
          encCount++;
        }else if(digitalRead(encBPin)==FALLING){
          encCount--;
        }
      }
      if(digitalRead(encAPin)==FALLING){
        if(digitalRead(encBPin)==HIGH){
          encCount++;
        }else if(digitalRead(encBPin)==LOW){
          encCount--;
        }
      }
      if(digitalRead(encAPin)==LOW){
        if(digitalRead(encBPin)==FALLING){
          encCount++;
        }else if(digitalRead(encBPin)==RISING){
          encCount--;
        }
      }
    }

```

When I tried Serial.print to check whether or not the pin A's and B's inputs were changing, I noticed that only pin A's (pin 2) input was changing. I made sure that the circuit and the wiring were all correct. Is there something about my code that is not reading pin B's input properly?

# Answer
> 2 votes
You're confusing interrupt *events* and pin *states* here.

A pin can be either HIGH or LOW. Never anything else.

An interrupt can trigger on one of four events:

1. The pin transitions from HIGH to LOW (`FALLING`)
2. The pin transitions from LOW to HIGH (`RISING`)
3. The pin transitions from one state to another (`CHANGE`)
4. The pin remains low (`LOW`)

Your code should be (as you have done) attaching the interrupt to the pins using `CHANGE` so you can see any change in the state of the pins.

Your interrupt code should then examine the two pins to see their current state.

But there is one bit missing from your code, and that is *what was the state **before** this interrupt triggered?* \- i.e., from what did the pins change from to get to this state?

The simplest way of coding this kind of thing is to think of each pin as a bit in a 2-bit binary number. Join the two pins together to form a number between 0 and 3:

```
uint8_t pinVal = (digitalRead(encBPin) << 1) | digitalRead(encAPin);

```

The truth table for that would be:

```
B | A | B<<1 | pinVal
0 | 0 |  00  |   00 (0)
0 | 1 |  00  |   01 (1)
1 | 0 |  10  |   10 (2)
1 | 1 |  10  |   11 (3)

```

There you have 4 states. And if you remember that state from one interrupt call to the next, you can compare the current value to the previous value. And that is where you get your 8 states from. Encoders use *Gray Code* so the sequence of numbers you would get as you rotate the encoder would be:

```
0, 1, 3, 2, 0, 1, 3, 2 ...

```

Or the other way:

```
2, 3, 1, 0, 2, 3, 1, 0 ...

```

And it's the transition between those values that tells you what the encoder is doing:

```
0 <-> 1 <-> 3 <-> 2 <-> 0 ...

```

Each of those transitions can go two ways, and if you count the arrows (`<` and `>`) there are 8 of them there, which are the 8 states you were thinking of before.

So if the previous value is stored in `oldVal` from the last time the interrupt triggered, and the new value is in `newVal`, your 8 states are:

* oldVal == 0 && newVal == 1
* oldVal == 1 && newVal == 3
* oldVal == 3 && newVal == 2
* oldVal == 2 && newVal == 0
* oldVal == 0 && newVal == 2
* oldVal == 2 && newVal == 3
* oldVal == 3 && newVal == 1
* oldVal == 1 && newVal == 0

The first four are progressing in one direction, the last four in the other - one set is clockwise, one is anti-clockwise.

So you could have an (untested) interrupt handler that looks something like this:

```
void encUpdate() {
    static uint8_t oldVal = 0; // Static variable to remember the last state
    uint8_t newVal = (digitalRead(encBPin)) << 1 | digitalRead(encAPin);

    if (
        (oldVal == 0 && newVal == 1) ||
        (oldVal == 1 && newVal == 3) ||
        (oldVal == 3 && newVal == 2) ||
        (oldVal == 2 && newVal == 0)) {
            encCount++;
    } else {
        encCount--;
    }
    oldVal = newVal;
}

```

You notice I've only implemented the comparison for the first four states and not the last four. Since there are only 8 states, and those states cause one of only two things to happen, if it's not one of the first four states, which would increase your count, it must then be one of the last four states which decrease your count. No point in checking for them since it can't be anything else. If you turned it clockwise then increase the value. Otherwise you must have turned it anti-clockwise since there is no other direction you can possibly turn it in, so decrease the count.

This is precisely why Gray Code is used - only one pin ever changes at a time, so there is no ambiguity in what has happened - either you turned it one code-point in one direction or you turned it one code-point in the other. Even if there is lots of bounce it will just bounce between two neighbouring code-points and settle on the final new code point (as long as the interrupt can react fast enough to catch all the bounces).

---
Tags: interrupt, rotary-encoder
---


title: Different functions using 2 buttons

text:
# Question
Title: Different functions using 2 buttons
I'm currently learning Arduino. So right now I'm trying to create an Arduino app that will use buttons, LEDs and RGB.

So I have 2 buttons, 8 LEDs and an RGB. The first button is the function switcher: when you press it the LED will light according to their function. The second button is the function activator so right now here's I want to do:

* Function 1: Turn on/off RED light
* Function 2: Increase RED light brightness by 5; if already at 255, reset at 0
* Function 3: Turn on/off GREEN light
* Function 4: Increase GREEN light brightness by 5; if already at 255, reset at 0
* Function 5: Turn on/off BLUE light
* Function 6: Increase BLUE light brightness by 5; if already at 255, reset at 0
* Function 7: Turn on ALL lights, all brightness to 255
* Function 8: Turn off ALL lights, all brightness to 0

I already started coding and I'm stuck at turning on and off the red light. Here's my code:

```
const int red = 5;

int b1, b2; //Buttons
int dir = 0;
int light = 11;
int func = 0;
boolean buttonValue = true;
boolean buttonState = true;

void setup() {
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(red, OUTPUT);
  for (int i = 11; i <= 18; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {
  b1 = digitalRead(2);
  if (b1 == HIGH) {
    dir = 2;
    func++;
    if (func >= 8)
      func = 0;
    } else {
      dir = 0;
    }
    digitalWrite(light, LOW);
    if (dir == 2 && light < 18) {
      light++;
    }
    digitalWrite(light, HIGH);
    delay(200);
  }

void function(int pin) {
  b2 = digitalRead(3);
  switch (func) {
    case 1:
      if (b2 = true) {
        digitalWrite(5, HIGH);
      } else {
        digitalWrite(5, LOW);
      }
  }
}

```

# Answer
> 1 votes
I have to be honest after reading you description and looking at you code I have no idea how you arrived at the code you have arrived at.

For now lets try a much simpler bit of code, once that is working you can build on it.

```
#define PIN_BUTTON_1    2
#define PIN_LED_RED     5

void setup() {
    pinMode(PIN_BUTTON_1, INPUT);
    pinMode(PIN_LED_RED, OUTPUT);
}

void loop() {
    const int buttonState1 = digitalRead(PIN_BUTTON_1);
    digitalWrite(PIN_LED_RED, buttonState1);
    delay(200);
}

```

If that code doesn't work then there is something wrong electrically.

I think is the next step you were trying for:

```
#define PIN_BUTTON_1    2
#define PIN_LED_RED     5

int lastButtonState1 = LOW;
int functionNumber = 0;
int currentLedValue = 0;

void setup() {
    pinMode(PIN_BUTTON_1, INPUT);
    pinMode(PIN_LED_RED, OUTPUT);

}

void loop() {
    const int currentButtonState1 = digitalRead(PIN_BUTTON_1);
    if (lastButtonState1 != currentButtonState1)
    {   // If the button's state has changed
        if (currentButtonState1 == HIGH)
        {
            ++functionNumber;
        }
        lastButtonState1 = currentButtonState1;
    }
    DoFunction(functionNumber);
    delay(200);
}

void DoFunction(const int& function)
{
    switch (function)
    {
    case 1:
        if (currentLedValue > 0)
        {
            currentLedValue = LOW;
        }
        else
        {
            currentLedValue = HIGH;
        }
        digitalWrite(PIN_LED_RED, currentLedValue);
        break;
    case 2:
        currentLedValue = 128;
        analogWrite(PIN_LED_RED, currentLedValue)
        break;
    default:
    }
}

```

# Answer
> 0 votes
If you would like to call the function you defined at the end of your code you need to give it a name `function name()...`.

In your code you used `if (b2 = true)`. That will not work as expected, since it sets the `b2` variable to `true`. Note the `if` expressions use `==` to compare values, see the Arduino Reference. Further you should use the `HIGH` and `LOW` Pin level constants for comparing pin states as described here.

So your code will look like `if (b2 == HIGH) {
 digitalWrite(5, HIGH);
 } else {
 digitalWrite(5, LOW);
 }`

or shorter just: `digitalWrite(5, b2);` without the if/else expressions.

---
Tags: arduino-uno, led, rgb-led
---


# Question
Title: How to have some code executed at a certain time of day with a DS3231 RTC?
I recently bought a DS3231 RTC, but I cannot seem to figure out how to get it to work. I have tried all different tutorials and example programs but I keep getting `2165.25.165 165:165:165` as the output.

I am using an Arduino Micro, with the RTC connected as follows:

* GND \> GND
* VCC \> 5V
* SDA \> A4
* SCL \> A5

**Project details:**

The project uses a 16x2 LCD to display the time of day, and a countdown to the next occurrence of 06:00. Then at 6 it will allow for a button to be pressed to open a servo and do other things. I got temporary test code to work using `millis()`, but it is only displaying a 12-hour countdown in seconds, and I would like to replace it with a more reliable RTC.

# Answer
> 3 votes
SDA and SDL pins on an Arduino Micro are on pins D2 and D3 as mentioned on the official page:

> TWI: 2 (SDA) and 3 (SCL). Support TWI communication using the Wire library.

and shown on this pinout reference:

# Answer
> 5 votes
If you are getting 165:165:165 that indicates usually a problem with your I2C bus. But it might also be a power problem in the RTC.

In any case, check your wiring.

Your processor is simply not properly communicating with the RTC. If the RTC's red light is on then check your wiring and make sure you haven't reversed SDA and SCL.

Also, the DS3231 has and most Arduinos have enough pull-up that you won't need external pull-up resistors in order to communicate directly with the DS3231.

Try plugging it straight into the Arduino - go minimalist and make that work before adding other devices to the I2C bus like a LCD display. Set the clock by code and watch it in the serial monitor.

Once you're sure the RTC is not a problem then you can go from there with the I2C bus. It is certainly possible for other devices on the bus to cause the RTC to be unable to respond correctly. For a short-range I2C bus that includes the DS3231 don't add any external pullups.

The most reliable RTC for Arduino is the DS3231, but if you bought it via the slow boat you might try a voltmeter to verify the battery so it keeps time even when powered down.

And of course, it is only as accurate as you program it to be. When I program my DS3231s, I always add a couple of minutes to the current time to allow for the time to fix forgotten semicolons and such before it gets around to actually programming the device.

One last note: The program will run when you open the serial monitor. So that will be when it sets the time then begins to display it.

# Answer
> 1 votes
Your question doesn't match your title so I will go with your title.

> How to have some code executed at a certain time of day with a DS3231 RTC?

The typical approach is to set an alarm on the RTC (to the extent that it supports it), and process that interrupt from the RTC on the MCU side.

Alternatively, you can poll the time on the RTC periodically and once the time is up, do your thing.

---
Tags: arduino-micro, rtc
---


# Question
Title: Best way to send text to ESP8266 remote display
I need a remote display to show information sent via WiFi from another ESP8266. What needs to be sent is a string along with some variables, for example a string to be displayed along with two integers for the position on the display:

```
0, 12, "message to display on screen"

```

As I am absolutely new to network stuff, what would be the best way to achieve this?

* Sending a POST request through REST API?
* Use UDP instead?
* Or better use a framework like MQTT?

# Answer
> 0 votes
Try the esp8266 UDP messages

With UDP you can send and receive messages quite easily and without consuming lots of resources.

---
Tags: esp8266, wifi, communication, display, networking
---


# Question
Title: Ethernet Shield 2 data to PHP server doesn't work
I am trying to send data via GET to my PHP server from my Ethernet Shield2. This is part of my sketch:

```
char myserver[] = "www.myserver.com/";
if (client.connect(myserver, 80)) {
  Serial.print("Connected to ");
  Serial.println(myserver);
  client.print("GET /arduino/controller.php?");
  client.print("air_temp=");
  client.print(DS18B20_temperature);
  client.println(" HTTP/1.1");
  client.print("Host: ");
  client.println(myserver);
  client.println("Connection: close");
  client.println();
  client.println();
} else {
  // if you didn't get a connection to the server:
  Serial.println("Connection failed to Server");
}

```

The serial monitor displays "Connect to myserver.com" but my PHP code doesn't seem to receive the `air_temp` value from DS18B20\_temperature. I checked this value and it's true.

However, when I try `myserver.com/arduino/controller.php?air_temp=25` in my browser, the PHP code is running well.

What's going wrong with my code?

# Answer
> 0 votes
I just removed the line server.begin() and it's works !!! Thanks.

---
Tags: arduino-uno, shields
---


# Question
Title: Error while trying to drive relay through the state of a digital input pin in Arduino
I'm trying to change the state of a relay according to the state of a digital input in an Arduino with an ethernet shield. It works sometimes and some other times it doesn't work.

**My code:**

```
const int led1 = 2;
const int enable1 = 4;
boolean led1_OnOff;

void setup() {
  led1_OnOff = false;
  pinMode(enable1, INPUT);
  digitalWrite(enable1, LOW);
  pinMode(led1, OUTPUT);
}

void loop() {
  if(digitalRead(enable1) == HIGH) {
    if(led1_OnOff == true) {
      led1_OnOff = false;
    } else {
      led1_OnOff = true;
    }
  }

  if(led1_OnOff == true)
    digitalWrite(led1, HIGH);
  else
    digitalWrite(led1, LOW);
}

```

**My schematics:**

Relay 5v -\> arduino 5v Relay gnd -\> arduino gnd Relay in -\> digital pin 2 Relay com -\> 220 AC Relay NC -\> 220 AC Push button pin 1 -\> Arduino 5v Push button pin 2 -\> digital pin 4

Pin 2 is connected to the relay enable pin and pin 4 is connected to a push button and the boolean is used for saving the state.

Can anyone tell me what the problem is, and why the relay doesn't work most of the time?

# Answer
I modified my code and added some code for button debounce and added 10k ohm pull down resistor to my hardware and it works like a charm now.

**my new code :**

```
const uint8_t led1 = 6;
const uint8_t enable1 = 7;
const uint16_t buttonConfidenceLevel = 500;
boolean led1_OnOff;

uint16_t pressedConfidenceLevel;
uint16_t releasedConfidenceLevel;
boolean pressed;

void setup() {
    led1_OnOff = false;
    pinMode(enable1, INPUT);
    pinMode(led1, OUTPUT);

    pressedConfidenceLevel = 0;
    releasedConfidenceLevel = 0;
    pressed = false;
}

void loop() {
    if(isButtonPressed()) {
        // Button is pressed
        led1_OnOff = !led1_OnOff;

        if(led1_OnOff == true)
          digitalWrite(led1, LOW);
        else
          digitalWrite(led1, HIGH);
    }

}

boolean isButtonPressed() {
    if(digitalRead(enable1) == HIGH) // button is sensed pushed down
    {
        releasedConfidenceLevel = 0;

        if(pressed == false)
        {
            pressedConfidenceLevel++;

            if(pressedConfidenceLevel > buttonConfidenceLevel)
            {
                pressedConfidenceLevel = 0;
                pressed = true;

                // Button is pressed
                return true;
            }
        }
    }
    else // button is sensed released
    {
        pressedConfidenceLevel = 0;

        if(pressed == true)
        {
            releasedConfidenceLevel ++;

            if(releasedConfidenceLevel > buttonConfidenceLevel)
            {
                releasedConfidenceLevel = 0;
                pressed = false;
            }
        }
    }

    return false;
}

```
> 0 votes

# Answer
Assuming your circuit is correct (and perhaps it is, since you imply that it works *some* of the time), the first obvious problem is that when you press the button, the code will repeatedly toggle the output, very very fast. It may seem to you like you're only pressing the button for a moment, but the code will loop many many times. When you release the button, it's a 50/50 chance whether it leaves the relay on or off.

To solve this, you can wait until the button is released before checking again.

In addition to this, you may have switch bounce. There are nicer ways of fixing this, but for your stated purpose, waiting 0.1s after a releae before checking the button again is probably sufficient.

```
....
void loop() {
  if(digitalRead(enable1) == HIGH)
  {
    if(led1_OnOff == true)
    {
      led1_OnOff = false;
      //+digitalWrite(led1, LOW);
    }
    else
    {
      led1_OnOff = true;
      //digitalWrite(led1, HIGH);
    }

    // Wait for the button to be released
    while(digitalRead(enable1) == HIGH)
    {
      // do nothing, just wait
    }
    // Poor-man's debounce
    delay(100);
  }

  if(led1_OnOff == true)
    digitalWrite(led1, HIGH);
  else
    digitalWrite(led1, LOW);
}

```
> 0 votes

# Answer
First, how you are set a pin as input and **write** in this pin?

> pinMode(enable1, INPUT);
>
> digitalWrite(enable1, LOW);

You dont need compare a boolean with true

> if(digitalRead(enable1) == HIGH)

is the same as:

```
if(digitalRead(enable1))

```

use a debbounce with a button state flag to change the button state

```
if( digitalRead(enable1))
       ena_deb++;
       if(ena_deb > 5){
            change_en_state
       }
}else{
    change_en_state = 0
}

if(change_en_state == X)
    change_output_value;

```
> 0 votes

---
Tags: arduino-mega, relay
---


title: Garbled serial from GPS device

text:
# Question
Title: Garbled serial from GPS device
I'm using an Arduino Uno. "Regular" serial is plugged into my computer, and I can receive just fine.

I'm using AltSoftSerial (tried SoftwareSerial, same results) with RX and TX on pins 8 and 9 to interface with a BR-355S4 GPS module. According to the data sheet on that module, the RX and TX are at 5v, which I believe is what the Arduino expects.

I combined the Serial and SoftwareSerial examples to test the connectivity from the Arduino to my PC and from the GPS to the arduino.

```
#include <AltSoftSerial.h>
AltSoftSerial altSerial;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(19200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  printAsciiTable();

  altSerial.begin(4800);
}

void printAsciiTable(){
  Serial.println("ASCII Table ~ Character Map");
  int thisByte;
  for(thisByte = 33; thisByte < 127; thisByte++){
    Serial.write(thisByte);
    Serial.print(", dec: ");
    Serial.print(thisByte);
    Serial.print(", hex: ");
    Serial.print(thisByte, HEX);
    Serial.print(", oct: ");
    Serial.print(thisByte, OCT);
    Serial.print(", bin: ");
    Serial.println(thisByte, BIN);
  }
  Serial.println("~~Done with ASCII Table~~");
}

void loop() {
  char c;
  if(altSerial.available()){
    c = altSerial.read();
    Serial.print(c);
  }
}

```

The data coming into the Serial Monitor tool looks fine until it starts pulling from the GPS serial stream (ellipses added by me):

> ...
> |, dec: 124, hex: 7C, oct: 174, bin: 1111100
> }, dec: 125, hex: 7D, oct: 175, bin: 1111101
> ~, dec: 126, hex: 7E, oct: 176, bin: 1111110
> ~~Done with ASCII Table~~
> 4™5f3y=›ùÙ)É9Ó¦Ì™¦ ...

I would like to receive the correct NMEA strings from the GPS module on altSerial and push them out to Serial. The garbled nature of the serial data looks like a baud rate issue, but I've tried a handful of combinations for Serial and altSerial speed with no success. Any ideas?

# Answer
I looked up the datasheet and product specs for the GPS device. It says that the output is RS-232. Note that RS-232 is NOT compatible with the Arduino levels. Arduino "talks and listens" at 5V or 3.3V depending on which board you're using. So what you need is a RS-232-to-TTL converter. Now, TTL speaks Arduino. So Arduino will be able to understand that. So try using a MAX232 IC or a shield, whichever you're comfortable with.
> 1 votes

# Answer
You can get 5V TTL USB serial adaptors. The classic being an FTDI one. Also you can get the MAX chip level converters as a tiny module, if you already have a normal RS232 adaptor. I would recommend connecting the GPS to your PC as a reality check. The garbled that you are seeing is typical Baud rate issues.

Also there can be polarity issues with the signal. (Not sure if you can switch the pin polarity of the Arduino in software.) So if you are connecting to a standard RS232 adaptor I think the MAX chips are available in inverting and none inverting versions.

Some PC RS232 adaptors are 5V tolerant. Google this for confirmation. You should just connect the GPS tx to the PC RX if you try this. (And 0V obviously.)
> 1 votes

# Answer
In the comments I see that is not clear how you connect the module in your arduino. The native mode is PS2 (old mouse and keyboard) you can use that directly with your arduino (PS2 protocol is 5v too), for this, you need implement a clock/data protocol. If you use the rs-232 converter, notice that RS-232 as a amplitude from -12v ~ 12v this burn your arduino, so you need use a rs232-ttl converter.

Serial software are not a good choise, if you use that, save your data in a buffer and write only one time, in the end.
> 1 votes

---
Tags: arduino-uno, serial, softwareserial, rs232
---


title: Serial Connection to Phone Line

text:
# Question
Title: Serial Connection to Phone Line
I was hoping to create a cheap security system by connecting an Arduino to the phone line output of a base station.

Since the base station should call a phone number if the alarm is tripped I wouldn't have to do much hardware hacking so long as I can read/parse the output from the base station.

My question is can I read serial output from a phone line like this?

# Answer
> 2 votes
Phone lines run off of the RS-232 telecommunications protocol which can run off -25v to 25v, which would completely destroy your Arduino. Luckily there is an IC made to help you with that. You can use the MAX3232 IC to convert RS-232 to TTL 5v or 3.3v (Same chip can do either). Look at providers like Digikey for just the chip or you can get a breakout from providers like SparkFun.

TL;DR Yes, but you need a special IC to not fry your Arduino.

---
Tags: serial
---


title: Why does "!=LOW" != "HIGH"?

text:
# Question
Title: Why does "!=LOW" != "HIGH"?
I'm learning about accessing ports directly on the ATMEGA 328 using an Arduino Uno. The program sets up pin 13 as an output and pin 2 as an input. I then enable the pull up resistor on pin 2.

I read Pin 2 and set the LED high or low depending on if pin 2 is high or low.

**Why is it that I cannot seem to use == HIGH in my if statement instead of != LOW?**

```
void setup() {
  MCUCR &= ~(1 << 4); //disables pull-up disable (redundant as default is off)
  DDRB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as output
  DDRD &= ~(1 << 2); //sets pin 2 (D2 on ATMEGA 328) as input (redundant as default is input)
  PORTD |= (1 << 2); //since it's an input sets pull-up resistor ON
  PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW

}

void loop() {
  if ((PIND & (1 << 2)) != LOW) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH
  else PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW
   delay(100);

}

```

# Answer
> 2 votes
Because

```
((PIND & (1 << 2)) != LOW)

```

means exactly

```
(PIND & 4) != 0

```

and that is true if PIND is 4, 5, 6, 7, 12, 13, ... (any number having 4 in it binary), so it yelds

```
4 != 0

```

Which is definitively not equal

```
4 == 1

```

---

BTW: in C any integer != 0 is true and 0 is false, so you can as well write:

```
if (PIND & (1 << 2)) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH

```

# Answer
> 1 votes
```
if ((PIND & (1 << 2)) != LOW) PORTB |= (1 << 5); //sets pin 13 (B5 on ATMEGA 328) as HIGH
  else PORTB &= ~(1 << 5); //sets pin 13 (B5 on ATMEGA 328) as LOW

```

PIND & (1\<\<2) will return a value of either (1\<\<2) if PD.2 is high, or 0 if PD.2 is low.

So it basically says that if PD2 is high, set PB5; otherwise, clear PB5.`enter code here`

---
Tags: port-mapping
---


# Question
Title: Arduino digital output pin controling relay problem
I try my code to change the state of a relay on pushing a push button buy checking the state of a digital pin.

**My code :**

```
const int led1 = 6;
const int enable1 = 7;
boolean led1_OnOff;
long now;
int minSecsBetweenUpdates = 1; // 1 seconds
long lastSend = -minSecsBetweenUpdates * 1000l;

void setup() {
  led1_OnOff = false;
  pinMode(enable1, INPUT);
  pinMode(led1, OUTPUT);
}

void loop() {
  now = millis();
  if (now > (lastSend + minSecsBetweenUpdates * 1000l))
  {
    if(digitalRead(enable1) == HIGH)
    {
      lastSend = now;
      if(led1_OnOff == true)
      {
        led1_OnOff = false;
        //+digitalWrite(led1, LOW);
      }
      else
      {
        led1_OnOff = true;
        //digitalWrite(led1, HIGH);
      }
    }
  }

  if(led1_OnOff == true)
    digitalWrite(led1, HIGH);
  else
    digitalWrite(led1, LOW);
}

```

But the code keeps on looping and the relay keep changing it's state as if pin 7 is always high, I'm sure of my schematic but I don't know what's wrong with my code.

**for those who want my schematic:**

# Answer
> 2 votes
Your problem is that you are basically saying "while the pin is HIGH toggle the relay" rather than "When, and only when, the pin *transitions from LOW to HIGH* do I toggle the relay".

To do that you must remember what state the pin was in during the last iteration:

```
const uint8_t led1 = 6;
const uint8_t enable1 = 7;

void setup() {
    pinMode(enable1, INPUT);
    pinMode(led1, OUTPUT);
}

void loop() {
    static bool led1_OnOff = false;
    static bool lastValue = digitalRead(enable1);

    bool currentValue = digitalRead(enable1);

    if (currentValue != lastValue) {
        lastValue = currentValue;
        if (currentValue == HIGH) {
            led1_OnOff = !led1_OnOff;
            digitalWrite(led1, led1_OnOff);
        }
    }
}

```

# Answer
> 1 votes
You say your switch is between pin 7 and +5v. Therefore you will need a pull-down resistor on pin 7.

You say that setting pin 7 to an output works. However you are very likely to burn out the output like this. A pull-down resistor is the way to go.

---
Tags: arduino-mega, relay
---


title: Arduino Mega read data from USB

text:
# Question
Title: Arduino Mega read data from USB
I´m completely new to the arduino and not used to work with it. Due to an project I need to know the best way to transfer Data to my Arduino Mega. The transferred file will be an sliced 3D object. Is it possible to use the built in USB port to read from a stick? Or do I have to use a PC to transfer my data?
Please help me to answer this question since I have no clue how to manage to get the sliced file to my Arduino.

# Answer
> 1 votes
The Arduino Mega doesn't support USB-host, so you can't connect a USB stick directly.

The easiest way is to connect it to a computer, and send the data over the serial connection.

---
Tags: serial, arduino-mega, usb
---


title: Serial Connection

text:
# Question
Title: Serial Connection
I was trying to communicate with my arduino uno over the serial connection from the USB. Connecting to it is usually not a problem, but what buggs me is the first transaction of the data... No matter with what I do it, java code or the serial monitor which comes with the IDE, I always have the problem that usually only one Byte is being transfered or received from the Arduino. What could be the problem? Is it just a bug and I have to live with it or can this somehow be fixed?

My Arduino Code:

```
#include "RGBdriver.h"
#define CLK 10
#define DIN 11

RGBdriver driver(CLK, DIN);
byte red = 0;
byte green = 0;
byte blue = 0;

byte newRed = 0;
byte newGreen = 0;
byte newBlue = 255;

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

void loop() {
  if (Serial.available() >= 3) {
    newRed = Serial.read();
    newGreen = Serial.read();
    newBlue = Serial.read();
  }

  if ((red != newRed) || (green != newGreen) || (blue != newBlue)) {
    red = newRed;
    green = newGreen;
    blue = newBlue;

    driver.begin();
    driver.SetColor(red, green, blue);
    driver.end();
  }
}

```

# Answer
Consider giving sufficient delay to initiate the time to receive the data. The loop would otherwise terminate since the data received is less than 3
> 1 votes

---
Tags: arduino-uno, serial, java
---


title: Arduino rc plane logger

text:
# Question
Title: Arduino rc plane logger
Well, I want to make an rc plane with an arduino that logs to an sd card
A) Video
B) Accelerometer data
C) Tempature
D) Humitity
E) Atmospheric pressure
F) Gyroscope Data
What arduino/parts should I use? I have a maximum of 170 grams or 6 OZ. The arduino will not control the plane, just log data. I'm thinking an arduino 101... but I would like to know if there is a lighter/better way.
THANKS! :)

# Answer
> 2 votes
It is not an Arduino answer but a Raspberry Pi with a Sense hat will record most of what you need with little coding. Add a Pi camera and you have all this for about $100. The Sense Hat temperature sensor doesn't work because it is too close to the CPU but you could get a digital thermometer for a few bucks.

# Answer
> 0 votes
I've completed a similar project.

---
Tags: sd-card, accelerometer, gyroscope, 101
---


# Question
Title: Pulldown resistors and multiple switches
Maybe this is a question for Electronics SE but I’m not a member there yet so hopefully someone will have an answer here.

I did an experiment with having some push-to-make buttons connected to my Uno. I copied the circuit from the aduino.cc website and all worked exactly as expected. Here is my schematic of the circuit as I have it now:  The pins are both held LOW by the Pulldown resistor until the switch is closed, when they go HIGH. All well and good. But I’ve just been looking at the circuit and something puzzles me. I can see a direct connection from Switch 1 to Pin 2 VIA the resistors and the Ground connection – and vice versa, S2 to P1. See my pathway in Red here:

Now, to be clear, this is NOT happening – but I just want to understand why not. Is it just that the 2 resistors in combination provide enough resistance to stop the opposite pin from going HIGH? In which case, this Pulldown resistor is actually serving 2 completely different functions in the circuit…?

# Answer
> 1 votes
An input pin is in what is known as *high impedance* mode. That is, to all intents and purposes, to the external circuit it looks like a massive resistor to ground.

This resistance can be in the millions of ohms.

So let's redraw your circuit with those input pins as big resistors:

simulate this circuit – Schematic created using CircuitLab

Now you can see how the schematic really looks (see how it's set up so +5V is at the top and GND is at the bottom - the \[conventional\] current flows then from top to bottom).

So with SW2 pushed (as shown) the current wants to flow from 5V (top) to GND (bottom). That goes through SW2, through R2, and down to ground. Some tiny amount also flows through R4, which represents the input pin. Since by then the current is already at ground and has reached its destination there is no reason at all for it to then flow back up through R1, and back down to ground again through R3. For current to flow through R1 the voltage at IN1 would have to be negative since current will only flow from a higher to a lower voltage. And since it isn't negative, no current can flow.

# Answer
> 2 votes
Call the resistors R1 and R2, the negative terminal Ground, and the positive terminal V+. The junction of R1 and R2 is connected to Ground. This holds the resistor ends at the junction to zero volts relative to ground. Ignoring P2 for the moment, the other end of R2 is open circuit to V+ when S2 is open. Applying Ohm's law, we have a finite resistance in series with an infinite resistance, so zero volts across R2 when S2 is open. Thus one sees that voltage across R2 is not affected by voltage changes across R1.

P2 as an input is not completely an open circuit; typically its effect is similar to a multi-gigaohms resistor to some voltage between Ground and V+.

*Edit:* More directly, observe that the voltage at the Ground ends of R1 and R2 is zero and remains at zero no matter what S1 and S2 do. Thus, operation of S1 does not affect voltage at P2, and operation of S2 does not affect voltage at P1.

# Answer
> 1 votes
It helped me to draw an equivalent schematic to yours when S1 is closed and S2 is open. P2 is neither high nor low by itself; it is a high-impedance (which is why you need a pulldown or pullup resistor). It is pulled to ground by R2 and the fact that the junction of the two resistors is grounded. If you disconnected that junction from ground, P2 would see a 20K pullup, but as it is, the (left) end of R2 stays at ground, regardless of what you apply to the P1-R1 junction.

simulate this circuit – Schematic created using CircuitLab

# Answer
> 0 votes
A simple rule of thumb is that electricity always follows the path of least resistance. The energy going over the switch has a lower resistance path to ground through the Arduino than it does through the pull-down resistor, so it will prefer to go that way than through one - or both resistors when it is available.

---
Tags: switch, electricity
---


# Question
Title: How do I configure the Arduino IDE to look for source code in a subdirectory within the directory that holds my sketch?
I'm writing an Arduino program that contains various .h and .cpp files. Due to organizational needs, I have configured the directory that contains my Arduino sketch (.ino) to possess a subdirectory. This subdirectory contains related source code.

An example layout of my project directory is located below:

```
mysketch
    mysketch.ino
    mycode.h
    mycode.cpp
    mylibs
        mylib1.h
        mylib1.cpp
        mylib2.h
        mylib2.cpp
        mylib3.h
        mylib3.cpp

```

With this, I'm able to successfully #include the header files. However, the compiler then complains that mylib1.cpp, mylib2.cpp, and mylib3.cpp are not defined (however they are). I'm guessing that the Arduino only looks for source files within the same directory that the sketch lives in. Thus subdirectories contains source code are ignored.

I can then modify my directory layout such that all of the 'mylib.h/.cpp's' are in the same directory and the project compiles fine.

So my question: how do I configure the Arduino IDE to reference source code within a subdirectory? Also, I would prefer that the mylibs exist within the same directory, and not within the Arduino 'library' directory. This will allow me to then easily distribute the code as a single zipped folder.

# Answer
> 1 votes
In the Arduino IDE the answer is simple: you can't.

The Arduino IDE doesn't compile within the directory your sketch is in. Instead it writes out a fresh copy of all the files directly from the tabs in the IDE into a temporary build folder (munging them as it goes if they are .INO or .PDE) and then compiles them there. Anything else within your sketch folder is completely ignored.

If you want that kind of functionality you will have to use a different IDE.

For example, UECIDE lets you have a structure like:

```
MySketch/
    MySketch.ino
    libraries/
        MyLib1/
            MyLib1.h
            MyLib1.cpp
        MyLib2/
            MyLib2.h
            MyLib2.cpp

```

# Answer
> 1 votes
The behavior of the Arduino IDE with this sort of thing has changed over time so it depends on which version of the Arduino IDE you're using. With recent versions you can put the files in a `src` subfolder of your sketch folder and then do:

```
#include "src/mylib1.h"

```

or:

```
#include "src/mylib1/mylib1.h"

```

depending on how you want to organize the folder structure.

When doing this you may find that Arduino libraries often use incorrect include syntax in their source code. For example in mylib1.cpp:

```
#include <mylib1.h>

```

although wrong, would still work if the library was located in one of the Arduino libraries folders but with the library located in the sketch folder this no longer works and you need to change it to:

```
#include "mylib1.h"

```

---
Tags: arduino-ide
---


# Question
Title: Measure the duration a pin is in a HIGH state
I'm struggling with getting the button configuration. Simply, I have a LED controlling setup for a button to increase its brightness when pressed. However, I would like to have it setup like this:

1. When button is pressed.
2. change the value by 1,
3. wait for 500ms,
4. Then go fast (with the usual void loop time).

Is it something to do with interrupts? If I just write it like below, it actually (obviously) goes by +1 by itself, even when button is not pressed.

```
void loop() {
  if(digitalRead(button_pressed) == HIGH) {
    current_state = current_state+1;
    delay(500);
    current_state = current_state+1;
  }
}

```

# Answer
> 1 votes
Non-blocking version.

```
bool old_button_state = LOW;
void loop()
{
    if(digitalRead(button_pressed) == HIGH)
    {
        current_state = current_state+1

        if( old_button_state==LOW )
            delay(500); // long delay
        else
            delay(100); // short delay

        old_button_state = HIGH;
    }
    else
    {
        old_button_state = LOW;
    }
}

```

Simplistic version.

```
void loop()
{
    if(digitalRead(button_pressed) == HIGH)
    {
        current_state = current_state+1
        delay(500);// long delay

        // repeat while the button is being pressed
        while(digitalRead(button_pressed) == HIGH)
        {
            current_state = current_state+1
            delay(100); //short delay
        }
    }
}

```

Ideally you wouldn't just wait for 500ms, but 'break out' of this delay as soon as the button is released.

# Answer
> 1 votes
```
long timenow, timelong=500;
int current_state = 0;
void increase_state()
{
    current_state++;
    Serial.println(current_state);
}

void loop()
 {
    if(digitalRead(button_pressed)) //button is pressed
    {
        timenow=millis();   //get current time
        increase_state(); // increase by 1
        while (digitalRead(button_pressed)) //check if the button is still pressed
            {
                //rapidly increase "current_state" by 1 if button is pressed more than 500ms with interval of 50ms.
                if ((millis()-timenow)>timelong)
                {
                increase_state();
                delay(50);
                }
            }
    }
    delay(500)
 }

```

The increment of `current_state` is always by 1. If button is pressed, it will always increase by 1, but if it's not a long press, you have to wait another 500ms to increase it values again.

# Answer
> 0 votes
> Fairly simple.

I thought I would lay out my code here so it is more clear.

```
if (BTN_PRESSED()) {            //button is pressed now
    btn_cnt += 1;               //increment button counter
    if (btn_cnt >= BTN_LONGPRESS) {
        volume += VOLINC_FAST;  //btn has been pressed for a long time, so increment volume fast
    } else {
        volume += VOLINC_SLOW;                              //otherwise increment the button slowly
    }
} else btn_cnt = 0;             //button is not pressed so reset the counter

```

It basically follows what I laid out earlier and is self explanatory, I hope.

Formatting needs more work, obviously.

edit: reformatted the code a little bit to make it more readable.

here is an example of this code at work:

here, the code is used to detect a button press (active low) on RA0. Once the button counter (btn\_cnt) has been pressed sufficiently long (set by BTN\_LONGPRESS), it increments volume by VOLINC\_FAST (=4); otherwise, it increments volume by VOLINC\_SLOW (=1).

the simulation shows just that. the value of volume is output on PB0..7, to a dac to show more graphically what happens to volume's value.

1) when the button is high (=not pressed), volume is not changed and you see a flat line on the DAC output; 2) when the button is just pressed (but not sufficient to trigger BTN\_LONGPRESS), volume is incremented slowly and you see the DAC's output goes up slowly (1 at a time); 3) when the button is pressed long enough, volulme is incremented fast and you see the DAC's output goes up much steeper.

Obviously, you can modulize the code so it can process multiple buttons and return multiple states - not pressed, pressed, long pressed, double pressed. or if you wish, allow it to process bounces.

all sorts of possibilities but the basic idea is the same.

---
Tags: arduino-uno
---


title: Low Power Pin Change Detection (ATtiny)

text:
# Question
Title: Low Power Pin Change Detection (ATtiny)
I want to use an ATtiny as data logger for the opening and closing of a door/window. For that I am using a reed-switch. Since I want to run it from a 3V coin battery, long term power consumption is crucial. Therefore the ATtiny (currently 13A) is in system down mode most time and is only listening to Pin-Change-Interrupts. Depending on the state of the reed-switch the power consumption differs in an order of magnitude.

* switch open: 0.1µA
* switch closed: 74.5µA
* my Multimeter has a tolerance of ±0.1µA

This is a difference of an order of magnitude. But it is plausible as the datasheet of the ATtiny13A states in chapter 10 that a GPIO pin can only be pulled up and is otherwise dangling. The pull-up resistor is somewhere between 20k and 50k as stated in chapter 18.2.

So in my setup the pin is pulled up and the reed-switch is grounded.

How can I reduce the power consumption in the case where the switch is closed?

Alternatively: Can I somehow revert the state of the switch, as windows and doors are closed most of the time?

The MCU is running with the 128kHz internal Clock with CKDIV8 so practically running @ 16kHz.

The minimum viable code:

```
/*
  3V0               SW0
   |     |     |     |
 -----------------------
 |                     |
 |                     |
 |      ATtiny13A      |
 |                     |
 |                     |
 -----------------------
   |     |     |     |
               TX   GND
 */

#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <iso646.h>
#include <stdbool.h>
#include <util/delay.h>

#define BIT_SET( PORT, BIT_FIELD ) PORT |=  BIT_FIELD
#define BIT_CLR( PORT, BIT_FIELD ) PORT &= ~BIT_FIELD

#define TX_PIN          PB4
#define SW0_PIN         PB0
#define INT0_MASK       PCINT0

// MARK: - POWER

static void power_down(void) {
    BIT_SET(GIFR, _BV(PCIF));       // Clear interrupt signal
    BIT_SET(GIMSK, _BV(PCIE));      // Pin Change Interrupt Enabled
    sleep_enable();
    sleep_cpu();                    // Enter sleep mode
    sleep_disable();
    BIT_CLR(GIMSK, _BV(PCIE));      // Pin Change Interrupt Disabled
}

ISR(PCINT0_vect) {}

// MARK: - Setup

static void setup(void) {
    cli();

    // Set up output pins
    DDRB = _BV(TX_PIN);
    BIT_CLR(PORTB, _BV(TX_PIN));

    BIT_SET(PORTB, _BV(SW0_PIN));        // pull up interrupt pins
    BIT_SET(PCMSK, _BV(INT0_MASK));   // set PCINT0 to trigger interrupt
    BIT_SET(GIFR, _BV(PCIF));       // Clear interrupt signal
    BIT_SET(GIMSK, _BV(PCIE));      // Pin Change Interrupt Enabled
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    sei();
}

static void loop() {
    BIT_SET(PORTB, _BV(TX_PIN));
    _delay_ms(1);
    BIT_CLR(PORTB, _BV(TX_PIN));

    power_down();
}

int main(void) {
    setup();

    while (true) {
        loop();
    }
}

```

# Answer
> 2 votes
I'm tempted to suggest *two* reed switches (one NO and the other NC). Then depending on the window state you change to use the switch which gives you the lowest drain (you could use a spare couple of pins to activate one or the other).

Failing that, you can just sleep when the switch is open (the low-power condition) and if it is closed use the watchdog timer to check it from time to time (in other words, drop the power to the switch while asleep). The WDT only uses around 5 µA so that isn't too bad (the coin battery probably self-discharges at about that rate anyway). That would be a lot better than a constant drain of around 70 µA.

I've got an ATtiny85 sitting in my hallway flashing an LED every couple of seconds. I can't recall when I replaced the battery, possibly once since I made it two years ago.

# Answer
> 3 votes
The additional 80uA drain is almost certainly coming from the pull-up resistor being shunted to ground though the reed switch.

https://www.wolframalpha.com/input/?i=(3+volts)+%2F(50k+ohm)+in+uA

As suggested by @Edgar Bonet, one way to greatly reduce this drain is to disable the pull-up immediately when you wake from the pin going low. At this point it is possible for the pin to stay low even if the switch is no longer grounding the pin, so you need to periodically check it using a watchdog.

1. Wake from pin going low pin change interrupt
2. Disable pull-up (stops current flowing though resistor)
3. Do your logging operation.
4. Enable a watchdog wake up
5. Go back to sleep.

At this point you can wake either from (1) a watchdog or (2) pin change if the pin goes high again.

If you wake from a pin change...

1. re-enable the pull-up
2. disable the watchdog
3. go back to sleep

If you wake from the watchdog...

1. re-enable the pull-up.
2. if the pin is high now, disable the watchdog and go back to sleep.
3. if the pin is low, disable the pull-up and leave the watchdog running and go back to sleep.

The watchdog timer on this part should only use single digits of uA while running, and it should only need to be running while the switch is grounding the pin. You can set the watchdog timeout to be quite long- on the order of seconds even, to reduce the frequency you wake to check with the pull-up (and therefore the net power used, at the cost of latency for detecting pin changes). The main downside to this strategy is that you can miss activations that happen inbetween your watchdog wake-ups, so for example if the pin goes low and then you set the watchdog for 8 seconds, and then the pin changes high and then low again during the next 8 seconds, it is possible (but not assured) that you could miss the second event, so set the watchdog timeout to be short enough that you will not miss consecutive events that you care about (you might not care if the door is opened twice in the same minute anyway).

Also, as noted by the famous @nick gammon, you might be able to get lower than 5uA when sleeping without the watchdog. Check to make sure you are disabling everything in the power register and that all unused pins are in input mode (these will be disabled when sleeping as long as there is not a pin change interrupt on them). There are lots of googleable articles on minimizing ATTINY power during sleep.

You also mentioned that your dominant case is that the switch is closed rather than opened. Since this is the higher-power case with the current switch consider using a normally open switch rather than normally closed one if possible.

Finally, if you just want simplicity and you only care about events of a minimum duration (saym then door much be open for at least 1/2 second to be noticed), then you can skip the pin change interrupt completely and only use an always-running watchdog to wake periodically and very quickly enable the pull-up and check for the desired pin state, and then disable the pull-up and go back to sleep. You should be able to do this in less than a dozen cycles so the net power usage should be almost as low as the watchdog timer drain by itself.

---
Tags: power, pins, attiny, battery, attiny13
---


# Question
Title: Arduino + UltraSensor - Serial Monitor outputs garbage
I am trying to connect an HC-SR04 to an Arduino Uno. For some reason when I run this code on the serial monitor it outputs wingdings in a straight line.

ýòøÿüÿøÿüòý÷ÿ÷ýÿÿúýÿýúÿòý÷ûòûòû÷ýÿøÿøÿÿ÷øÿüÿýÿþòøòÿÿøûüÿøÿÿòÿ÷ûòûòý÷ûòûòûöû÷ÿûû÷øÿÿ÷øÿüÿýÿüÿûöþÿý÷ûòûòûòûöûûûûûò

No breaks. Sometimes when I hit "Tools/Fix Encoding and Reload" it outputs

Ping: 0 cm Ping: 0 cm Ping: 0 cm

followed by more wingdings.

I've looked up some similar problems and it was usually fixed by changing baud to a lower value, 9600. I've done this and I still have problems.

Would you be able to help me out? I'd very much appreciate it.

```
const int trigpin = 9;
const int echopin = 10;
long duration;
int distance;

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

void loop() {
  pinMode(trigpin, OUTPUT);
  pinMode(echopin, INPUT);
  digitalWrite(trigpin,LOW);
  delayMicroseconds(2);
  digitalWrite(trigpin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigpin,LOW);
  duration = pulseIn(echopin,HIGH);
  distance = duration *0.034/2;
  Serial.print("Distance: ");
  Serial.println(distance);
}

```

**Updated Solution**

After testing out Joel's code to check the sensor was in order, I found some new sample code which worked to display the distance in inches of a HC SR04 sensor.

```
  // set up variables

  int trigpin = 13; // Trig Pin is connected to Arduino pin 13
  int echopin = 11; // Echo Pin is connected to Arduino pin 11

 // now we need variables which we will be measuring

 float pingtime; // Time for ping to travel to target and return
 float targetdistance; // Distance from sensor to target
 float speedofsound = 776.5; // speed of sound in miles per hour at 77 F

void setup() {
Serial.begin(9600); // Turn on serial port
pinMode(trigpin, OUTPUT); // Sensor trig pin is output
pinMode(echopin, INPUT); // input is reading from echopin

 }

void loop() {
digitalWrite(trigpin, LOW);// set trigger pin low
delayMicroseconds(2000); // pause to let signal settle
digitalWrite(trigpin, HIGH); // set trigger pin high
delayMicroseconds(15); // pause in high state, make sure sensor reads
digitalWrite(trigpin, LOW); // bring trigpin back low

   pingtime = pulseIn(echopin, HIGH);

// sensor will be sending HIGH pulse, measure pingtime at echopin
// ping time is in microseconds

  pingtime = pingtime / 1000000.;

// converts pingtime to seconds because speed of sound is miles per hour

  pingtime = pingtime / 3600.;
  // converts pingtime to hours
  // add a period to make float to avoid int mistakes

  targetdistance = speedofsound * pingtime;
  // calculates distance in miles traveled by ping

  targetdistance = targetdistance / 2;
  // accounts for roundtrip of ping to target

  targetdistance = targetdistance * 63360.;
  // convert target distance to inches
  // 63360 inches in a mile

Serial.print("The distance to the target is:");
Serial.print(targetdistance);
Serial.println("inches");
delay(1000);

 }

```

# Answer
Check your serial monitor baud rate. This is definitely caused by your serial monitor being set to a different baud rate than the 9600 you specified in the program.

If it had anything to do with the sensor than this line would be printed properly `Serial.print("Distance: ");`

Once you change the serial monitor baud rate then try running this program, to verify that it is set properly:

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

void loop() {
  Serial.println("Hi There!");
}

```

If that prints "Hi There!" then the program your serial monitor is set up properly.
> 1 votes

---
Tags: arduino-uno, hc-sr04
---


# Question
Title: What's the difference between all the Software Serial Libraries? Which one is Arduino Nano compatible?
There are so many Software Serial Libraries, what are the differences between them? And which one I can use with my Arduino Nano? For my Arduino Nano I need one Hardware Serial Port and one Software Serial port at a baud rate of 115200.

On which pins of the Arduino Nano can I use the software serial library?

# Answer
> 20 votes
This answer lists the 4 basic choices:

* `HardwareSerial`, always the best. Simply use the pre-defined `Serial` variable. On some Arduinos, there are extra HardwareSerial ports, called `Serial1`, `Serial2`, etc. The Nano only has `Serial`.
* `AltSoftSerial`, the best of the software serial libraries. Only one instance is allowed, and it is must be used on one of the Input Capture pins (pins 8 & 9 for a Nano).
* My `NeoSWSerial` is next best. It works on any two pins, but only at baud rates 9600, 19200 and 38400.
* `SoftwareSerial` is the worst choice. It works on any two pins, but it is very inefficient. It disables interrupts for the entire time that a character is being sent **OR** received, and it cannot do both at the same time (unlike all the other serial choices). This can interfere with other parts of your sketch, other device communications, or with libraries.

If you could use a slower baud rate, you could keep your debug prints on `Serial`, and use either `AltSoftSerial` or `NeoSWSerial` for your device.

But if you have to use 115200, the only reliable choice is `Serial`. Although `AltSoftSerial` and `SoftwareSerial` allow that baud rate, they may not send/receive data correctly.

In that case, I would suggest using `Serial` for the 115200 device. Unless you are using an ISP, you will have to disconnect the device to upload a new sketch over USB.

Then use `AltSoftSerial` or `NeoSWSerial` for your debug statements. You will need a TTL Serial-to-USB adapter (aka FTDI) on the selected pins to connect to the PC. The `Serial Monitor` or other Terminal emulator program will read from that USB COM port.

---
Tags: serial, arduino-nano, uart
---


# Question
Title: In ESP-12E NodeMCU, what's the pin number of A0?
In ESP-12E NodeMCU, all digital pins can be called with a number. Here is the list:

```
static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;

```

So these two lines of code will do the same:

```
pinMode (D0, INPUT)
pinMode (16, INPUT)

```

What's the corresponding number for A0 (the only analog input of this board)?

# Answer
The numeric value of `A0` is 17, as defined here.

But unlike on an Arduino board, you can't use it as a digital pin. It only work for pin numbers 0-16.

If you are using as a parameter for `analogRead`, the numeric values would be 0 and 17, as seen here.

And as such, these three calls would do the same:

```
analogRead(A0);
analogRead(17);
analogRead(0);

```
> 8 votes

---
Tags: esp8266, arduino-ide, nodemcu
---


# Question
Title: Can I hook up an Analog multiplexer to Arduino Nano?
I want to increase the analogue inputs for the Nano. So is it possible to hook up a CD74HC4067 analog multiplexer to it?

Thanks.

# Answer
> -1 votes
> yes. those using IO expanders offers more flexibility.

---
Tags: arduino-nano, analogread, multiplexer
---


title: Arduino analog input protection

text:
# Question
Title: Arduino analog input protection
I've been trying to find a way to protect my analog input pins (for my Leonardo and Pro micro). I'm basically using them to read an amplified piezo sensor output. The output is amplified because I'm using it to measure very low signal (heartbeats). The normal level of the sensor's output doesn't exceed 5V when I'm measuring heartbeats or chest movement, yet when the sensor is moved rapidly or lifted, I can expect a 5v+ voltage. I know that Arduino has an internal protection circuit, will that be enough to combat those sudden movements? If not, I've read so many posts on this topic including this one: http://www.thebox.myzen.co.uk/Tutorial/Protection.html

If I wanted to add a series resistor by itself as a protection will it be okay? and also, my signal is already small, wouldn't adding a resistor attenuate it even more?

Most circuits seem to have a capacitor, my signal is DC shifted upward (to avoid -ve voltage), wouldn't the capacitor remove that offset?

Finally, if I wanted to use the diode clamping diodes, which diodes should I use (i.e 1n4148 or 1n4002)?

Thank you

# Answer
If you amplified with an op-amp powered by 5V then it couldn't produce more than 5V output, so that could be your solution. Failing that, I think a resistor and a couple of clamping diodes would help. The resistor is to current-limit the clamping diodes. I don't think you need to worry about dropping the voltage through the resistor because the analog input is high impedance.

I think the 1n4148 would be OK, I don't see why not.
> 3 votes

# Answer
Use a voltage comparator to buffer the input to analog pin . E.g. a cheap lm 393. If the signal is less than 5v in buffer circuit is stored and passed on- if its more than 5v voltage comparator blocks the , more than 5v, voltage to the arduino.
> 0 votes

# Answer
> I know that Arduino has an internal protection circuit, will that be enough to combat those sudden movements?

it depends on the voltage your pin may see. the pins have clamp diodes - the reset pins may not have, so check the datasheet for sure.

those diodes can sustain some current - check the datasheet on that - absent of it, I wouldn't go more than 10ma on those little guys.

So if you think you may see 10v on the input, put a resistor of (10v-5v) / 10ma = 500ohm resistor there, where 5v is (assumed by me) the supply voltage of your mcu - use the real figure if yours has a different supply voltage.

the same calculation with the negative rail /ground.

and pick the larger of the two.

I typically put a 1k resistor there. I try to be careful if i need to go over 10k, especially for adc pins.

a safer route is to use a (dual directional) buffer. but it does add cost + board real estate.
> 0 votes

---
Tags: arduino-leonardo, analogread, arduino-pro-micro
---