title: Arduino 101 I/O voltage levels

text:
# Question
Title: Arduino 101 I/O voltage levels
As per the Arduino 101 schematic.

The Arduino 101 has level shifters (TI make LSF0108) connected to the I/O ports I guess these are to make them Arduino compatible(5V) since the Intel Curie Module is 3.3V rated.

I have 2 doubts regarding this

1. The level shifters are also connected to the analog pins so I was wondering how do these shifters pass through analog signals?
2. I have some 3.3V sensors that I want to interface to the Arduino 101 via I2C. My question is can I use 3.3V levels at the I/O ports or am I restricted to 5V?

TIA

# Answer
> 2 votes
An *Exploring the I/O Performance of the Arduino 101* webpage by Dan Watson has a number of relevant comments:

> The board uses three Texas Instruments LSF0108 level translators to accommodate all of the I/O lines (including the analog inputs). This is an interesting part. It's not really a level "shifter", and it's not a buffer. The Curie is still sourcing and sinking current to the pins, but the voltage levels are clamped at 3.3V on the Curie's side of the chip. In this regard it's kind of like a fancy analog switch. The on resistance of each signal path is in the neighborhood of 10 ohms.

Somewhat later in the article:

> Analog Input Linearity: Next I tested the analog inputs. I was curious if the level translators affect the accuracy of the readings. I applied a DC voltage on pin A5, starting at 0V and increasing to 3.3V in 100 mV steps. At each step, I recorded the 10-bit analog-to-digital (ADC) readings reported by the Arduino 101. I then created a graph of the data, which is shown \[on the webpage\]. As you can see, the results are pretty linear across the entire input range. Spot-checking a few values, I found that there might have been a +20mV bias on the readings at the top end of the scale.

To summarize: As a consequence of being like an analog switch, the LSF0108 allows the Curie's analog input pins to accept analog inputs, and apparently it works ok.

Regarding the second question, whether 3.3 V levels are ok at the I/O ports, I think they are. See the article mentioned above for more comments. Here is one that may be relevant:

> Digital Input Logic Transitions: I applied a DC voltage to pin D7 and varied it up and down while the Arduino 101 reported the logic state in the serial monitor. This was done in order to discover the logic transition levels. Going from high to low, it returned a low state after crossing 1.26V. Going from low to high, however, the transition occurred at 1.55V.

---

*Edit 1:* Regarding two questions in a comment...

> 1. What is the function of the level translators.. do they actually map the 0 to 5V levels to 0 to 3.3V on the curie side. ?

See the LSF0108 datasheet. The LSF0108 has eight A, B pairs: (A1,B1); (A2,B2); ... (A8,B8). If you drive Ai low, Bi goes low too; and vice versa, if you drive Bi low, Ai goes low too. That translates low to low. If neither side is driven low, connected inputs can pull up to an individual-pullup level but not higher than a reference level (VREFA or VREFB). This translates high to high.

> 2. If I give a 0 to 5V analog voltage at the headers will the 3.3V to 5V level part of the signal be lost, I mean does the board only take care of the 0 to 3.3V part of the signal and the adc will give max counts at 3.3V?

It *should* be 'lost', because as noted in the Curie datasheet's *Table 2-5. ADC - DC I/O specifications*, the AIN Full-scale input range is ≤ ADC\_3P3\_VCC and ≤ AON\_IO\_VCC. (The latter voltage is 1.8 or 3.3 V.) I'm not clear on why the LSF0108 doesn't interfere with ADC measurements. Maybe the switches operate in a linear mode when pullups are turned off?

---
Tags: voltage-level
---


title: Reading pulse train with DC offset

text:
# Question
Title: Reading pulse train with DC offset
One of the analog inputs to Arduino is a pulse train with DC something like 1.5V to 3.9V pulse. This of course changes by time and Im only interested in the difference voltage (peak-to-valley). Like I want Arduino to measure (3.9V-1.5V) in the loop. I can use two analog inputs if there's no other way.

How to code this kind of measurement? Does anybody have experience with this?

duty cycle is 50% freq 3.3kHz.

# Answer
> 1 votes
The proper method to use depends in part on what the data is for, and on what other processing your loop needs to do. The following example assumes there is nothing to do except compute the difference between the highest and lowest readings from among the most recent 8.

```
enum { nReads = 8 }; // # of readings = 2**3
enum { rMask = 7 };  // index-mask of 3 bits
enum { aIn = A3 };   // analog input pin #
int reads[nReads];
byte rindex=0;

void loop() {
  int vhi, vlo, vdiff, r;
  r = reads[rindex] = analogRead(aIn); // Analog read takes about .1 ms
  vhi=0; vlo=1024;
  for (byte i=0; i<nReads; ++i) {
    if (r > vhi) vhi = r;
    if (r < vlo) vlo = r;
  }
  rindex = (rindex+1) & rMask;
  vdiff = vhi - vlo;
  //
  // In this section, scale or use or report vdiff
  //   ...
}

```

An analog read takes about 104 μs. That, plus any time taken to scale, use, or report `vdiff`, will be the major determinant of how rapidly `loop()` runs, because the `for` loop that calculates `vhi` and `vlo` should take less than 10 or 15 μs.

For example, if `loop()` takes 125 μs per pass, the code will get about one reading per half cycle of input. (3.3 KHz is 303 μs per full cycle.) This will produce a steady precession of where the analog readings are taken within the input waveform's cycle. If that phenomenon is undesirable, you may need to use interrupt-triggered ADC reads.

If you don't need new differences as frequently as the above code produces them, you could instead on demand take several readings in a row and produce a result. For example:

```
int getDiff() {
  enum { nReads = 6 };
  enum { aIn = A3 };   // analog input pin #
  int vhi=0, vlo=1024, r;
  for (byte i=0; i<nReads; ++i) {
    r = analogRead(aIn); // Analog read takes about .1 ms
    if (r > vhi) vhi = r;
    if (r < vlo) vlo = r;
  }
  return vhi - vlo;
}

void loop() {
  int vdiff;
  if (readingIsNeededNow) {
    vdiff = getDiff();
    // do stuff with voltage difference
  }
  // etc
}

```

---
Tags: analogread
---


# Question
Title: arduino creates strange files in SD card
I'm new to Arduino and electronics. I want to make a project including SD data-logger, but I had a problem. I would appreciate if someone show me where I made a mistake.

Firstly, circuit was set up as in picture:

I am using 8 Gb micro SDHC card with SD adapter. I formatted in FAT32. I can play audio files which are in appropriate format and read and the print contents of text files.

But when I want to create a new file, strange file is obtained in SD card as in pic:

So I reformat SD card. the code that is used while creating file is as this;

```
// open a new file and immediately close it:
Serial.println("Creating example.txt...");
myFile = SD.open("example.txt", FILE_WRITE);
myFile.close();

```

Somewhere I read SDHC card with more than 2 Gb capacity is not supported in Arduino and I bought 2 Gb SD micro with SD adaptor.

But in this case aurduino does not detect SD card. please someone help me.

# Answer
> 1 votes
I've had similar issues with large (\> 1Gb) SD cards, I've had various different problems with different cards, some things that helped me debugging the problem:

* make sure your wires are the same length and try to use **short wires**
* make sure your power supply is sufficient, sd card readers can draw up to `150mA`
* format the card in either `FAT16` or `FAT32` and never use "quick erase", try to use official tools (like https://www.sdcard.org/downloads/formatter\_4/index.html)
* make sure if you're the correct `BAUD rate` (9600) to talk to your card
* filename support is pretty old so keep them short and don't use spaces or special characters
* make sure the SD card is not in "**write lock**" mode, there's a small switch on the side of some SD cards that can prohibit writing (but will allow reading)

# Answer
> 1 votes
I have faced this problem. Try

* If you are using multiple devices with SPI communication ignore the others by keeping their slave select HIGH
* Never forget `file.close()`

---
Tags: arduino-uno, c++, sd-card, datalogging
---


# Question
Title: Switch case inside a switch case with serial input
I'm trying to build a test program for some hardware. Basically I want to select the piece of hardware with the outer switch case then select the test with the inner switch case. I'm trying to accomplish this by using serial input in the Arduino IDE monitor.

I can't make it work whatever I do. I either end up stuck in the outer switch case or I never enter the inner switch case where I want to select the test.

I've got a bit of code below:

```
char select_addon;
char select_test;

void setup() {
  Serial.begin(9600);
  Serial.println("(1) PB1");
  Serial.println("(2) PB2");
  Serial.println("(3) PB3");
}

void loop() {
  if (Serial.available() > 0) {
    select_addon = Serial.read();
    switch (select_addon) {
      case '1':
        Serial.println("Test");
        if (Serial.available() > 0 ) {
          select_test = Serial.read();
          switch (select_test) {
            case '4':
              Serial.println(" Test 1.1");
              break;
            case '5':
              Serial.println(" Test 1.2");
              break;
            case '6':
              Serial.println(" Test 1.3");
              break;
          }
        }
        break;
      case '2':
        Serial.println("TEST 2");
        break;
      case '3':
        Serial.println("TEST 3");
        break;
    }
  }
}

```

Obviously this isn't the finished code, but it's the switch case structure I've been trying to implement. Any suggestions on how I can enter the inner switch case?

# Answer
What happens of the `if (Serial.available() > 0)` call fails? That's the problem, because when there isn't anything available it's skipping the second switch statement.

On a point of style it actually might be better to implement the inner switch as a separate function. Imagine what your code will look like with 5 cases in the outer switch, each with 5 cases in the inner switches.

Also it might be worth, for debugging purposes, to always have a default statement, at least then you will know what key it was that you pressed.
> 2 votes

---
Tags: arduino-uno
---


# Question
Title: Renaming folders in Arduino Uno' SD card
I want to rename folders through the SD shield but it does not rename them, because It renames It in another default name How Can i rename it using the name that I want?

# Answer
> 0 votes
According to this post (https://forum.arduino.cc/index.php?topic=73265.0) this library should be able to rename the folders (https://github.com/greiman?tab=repositories) but there are a lot of posts out there saying they are having problems.

It might be worth checking you can rename them on a PC, there may be problems with name lengths etc that will just complicate matters.

---
Tags: arduino-uno, shields, sd-card
---


# Question
Title: Arduino Uno R3 stuck in DFU mode/Port not recognized
I have an Arduino Uno R3 that is simultaneously stuck in DFU mode and won't be recognized as a port in the Arduino IDE on my Macbook Pro (El Capitan). Upon receiving power, the Arduino is automatically in DFU mode (I can use dfu-programmer via Terminal to access it, even though the Arduino is not 'recognized'), and by using the process normally reserved for entering DFU mode (connecting the two pins on the left side of the ICSP) the Arduino actually exits DFU mode. However, by neither entering or exiting DFU mode, the Arduino is still not 'recognized' as a port by the Arduino IDE. Prior to this happening, I had been attempting to flash files to the bootloader with success (I got this same predicament in that process previously once, but I do not know what happened differently).

Thanks, wblegoboy

# Answer
It sounds like your ATMega16U2 has lost its CDC/ACM firmware and is entering DFU mode by default to allow you to install firmware.

Installing the CDC/ACM firmware using `dfu-programmer` would get it working again.
> 0 votes

---
Tags: bootloader, mac-os
---


# Question
Title: Arduino Mega 2650 + Matlab/Simulink - Serial decimation
I am performing a control analysis on an Arduino board.
As such, I want to minimize the board cycle duration.
(Faster board = faster controller).

## **Introduction**:

I use Mathworks Matlab/Simulink to program the board.
I created a model in Simulink,
and embedded this model into my Arduino Mega 2650.

The model includes an Arduino Serial Transmit block.
I am therefore able to use Matlab software on my PC to request
serial transmission from the Arduino board to Matlab.

The Arduino Mega 2650 has the following serial constraints:

* Maximum output buffer: 64 \[byte\]
* Maximum baud frequency: ~115,000 \[bit/s\]

## **Problem**:

To perform my control analysis,
I want to minimize the board cycle duration, and
I want to read several signals simultaneously.

The time it takes to read all signals sent
(as dictated by the baud rate)
is the primary obstacle in reducing my board cycle duration.

## **Requested Information**:

Is it possible to reduce the board cycle duration
without reducing the duration in which
the serial transmission must be completed.

For **example**,
what if I run my board at 0.001 \[s\],
but I can only send all of my signals in 0.010 \[s\], what will happen during my reads?

If I read every 0.001 \[s\], obviously I will not receive all of the data,
as this is not feasible in the time that I am allotting.
My concern is regarding what will happen if I read every 0.010 \[s\]:

1. Will the passing of several board cycles before the read completes affect the read?
2. Is there a method to lock the serial output buffer while reading
(such that the data does not change midread)?
3. How long does it typically take to refill the serial output buffer with the next set of data?

## **Conclusion**:

Ultimately, I would like to run the board as fast as possible,
since I believe that this could significantly improve my controller's performance,
despite not being able to read these additional cycles.

# Answer
> 1 votes
I don't think there will be a problem in this.

I do not understand exactly why you can only send signals every 0.010 s.

The board runs at 16 MHz, that's 16 million cycles per second, however, every 'instruction' normally takes many cycles (let along parsed C/Arduino language).

What you can do is to copy the read information into an array and use it later.

Keep in mind that the serial buffer is 64 bytes. If more is read, data will be overwritten. However, if you copy the buffer into your own (larger) buffer it might help. Also you can change the 64 bytes (it's somewhere in the Serial library).

The buffer works (afaik) with a sort of circular buffer, meaning it can store 64 bytes maximum 'unprocessed' bytes. So you don't have to wait until the buffer is full before processing (actually, this is not even the best method). You can process it as long as there are bytes available.

The pseudo code can be as follows:

```
lastSignalSent = millis(); // last time signals sent

void loop()
{
    while serial bytes available
    {
        process bytes
    }

    if (millis() - lastSignalSent > 10) // More than 10 ms ago
    {
        Send signals
         lastSignalSent = millis();
    }
}

```

This assumes the serial byte processing can be done faster than they arrive, but if not, you run into problems anyway, since the serial buffer (of only 64 bytes) will be full too fast.

---
Tags: serial, arduino-mega, matlab
---


# Question
Title: Button and switch to turn on and off LED and changing after time
I have system connected to an Arduino Uno where I want to read whether the switch is open or closed.

Based on if the switch is open/closed, I want an LED light to turn on/off. When the switch is open, the LED turns on and pushing the button turns it off and stays off for 24 hours then turns back on if the switch is still open and I can again turn off the light with one push of the button. However, if the switch is closed within the 24 hours, the light doesn't turn on and pushing the button does not do anything.

I don't know how to change the state of the LED back on after the 24 hours. Should I use a button counter, `if` statements, or `while` statements? I'm really new to coding and took on a large project I'm not sure how to complete. This is obviously a very small portion of the project. Any help is much appreciated.

This is as far as I've gotten. When the switch is open the LED turns on, but when I push the button, the light just dims. I also have to hold the button down to keep the light "off" and it turns right back on when I release the button.

```
if (digitalRead(switch) == LOW) {
digitalWrite(Light, HIGH );

if (digitalRead(Button) == LOW) {
    digitalWrite(Light, LOW);
}

else if (digitalRead(switch) == HIGH) {
  digitalWrite(Light, LOW );

}
}

```

# Answer
I have to make an answer, since I cannot use items/links easily in a comment.

Instead of creating the application for you, I suggest you do the following:

* Read/try and experiment with the default Arduino examples for a switch (see Switch
* In the above example also is shown how to debounce the signal, this is needed since you want to use it as a 'toggle'.
* Use a timer for millis() and check for 24 hrs (which is 1,440,000) millis, so it should fit in a long.
* Small thing: Always align brackets to make it easier for yourself and others.
> 1 votes

# Answer
A few things will need to be done.

1. You have to figure out to detect a button press. This needs to be transition based. Ie. Detect a button press when it was not pressed the previous time.

Once a button is pressed, you take a snap shot of the time. And then turn on the led.

2. Then you test current time at each pass and see if the desired time has passed.

This can be done by configuring one of the timers to record sufficiently long period.

If you have to use mill is(), you have to figure out how long it overflows and how to detect its overflow.

Both can be done, fairly easily.
> 0 votes

# Answer
Your problem is, that you do not keep the status and acts only on actual state of switch+button each pass of `loop()` (that is many thosand each second).

So you Light On is switch is turned, then Light off if button is pressed and next split of second you repaet it again - led looks dim, as your eye cannot see how fast is blinking.

You need to keep the status (OFF,ON,TEMP\_OFF) and act upon that. Also if it is temporary off, you need know, when it happend, to undo it after 24 hours. (google for state automat arduino)

the code would be like this (not tested, I wrote it from head, so try to understand the principle and fix all small errors and play with the idea on your own)

```
// statuses - just some different values
#define ST_OFF 1
#define ST_ON 2
#define ST_TEMP_OFF 3

// pin assignment - change by tour projects need
#define pin_switch 2
#define pin_button 3
#define pin_led 13

unsigned long temp_time; // temporarry off from this time
byte status=ST_OFF; // start with dark

loop() {
  switch (status) {

    case ST_OFF:
      if ( digitalRead(pin_switch) == LOW ) {
          status = ST_ON;
          // light it on if switch turns/is LOW
          };
       break;

    case ST_ON:
      if ( digitalRead(pin_button) == LOW ) {
         status = ST_TEMP_OFF;
         temp_time=millis();
         // light it off temporary if button pressed, remeber when
         };
       if ( digitalRead(pin_switch) == HIGH ) {
          status = ST_OFF;
          // light it off permanently if switch released - override TEMP, if both happens
          };
       break;

    case ST_OFF:
       if ( millis()-temp_time > 24L*60L*60L ) {
          status = ST_ON;
          // light it on, if timeouted
          };
       if ( digitalRead(pin_switch) == HIGH ) {
          status = ST_OFF;
          // light it off permanently if switch released - overrides TEMP/ON
          };
       break;
    };

  digitalWrite(pin_led,(status == ST_ON) );
  // light the led if ST_ON, turn it off otherwise
  // we can keep old value or look for actual and write only if it differs, but it is the simplest way

}

```
> 0 votes

---
Tags: led, button, switch
---


# Question
Title: Bluetooth communication not working with DC power but works with USB power?
I am running an HM-10 Bluetooth Low Energy (BLE) module to transmit serial data (using SoftwareSerial) from an analog sensor onboard my Arduino Uno to a serial terminal app on my Android phone. When I power the Arduino with a USB power bank, the data transmits flawlessly.

When I tried to power the Arduino with a 9V battery through the DC power jack instead of USB power, the BLE module connects to my phone, but no data is transmitted when a serial connection is established.

Any ideas why this would be?

# Answer
Take two 9 volt batteries with same specifications and connect it into the parallel by using this efficiency of current increases and it full fill the current requirement at the time of data transmission and for others modules u r using with the arduino.
> 0 votes

# Answer
A PP3 battery is not a suitable power source for an Arduino.

For battery powered operations I would recommend a set of AA batteries with between 6 and 8 volts (if you don't care about bulk) or a Li-Ion battery (or two) and a suitable buck or boost (depending on number of cells) regulator to bypass the inefficient linear regulators on the Arduino.
> 0 votes

---
Tags: serial, power, bluetooth, softwareserial
---


# Question
Title: how can I combine two 2 digit 7 segment display to a single arduino uno
One of the two digit 7segment display will read its values from a smoke sensor while the other will read its values from a temperature sensor. From what I have seen in textbooks recently;each segment display will make use of ten digital pins(7 segments, decimal point, display faces(correct me if I'm wrong Pls)).

# Answer
You are correct about the 10 pins, shift register are probably the way to go for you. They are very cheap and pretty simple to use. Try googling 74hc595. It basicly turns 3 pins into 8, and you can even Daisy chain the chips to get 16, 24, 32 and so on from the 3 pins on the arduino. Good luck to you.
> 0 votes

---
Tags: arduino-uno
---


title: Why using a ESP01 adapter?

text:
# Question
Title: Why using a ESP01 adapter?
I bought an ESP-01 adapter (initially I thought this was the WIFI module):

ESP-01 adapter

Than I bought the 'real' ESP-01 (which is not arrived yet):

ESP-01

However, according to this link: connect (sorry it's in Dutch), but the picture shows that the ESP-01 is directly connected to the 3.3V of the Arduino.

My question: why bother using the adapter card? Or does it give additional security/protection (and what)?

# Answer
Using an ESP8266 with a traditional Arduino requires logic level translation of the UART signal. That is what this adaptor provides. It also provides a dedicated 5V -\> 3.3V voltage regulator so you don't stress the Arduino's rather underpowered 3.3V regulator.

The two SOT-23 components are N-channel MOSFETs (probably BSS138P or similar), and the SOT-89 component is the voltage regulator.

Yes, you can provide all that yourself, to varying levels of complexity - this just makes things easier. And since you already have it you may as well make use of it.
> 1 votes

---
Tags: wifi
---


# Question
Title: Errors creating instance MenuBackend and MenuItem attributes in a display class
I am doing a display class using 2\*8 lcd on an arduino to display and navigate my menu using MenuBackend library but i can make instance of these variables. I tried using static variable it did not work either.

**here is the codes**

GPSMenu.h :

```
#ifndef GPSMENU_h
#define GPSMENU_h
#include "Arduino.h"
#include <MenuBackend.h>
#include <LiquidCrystal.h>

class GPSMenu
{
public:
GPSMenu(LiquidCrystal* lcd);

  void navigateMenus( byte read);

  private:
  void menuChangeEvent(MenuChangeEvent changed);
  void menuUseEvent(MenuUseEvent used);
  void menuSetup();
  LiquidCrystal *_lcd;

  MenuBackend menu =  MenuBackend(menuUseEvent,menuChangeEvent);

  //beneath is the list of menu items needed to build the menu
  MenuItem Battery     = MenuItem(menu, "Battery ", 1);//----usable
  MenuItem Iteneraire  = MenuItem(menu, "Itener  ", 1);
  MenuItem Start       = MenuItem(menu, "Start   ", 2);//----usable
  MenuItem Stop        = MenuItem(menu, "Stop    ", 2);//----usable
  MenuItem FileOpn     = MenuItem(menu, "FileOpn ", 2);
  MenuItem NewFile     = MenuItem(menu, "NewFile ", 3);//----usable
  MenuItem OverWr      = MenuItem(menu, "OverWr  ", 3);//----usable
  MenuItem PtOpn       = MenuItem(menu, "PtOpn   ", 2);
  MenuItem Seconde_1   = MenuItem(menu, "Court   ", 3);//----usable
  MenuItem Secondes_15 = MenuItem(menu, "Moyen   ", 3);//----usable
  MenuItem Minute_1    = MenuItem(menu, "Long    ", 3);//----usable
  MenuItem GPSData     = MenuItem(menu, "GPSData ", 1);
  MenuItem Coord       = MenuItem(menu, "Coord   ", 2);//----usable
  MenuItem Time        = MenuItem(menu, "Time    ", 2);//----usable
  MenuItem Status      = MenuItem(menu, "Status  ", 2);//----usable
  MenuItem SpdAlti     = MenuItem(menu, "SpdAlti ", 2);//----usable
  MenuItem Filemnger   = MenuItem(menu, "Filemngr", 1);//----usable

```

};

```
#endif

```

GPSMenu.cpp:

```
#include "Arduino.h"
#include <MenuBackend.h>    //MenuBackend library - copyright by Alexander Brevig
#include <LiquidCrystal.h>  //this library is included in the Arduino IDE
#include "GPSMenu.h"  //this library is included in the Arduino IDE

GPSMenu::GPSMenu(LiquidCrystal* lcd){
 _lcd = lcd;
 _lcd->begin(8, 2);
 _lcd->clear();
  GPSMenu::menuSetup();

}

//this function builds the menu and connects the correct items together
void GPSMenu::menuSetup()
{
  //add the file menu to the menu root
  menu.getRoot().add(Battery);
  Battery.addRight(Iteneraire).addRight(GPSData ).addRight(Filemnger);
  Iteneraire.add(Start ).addRight(Stop).addRight(FileOpn).addRight(PtOpn);
  GPSData.add(Coord).addRight(Time).addRight(Status).addRight(SpdAlti);
  FileOpn.add(NewFile).addRight(OverWr);
  PtOpn.add(Seconde_1).addRight(Secondes_15).addRight(Minute_1);
}

//  This is where you define a behaviour for a menu item

void GPSMenu::menuUseEvent(MenuUseEvent used)
 {
   _lcd->setCursor(0, 0);
   _lcd->print(used.item.getName());
   _lcd->setCursor(0, 1);
   _lcd->print("Used    ");
}
/*
  Here we get a notification whenever the user changes the menu
  That is, when the menu is navigated
*/
void GPSMenu::menuChangeEvent(MenuChangeEvent changed)
{
  _lcd->setCursor(0, 0);
  _lcd->print(changed.from.getName());
  _lcd->setCursor(0, 1);
  _lcd->print(changed.to.getName());
}

void GPSMenu::navigateMenus( byte read) {
  MenuItem currentMenu=menu.getCurrent();

  switch (read){

  case 1:

    if(!(currentMenu.hasAfterChildren())){  //if the current menu has a child and has been pressed enter then menu navigate to item below
      menu.use();
    }
    else{  //otherwise, if menu has no child and has been pressed enter the current menu is used
      menu.moveDown();
    }
    break;

  case 2:
    menu.moveLeft();

    break;
  case 3:
    menu.moveRight();

    break;
  case 4:
    menu.moveUp();
    break;
  }
}

```

And the errors on my terminal :

```
In file included from GPSMenu.cpp:4:0:
GPSMenu.h:20:46: error: ‘void GPSMenu::menuUseEvent(MenuUseEvent)’ cannot appear in a constant-expression
       static MenuBackend menu =  MenuBackend(menuUseEvent,menuChangeEvent);
                                              ^
GPSMenu.h:20:59: error: ‘void GPSMenu::menuChangeEvent(MenuChangeEvent)’ cannot appear in a constant-expression
       static MenuBackend menu =  MenuBackend(menuUseEvent,menuChangeEvent);
                                                           ^
GPSMenu.h:20:74: error: invalid in-class initialization of static data member of non-integral type ‘MenuBackend’
       static MenuBackend menu =  MenuBackend(menuUseEvent,menuChangeEvent);
                                                                          ^
GPSMenu.h:20:74: error: initializer invalid for static member with constructor
GPSMenu.h:20:74: note: (an out of class initialization is required)
GPSMenu.h:23:46: error: ‘GPSMenu::menu’ cannot appear in a constant-expression
       static MenuItem Battery     = MenuItem(menu, "Battery ", 1);//----usable
                                              ^
GPSMenu.h:23:65: error: invalid in-class initialization of static data member of non-integral type ‘MenuItem’
       static MenuItem Battery     = MenuItem(menu, "Battery ", 1);//----usable
                                                                 ^
GPSMenu.h:23:65: error: initializer invalid for static member with constructor
GPSMenu.h:24:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Iteneraire  = MenuItem(menu, "Itener  ", 1);
                                                          ^
GPSMenu.h:25:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Start       = MenuItem(menu, "Start   ", 2);//----usable
                                                          ^
GPSMenu.h:26:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Stop        = MenuItem(menu, "Stop    ", 2);//----usable
                                                          ^
GPSMenu.h:27:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem FileOpn     = MenuItem(menu, "FileOpn ", 2);
                                                          ^
GPSMenu.h:28:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem NewFile     = MenuItem(menu, "NewFile ", 3);//----usable
                                                          ^
GPSMenu.h:29:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem OverWr      = MenuItem(menu, "OverWr  ", 3);//----usable
                                                          ^
GPSMenu.h:30:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem PtOpn       = MenuItem(menu, "PtOpn   ", 2);
                                                          ^
GPSMenu.h:31:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Seconde_1   = MenuItem(menu, "Court   ", 3);//----usable
                                                          ^
GPSMenu.h:32:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Secondes_15 = MenuItem(menu, "Moyen   ", 3);//----usable
                                                          ^
GPSMenu.h:33:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Minute_1    = MenuItem(menu, "Long    ", 3);//----usable
                                                          ^
GPSMenu.h:34:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem GPSData     = MenuItem(menu, "GPSData ", 1);
                                                          ^
GPSMenu.h:35:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Coord       = MenuItem(menu, "Coord   ", 2);//----usable
                                                          ^
GPSMenu.h:36:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Time        = MenuItem(menu, "Time    ", 2);//----usable
                                                          ^
GPSMenu.h:37:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Status      = MenuItem(menu, "Status  ", 2);//----usable
                                                          ^
GPSMenu.h:38:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem SpdAlti     = MenuItem(menu, "SpdAlti ", 2);//----usable
                                                          ^
GPSMenu.h:39:58: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
       MenuItem Filemnger   = MenuItem(menu, "Filemngr", 1);//----usable

```

# Answer
You can't set the value of a variable in the header file (class definition).

```
class foo
{
  int a = 1;  // This doesn't work
};

```

This works

```
class foo2
{
  static int b;
};
int foo2::b = 2;

```
> 1 votes

---
Tags: arduino-pro-mini, class
---


title: GPS very short distance calculation

text:
# Question
Title: GPS very short distance calculation
I'm currently working on a project involving making a "parent-child distance warning system" with my Flora board + Ultimate GPS Module (https://www.adafruit.com/product/1059). I'm on the preliminary phase and just trying to retrieve the current GPS module position, comparing it with a pre-fixed position (expressed in GPS decimal coordinates, e.g. 40.779006, -74.289395), calculate the distance between these two points and, if the distance is more than a certain value, say 20 meters, print on serial monitor a warning message. I was able to correctly retrieve the GPS module position (expressed in decimal coordinates, as above), but when I try to calculate the distance I'm not able to achieve a *few-meter accurancy.*

So, my questions are:

1. Is there a specific/best formula to calculate short distances (max 100 meters) on the earth surface with an accurancy of 2-3 meters? I tried with *Haversine formula* with not so bad results, but because of the scarce Double precision (in ATMega processors is the same of the Float one, i.e. 32 bits), I'm able to obtain a precision of only 6-7 digits in total (as stated in https://www.arduino.cc/en/Reference/Float). These approximations lead to large errors in the final distance value.
2. How can I obtain a fast and precise position update during my path? If I walk along a direction I'm no able to retrieve a fast enough position update in terms of lat/lon coordinates.

Hope to be as much clear as possible and to have explained my problem, thanks in advance to anyone will give me any feedback or any information and please be patience for my bad english.

Filippo

**\[UPDATE\]**

@EdgarBonet that's exactly what I was looking for!!! Huge thanks!

Does the simple GPS library you linked is good to me also if my Flora board mounts an AtMega32u4 processor instead of the ATtiny85 you mentioned?

Last question: do you know how faster can I retrieve a GPS fix? I mean, if I am in a certain position (say X) and I am able to correctly obtain my GPS coordinates, then I move 5 meters ahead (say X+5), when I arrive at X+5 position can I retrieve within few seconds the X+5 GPS coordinates?

Thank you so much again @EdgarBonet!!

I'm currently working on a project involving making a "parent-child distance warning system" with my Flora board + Ultimate GPS Module (https://www.adafruit.com/product/1059). I'm on the preliminary phase and just trying to retrieve the current GPS module position, comparing it with a pre-fixed position (expressed in GPS decimal coordinates, e.g. 40.779006, -74.289395), calculate the distance between these two points and, if the distance is more than a certain value, say 20 meters, print on serial monitor a warning message. I was able to correctly retrieve the GPS module position (expressed in decimal coordinates, as above), but when I try to calculate the distance I'm not able to achieve a *few-meter accurancy.*

So, my questions are:

1. Is there a specific/best formula to calculate short distances (max 100 meters) on the earth surface with an accurancy of 2-3 meters? I tried with *Haversine formula* with not so bad results, but because of the scarce Double precision (in ATMega processors is the same of the Float one, i.e. 32 bits), I'm able to obtain a precision of only 6-7 digits in total (as stated in https://www.arduino.cc/en/Reference/Float). These approximations lead to large errors in the final distance value.
2. How can I obtain a fast and precise position update during my path? If I walk along a direction I'm no able to retrieve a fast enough position update in terms of lat/lon coordinates.

Hope to be as much clear as possible and to have explained my problem, thanks in advance to anyone will give me any feedback or any information and please be patience for my bad english.

Filippo

**\[UPDATE\]**

@EdgarBonet that's exactly what I was looking for!!! Huge thanks!

Does the simple GPS library you linked is good to me also if my Flora board mounts an AtMega32u4 processor instead of the ATtiny85 you mentioned?

Last question: do you know how faster can I retrieve a GPS fix? I mean, if I am in a certain position (say X) and I am able to correctly obtain my GPS coordinates, then I move 5 meters ahead (say X+5), when I arrive at X+5 position can I retrieve within few seconds the X+5 GPS coordinates?

Thank you so much again @EdgarBonet!!

**\[UPDATE 2\]**

The `DistanceBetween` method recommended to me by @EdgarBonet returns to me always 0, even if I move my self a couple of tens of meters.

But, maybe I am wrong in passing the parameters. Do I have to pass the lat/lon parameters as decimal coordinates (e.g: 45.892829, 12.082583)? If I am wrong, in which format do I have to pass the lat/lon parameters to the `DistanceBetween` method?

# Answer
> 3 votes
The Haversine formula is way overkill for your needs. At the scale you are concerned about, the Earth is essentially flat, so the distance between two points is given by the standard Cartesian formula:

d = √(Δx2 \+ Δy2)

where Δx and Δy are the distances along the west–east and south–north axes respectively. These can be computed from the differences in latitude and longitude as

Δx = R Δλ cos(φ)
Δy = R Δφ

where φ is the latitude, λ is the longitude (both in radians), and R is the Earth radius. The term cos(φ) accounts for the fact that, far from the equator, consecutive meridians are closer together than consecutive parallels. When computing this cosine, it does not matter whether you use the latitude of either point.

I suggest you take a look at this simple GPS library. It was designed for doing exactly this kind of simple calculations on a small AVR processor like the ATtiny85. It should work great on your Flora. The function you want is `DistanceBetween()`. It uses the “locally flat Earth” approximation above, which is only good for distances up to a few hundred kilometers.

A couple of things worth noting about this library:

* the library trades accuracy for efficiency: everything is fixed-point and it uses low-order polynomial approximations for cos(x) and √(x2 \+ y2)
* angles are given in units of 10−4 arc minutes, as this is what you usually get from an NMEA sentence
* `DistanceBetween()` reports the distance as an integer number of meters, but you can easily modify it to give it in units of half-meters, quarter-meters, etc.: just replace the value 512 in the last line (`return ... / 512;`) by a smaller power of two.

# Answer
> 2 votes
I have successfully used an Arduino + hobby GPS to get an accuracy within a few meters with an update every second using normal floating point on Arduino. This should be possible.

A 32-bit float has 24 bits of precision, and one 2^24th of half the Earth's circumference is about 1.2 meters, so the theoretical cap is roughly that.

If I recall correctly, you would get better accuracy for short distances on a 32-bit float using normal 2D trig than haversine, but both should work.

Check to make sure you are reading your GPS correctly and go over the equations again. Is everything converted to radians correctly for the trig? Make sure your version of PI has enough digits. Are you correctly parsing the GPS output value as degrees+decimal minutes? It is not a simple decimal degree number (like Google Maps coordinates would be) if it came from an NMEA message. Are there any configuration startup commands you need to send your GPS unit?

I think the fastest updates you can expect is a new coordinate every second, but I haven't used your specific GPS.

# Answer
> 0 votes
The position difference calculation part of the question has been handled by Edgar. Which leaves the heading to the child part.

To work out which direction the parent is walking in don't use change in position. Use the heading and velocity outputs from the GPS. These will be far more accurate than calculating the velocity based on the change in position.

As for rate of update it depends a lot on the GPS being used, the one you linked to indicates that it supports 10 Hz updates so you should be able to get a position and heading update 10 times per second. The default will be 1 Hz so you'll need to send the correct configuration command. This will however significantly increase battery usage.

Those low end GPS systems typically have a fair amount of latency but the values you get in the serial stream shouldn't be more than 100 ms old, easily good enough for something as slow as a person walking.

# Answer
> 0 votes
You may be interested in my NeoGPS library. It is smaller, faster, more reliable and more accurate than all other libraries. It preserves the full accuracy of the GPS locations (10 significant digits), even during distance and bearing calculations. NeoGPS uses the equirectangular simplification suggested by Edgar at small distances, and switches to Haversine at large distances. As you have discovered, naive floating-point calculations (like those in all other libraries) lose that accuracy at small distances.

If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu **Sketch -\> Include Library -\> Manage Libraries**.

---
Tags: gps
---


title: digitalRead influenced by touches

text:
# Question
Title: digitalRead influenced by touches
```
  const int BUTTON      = 8;

void setup() {
  Serial.begin(9600);
  pinMode(BUTTON, INPUT);
}

void loop() {

  Serial.println(digitalRead(BUTTON));

}

```

I have connected a cable to pin 8. It's not connected to anything else nor have I any other cables connected. I am expecting constant zeros, but I keep getting ones and zeros all the time, e.g. when shortly touching the cable.

I didn't experience that before. Did I accidentally damage my Arduino?

# Answer
If you don't connect it to anything, it can be a result of a flipping 'input' ... try to use a pullup or pulldown resistor.

Or better:

PullUp

Use something like:

```
 pinMode(BUTTON, INPUT_PULLUP);

```
> 2 votes

# Answer
The pin is floating. Use pull up or pull down to help define its logic state.
> 2 votes

---
Tags: arduino-uno
---


# Question
Title: How can I2C be made to work through a level shifter?
I am attempting to use a bi-directional level shifter for an IMU to shift the SDA and SCL lines in an I2C implementation, however cannot get the level shifter working with the Arduino at all. It feels like the bi-directionality is confusing the master\<\>slave relationship and pulling the high and low levels to some average, preventing communications.

At idle, with no connection, the SDA and SCL lines on the Adruino are are 5 V, however when connected to two channels of the level shifter, the voltages drop to 2.5 V on the high side and 1.7 V on the low side of the shifter. The low side of the shifter is completely open so shouldn't be controlling the voltage at all, I've even tried a 10 kOhm and 1.5 kOhm pullup resistor between the low and high sides and their respective voltages, 3.3 and 5 V, but that hasn't worked either.

The level shifter works fine interfacing the MEGA to an SD card over the SPI pins, so I don't understand quite why the level shifting would stop working with the I2C.

The fault manifests as the Arduino hanging on a `Wire.endTransmission();` call, which would seem to suggest the MEGA is failing to oscillate its SDA and SCL pins as it wishes. The problem occurs when either of the SDA or SCL pins are connected to the shifter high-side.

I also know that the Sparkfun datasheet for the IMU states that for I2C a level shifter is not necessary, but in debugging another problem, this is being attempted as a solution.

Level shifter: Adafruit 8-channel Bi-directional Logic Level Converter

IMU: Sparkfun LSM9DS1 breakout

Arduino: MEGA 2560 v3

# Answer
For I2C you need a special kind of logic translator. This one isn't suitable.

> This device can only translate push-pull CMOS logic outputs. If for open-drain signal translation, please refer to TI TXS010X products.

Personally I use the PCA9306DCUR since it is specifically designed for I2C operation.
> 2 votes

---
Tags: i2c, voltage-level, accelerometer
---


# Question
Title: PCF8583 with Arduino delay of one second?
I'm trying to interface the RTC chip : PCF8583 with Arduino Uno. I'm using exactly the circuit shown below except instead of the variable capacitor near the crystal oscillator, I've used a 22pF ceramic capacitor.

For the programming side, I've used the Arduino PCF8583 library

The code I'm using is the following :

```
#include <Wire.h> // necessary, or the application won't build properly
#include <stdio.h>
#include <PCF8583.h>

/*
*  read/write serial interface to PCF8583 RTC via I2C interface
*
*  Arduino analog input 5 - I2C SCL (PCF8583 pin 6)
*  Arduino analog input 4 - I2C SDA (PCF8583 pin 5)
*
*  You can set the type by sending it YYMMddhhmmss;
*  the semicolon on the end tells it you're done...
*
*/

int correct_address = 0;
PCF8583 p (0xA0);
void setup(void){
 Serial.begin(9600);
 Serial.print("booting...");
 Serial.println(" done");
}

void loop(void){
 if(Serial.available() > 0){
   p.year= (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48)) + 2000;
   p.month = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   p.day = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   p.hour  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   p.minute = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   p.second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48));
   // Use of (byte) type casting and ascii math to achieve result.

   if(Serial.read() == ';'){
     Serial.println("setting date");
     p.set_time();
   }
 }

 p.get_time();
 char time[50];
 sprintf(time, "%02d/%02d/%02d %02d:%02d:%02d",
  p.year, p.month, p.day, p.hour, p.minute, p.second);
 Serial.println(time);
 delay(3000);
}

```

When setting the time and date, everything went ok, but when getting date/time the result is always HALF the period of the elapsed time, for example if I set the time 10:30 and I check it after 30 MINUTES, I get 10:45 instead of 11:00.

I really don't know if this is a hardware or software issue. If anybody has any idea about this issue, that would be highly appreciable !

Thanks in advance !

# Answer
> -1 votes
1. Check your schematic vs the datasheet and make sure that it makes sense.
2. Check to make sure that your input is right. You can print it back right away, or set the etc to a known good time and see if it keeps time.
3. Check the library to make sure that it is good.

---
Tags: arduino-uno, i2c, atmega328, rtc
---


title: GPS North? South? East? West?

text:
# Question
Title: GPS North? South? East? West?
I'm using the Adafruit SIM808 breakout board to text a GPS link to Google Maps when pinged. My program is mostly working, but the GPS data that I get has no "N, S, E, W" indicators. In addition, I know that the longitude where I live is negative but it's coming out as positive. This is the output that I get:

This is the code that triggers that output:

```
int8_t stat;
// check GPS fix
stat = fona.GPSstatus();
if (stat < 0)  {
  Serial.println(F("Failed to query"));
}
if (stat == 0) {
  Serial.println(F("GPS off"));
}
if (stat == 1) {
  Serial.println(F("No fix"));
}
if (stat == 2) {
  Serial.println(F("2D fix"));
}
if (stat == 3) {
  Serial.println(F("3D fix"));
}

// check for GPS location
char gpsdata[120];
fona.getGPS(0, gpsdata, 120);
Serial.println(gpsdata);

```

I'm already reading about how to fix the GPS data so that it can be used by Google Maps, but I don't know what to do about the issue of not having the directional information/sign.

Here is the full code, just for reference:

```
#include "Adafruit_FONA.h"
#include <SoftwareSerial.h>

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4
#define FONA_KEY 7
#define FONA_PS 8

// this is a large buffer for replies
char replybuffer[255];

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

void setup() {
  Serial.begin(115200);
  pinMode(FONA_KEY, OUTPUT);
  pinMode(FONA_PS, INPUT);
  analogReference(INTERNAL);
  delay(2000);

  TurnOffFona();

  Serial.println(F("FONA SMS caller ID test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
  delay(1000);

  TurnOnFona();

  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  Serial.println(F("FONA is OK"));

  // Print SIM card IMEI number.
  char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("SIM card IMEI: "); Serial.println(imei);
  }

  // turn GPS on
  if (!fona.enableGPS(true)) {
    Serial.println(F("GPS failed to turn on"));
  }

  Serial.println("FONA Ready");
}

char fonaInBuffer[64]; //for notifications from the FONA

void loop() {
  char* bufPtr = fonaInBuffer; //handy buffer pointer

  if (fona.available()) {
    //any data available from the FONA?
    int slot = 0; //this will be the slot number of the SMS
    int charCount = 0;
    //Read the notification into fonaInBuffer
    do  {
      *bufPtr = fona.read();
      Serial.write(*bufPtr);
      delay(1);
    } while ((*bufPtr++ != '\n') && (fona.available()) && (++charCount < (sizeof(fonaInBuffer) - 1)));

    //Add a terminal NULL to the notification string
    *bufPtr = 0;

    //Scan the notification string for an SMS received notification.
    //  If it's an SMS message, we'll get the slot number in 'slot'
    if (1 == sscanf(fonaInBuffer, "+CMTI: \"SM\",%d", &slot)) {
      Serial.print("slot: "); Serial.println(slot);
      char callerIDbuffer[32];  //we'll store the SMS sender number in here

      // Retrieve SMS sender address/phone number.
      if (! fona.getSMSSender(slot, callerIDbuffer, 31)) {
        Serial.println("Didn't find SMS message in slot!");
      }
      Serial.print(F("FROM: ")); Serial.println(callerIDbuffer);

      int8_t stat;
      // check GPS fix
      stat = fona.GPSstatus();
      if (stat < 0)  {
        Serial.println(F("Failed to query"));
      }
      if (stat == 0) {
        Serial.println(F("GPS off"));
      }
      if (stat == 1) {
        Serial.println(F("No fix"));
      }
      if (stat == 2) {
        Serial.println(F("2D fix"));
      }
      if (stat == 3) {
        Serial.println(F("3D fix"));
      }

      // check for GPS location
      char gpsdata[120];
      fona.getGPS(0, gpsdata, 120);
      Serial.println(gpsdata);
      String gpsString;

      gpsString = (String) gpsdata; //re-cast chr array as string.
      Serial.println(gpsString);
      int commaIndex = gpsString.indexOf(',');
      int secondCommaIndex = gpsString.indexOf(',', commaIndex + 1);
      int thirdCommaIndex = gpsString.indexOf(',', secondCommaIndex + 1);
      int fourthCommaIndex = gpsString.indexOf(',', thirdCommaIndex + 1);

      String firstValue = gpsString.substring(0, commaIndex);
      String rawLat = gpsString.substring(commaIndex + 1, secondCommaIndex);
      String rawLon = gpsString.substring(secondCommaIndex + 1, thirdCommaIndex);
      String rawAlt = gpsString.substring(thirdCommaIndex + 1, fourthCommaIndex);

      int decimalIndex = rawLat.indexOf('.');
      String lat1 = rawLat.substring(0, decimalIndex);
      String lat2 = rawLat.substring(decimalIndex + 1, rawLat.length());
      Serial.println(lat1);
      Serial.println(lat2);
      rawLat = lat1.substring(0, 2) + "." + lat1.substring(3, lat1.length()) + lat2;
      Serial.println(rawLat);

      int decimal2Index = rawLon.indexOf('.');
      String lon1 = rawLon.substring(0, decimal2Index);
      String lon2 = rawLon.substring(decimal2Index + 1, rawLon.length());
      Serial.println(lon1);
      Serial.println(lon2);
      rawLon = lon1.substring(0, 2) + "." + lon1.substring(3, lon1.length()) + lon2;
      Serial.println(rawLon);

      char txtmsgArray[80];
      String txmsg = "https://www.google.com/maps/@" + rawLat + "," +  rawLon + ",15z";
      txmsg.toCharArray(txtmsgArray, 80);
      Serial.println(txtmsgArray);

      Serial.println("Sending reponse...");
      if (!fona.sendSMS(callerIDbuffer, txtmsgArray)) {
        Serial.println(F("Failed"));
      } else {
        Serial.println(F("Sent!"));
      }
      delay(3000);
      // delete the original msg after it is processed
      //   otherwise, we will fill up all the slots
      //   and then we won't be able to receive SMS anymore
      if (fona.deleteSMS(slot)) {
        Serial.println(F("OK!"));
      } else {
        Serial.println(F("Couldn't delete"));
      }
    }
  }
}

void TurnOnFona() {
  Serial.println("Turning on Fona: ");
  while (digitalRead(FONA_PS) == LOW) {
    digitalWrite(FONA_KEY, LOW);
  }
  digitalWrite(FONA_KEY, HIGH);
  delay(4000);
}

void TurnOffFona() {
  Serial.println("Turning off Fona ");
  while (digitalRead(FONA_PS) == HIGH) {
    digitalWrite(FONA_KEY, LOW);
  }
  digitalWrite(FONA_KEY, HIGH);
  delay(4000);
}

```

# Answer
> 2 votes
Send the command:
`AT+CGPSOUT=1`

That should enable the output of the standard NMEA $GPGGA string which includes all the position information you should need in a format that either you can parse or use one of the many existing libraries to parse. It's not clear from the documentation if this will be a one time output or a 1 Hz output.

There are other NMEA messages available if you need them, see https://cdn-shop.adafruit.com/datasheets/SIM808\_GPS\_Application\_Note\_V1.00.pdf for details.

# Answer
> 1 votes
GPS is a positioning system: it doesn't do direction. If your software has serial information coming in, it can take the difference in readings and *generate* that data but GPS doesn't do it for you.

Some devices may add it to the standard, but that's a per-device feature. .

---
Tags: gps
---


# Question
Title: How can I set a calculated value when my sketch is uploaded?
I have an Arduino based countdown timer that counts down the number of minutes remaining to an event and displays them on an LCD. Since the event's start time is fixed, I have to re-calculate my countdown duration and update a constant in the sketch every time I upload it.

**Is it possible to calculate the duration on the PC and set the starting value for the timer automatically?** Perhaps using some kind of pre-compile script? Or perhaps through some kind of debugging features?

I'm not interested in adding RTC or other hardware to this project b/c (1) I don't have it handy and (2) there's very limited physical space in the already assembled project.

I'm currently using the Arduino IDE but I would be open to solutions that use other IDEs, or external components.

# Answer
The C compilers provide two macros that resolve to string literals: `__DATE__` gives the time the file was compiled, and `__TIME__` gives the current time of day. They output e.g. "May 31 2017" and "21:19:49"

You'd have to parse these string to get the time and do the calculations to get the remaining time.
> 3 votes

# Answer
Store your time acquired the way Gerben is describing.

If you have a fixed future date, add that date with the compilation date (and calculate the number of seconds/hours).

Note however, this only works when you don't reset your Arduino, or might expect a power loss in the future. If this can happens, store the current time + event time in EEPROM.

Also, add some seconds in case accuracy is important between the compilation time and time for uploading/resetting the Arduino.

Also take into account that the normal way to get time is millis(), and this might cause overflows when used in calculations. So use a second counter to convert/check for overflows and convert to minutes/hours for example.e
> 0 votes

---
Tags: sketch, uploading, variables
---


# Question
Title: Using SCL and SDA of ESP8266-01 with GY-30 BH1750FVI for lux measurement
I followed this tutorial to get lux measurement from GY-30 BH1750 with Arduino.

It's working fine. But now I want to use it with ESP8266-01.

I read Pin 4 is SDA and 5 is SCL for it. But it's not working. Can someone tell me what do I need to change in the code? I'm a "bit" confused about the addressing.

Following is the code for Arduino:

```
#include <Wire.h>

int BH1750_address = 0x23; // i2c Addresse
byte buff[2];

void setup() {
  Wire.begin();
  BH1750_Init(BH1750_address);

  delay(200);
  Serial.begin(9600);
  Serial.println("Starte Beleuchtungsstaerkemessung - blog.simtronyx.de");
}

void loop(){
  float valf=0;
  if(BH1750_Read(BH1750_address)==2){
    valf=((buff[0]<<8)|buff[1])/1.2;

    if(valf<0)Serial.print("> 65535");
    else Serial.print((int)valf,DEC);

    Serial.println(" lx");
  }
  delay(1000);
}

void BH1750_Init(int address) {
  Wire.beginTransmission(address);
  Wire.write(0x10); // 1 [lux] aufloesung
  Wire.endTransmission();
}

byte BH1750_Read(int address) {
  byte i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()){
    buff[i] = Wire.read();
    i++;
  }
  Wire.endTransmission();
  return i;
}

```

# Answer
> 0 votes
`Wire` is not setup for the ESP01 by default. There is no GPIO 4 or 5. you can specify the pins as arguments to the `begin()` method, ex: `Wire.begin(sda, scl)`. Using GPIO of (0,2) is common. Since the ESP01 is picky about pin states during power-up, don't use external pullups (you don't need them anyway).

---
Tags: i2c, esp8266
---


# Question
Title: Is there an ICRn CTC mode interrupt vector?
I can use the CTC waveform generation mode to loop to `OCRnA` and trigger the corresponding `TIMER1_COMPA_vect` interrupt.

```
// CTC mode
TCCR1A &= ~(1 << WGM10);
TCCR1A &= ~(1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B &= ~(1 << WGM13);
TIMSK1 |= (1 << OCIE1A);
OCR1A = 250;

ISR(TIMER1_COMPA_vect) {}

```

But if I use CTC mode with `ICRn` as "TOP" is there a corresponding interrupt vector?

```
TCCR1A &= ~(1 << WGM10);
TCCR1A &= ~(1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);
TIMSK1 |= (1 << ???);    // which interrupt to enable?
ICR1 = 250;

ISR(???) {}              // which interrupt vector?

```

# Answer
~~No, there isn't.~~ But you do have a simple alternative: use WGM 14 (fast PWM with TOP = ICR1). Then the TOV1 flag will be set after the timer reaches TOP:

```
TIMSK1 |= (1 << TOIE1);  // enable Timer 1 overflow interrupt

ISR(TIMER1_OVF_vect) {}  // Timer 1 overflow vector

```

Note that this waveform generation mode behaves very much like the CTC mode. If you do not set any of the COM1 bits in TCCR1A, then there will be no PWM output.

---

**Edit**: My bad. As noted by Gerben and confirmed by you, the `TIMER1_CAPT_vect` can be used, and *it is specified in the datasheet*, although maybe not very prominently:

In section 17.9.2 “Clear Timer on Compare Match (CTC) Mode”:

> An interrupt can be generated at each time the counter value reaches the TOP value by either using the OCFnA or ICFn Flag according to the register used to define the TOP value.

In section 17.11.40 “TIFR5 – Timer/Counter5 Interrupt Flag Register”, in the description of bit 5 (Input Capture Flag):

> When the Input Capture Register (ICRn) is set by the WGMn3:0 to be used as the TOP value, the ICFn Flag is set when the counter reaches the TOP value.
> 3 votes

# Answer
It does actually seem to work with CTC mode and `ICRn` as TOP, by using the `TIMER1_CAPT_vect` interrupt.

```
// CTC mode with ICRn as TOP
TCCR1A &= ~(1 << WGM10);
TCCR1A &= ~(1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);

// enable interrupt
TIMSK1 |= (1 << ICIE1);

// TOP value
ICR1 = 100;

// interrupt at TOP
ISR(TIMER1_CAPT_vect) {}

```
> 3 votes

---
Tags: interrupt, timers, avr, atmega2560
---


title: State Machine with If/Else?

text:
# Question
Title: State Machine with If/Else?
I am trying to make a state machine with if/else. But some of the code does not seem to be executing. I have information being displayed on an LCD screen so I know where it is, and it stays on **Todo=1** and does not go to the next state. I have tried using switch/case and it works. But I think it might be better for my project if I use if/else. Can I do this using if/else?

```
Void loop{
  if (state == PLAY) {
    Todo = 1;
    Mastermachine(Todo);
  } else if (state == TRYAGIN) {

  }
}

void Mastermachine(int Todo) {
  if (Todo == 1) {
    lcd.setCursor(16, 2);
    lcd.print(String(Todo));
    SongSeq[largestindex];
    for (int index = 0; index < largestindex; index++) {
      SongSeq[index]();
    }
    Todo = 2;
  } else if (Todo == 2) {
    for (learnindex = 0; learnindex < largestindex;) {
      MIDI.read();
      if (learnindex >= largestindex) {
        Todo = 3;
      }
      lcd.setCursor(16, 2);
      lcd.print(String(Todo));
    }
  } else  if (Todo == 3) {
    if (array_cmp(learn, note, largestindex, largestindex) == true) {
      largestindex++;
      delay(2000);
      Todo = 1;
    } else {
      delay(2000);
      Todo = 1;
    }
    lcd.setCursor(16, 2);
    lcd.print(String(Todo));
  }
}

```

# Answer
Inside Mastermachine(), Todo is *a copy* whatever is passed as its paramter. Even if you make a global named Todo, it will be 'hidden' by the parameter of the same name. That parameter goes out of scope - disappears - when Mastermachine() exits, including any changes made to it within the function.

There are a few choices to accomplish what you want to do, but the easiest is probably to make a global Todo and get rid of the parameter Todo in Mastermachine(); i.e., make it `void Mastermachine(void)`. Then the name Todo inside the function will refer to the global by that name.
> 1 votes

# Answer
Your loop executes continually, always setting the state to 1.....

The called state machine supposedly changes the state, but it get set back to 1 every time the loop executes.

The loop program needs to do the state changes, not the masternachine function.
> 0 votes

---
Tags: arduino-mega, programming
---


# Question
Title: Ring topology by using arduino and Bluetooth
I want to connect Bluetooth in a circular ring is it possible to contect 8 arduino with each other via Bluetooth hc05 or hc06 and share data into tha ring..

# Answer
> 1 votes
Its probably possible, but I don't think it would be a good idea.

Each Arduino is going to have to forward information it receives that is not for it. This is a drain on processing power. Add to that you are going to need to give the devices an identity, so they know what data is for them, and a inform them of the topology of the network so they know how to connect to the adjacent nodes.

Depending on what problem you are trying to solve you might want to look at direct radio coms implementing a mesh network, or the simplest of all solutions Wifi. You could use an ESP8266 to form an access point and others to connect to it. I believe there might be a limit to the number of connections an ESP8266 can have at any one time but this could be mitigated by dropping the connection after the message has been sent.

---
Tags: arduino-uno
---


# Question
Title: Make a Robotic Arm move straight not curved
I am planning on a project that includes a robotic arm controlled by Arduino. A simplified program of this would be:

* A robotic arm picks up an object
* The robotic arm then moves the object in a straight line
* The robotic arm releases the object

The problem with this is that every robotic arm that I have seen works with servos, which rotate precisely within 0 and 180 degrees. But, because the robotic arm moves with servos, it then moves in a *curved* path, rather than the desired straight path.

**The two paths in this problem appear in this image. The one on the left is the desired, but the one on the right is the one that occurs when using any robotic arm.**

Is there any way to make the robotic arm move in a straight path? Is there a specific robotic arm that moves in straight lines rather than curved lines?

Thanks for any help!

Here is the link to an example of a robotic arm picking up an object and moving in a curved path, and not a desired straight path.

# Answer
You need to learn about Inverse Kinematics.

> In robotics, inverse kinematics makes use of the kinematics equations to determine the joint parameters that provide a desired position for each of the robot's end-effectors. Specification of the movement of a robot so that its end-effectors achieve the desired tasks is known as motion planning. Inverse kinematics transforms the motion plan into joint actuator trajectories for the robot.

By deciding how you want the end to move and calculating the joint positions for each point along that path you can get straight line movements, etc.
> 2 votes

# Answer
It requires doing some geometry. Think about how you would do that with your arm. You'd have to move more than one joint at a time. So you have to define the line you want to follow, and back calculate from each point on the line what the angles of all the joints need to be in order to put the end there. This will require a bit of trigonometry. Is that something you've studied before?
> 0 votes

---
Tags: robotics
---


# Question
Title: Arduino and Raspberry Pi - initiate I2C communication as slave
I would like to interconnect Raspberry Pi and Arduino over I2C.

RPi will act as MASTER while Arduino is SLAVE.

I understand that I2C is designed that only master can send messages to slaves and then wait for responses.

I have sensor connected to Arduino, Arduino check periodically sensor value. My intent is, when sensor value exceed defined limit, inform RPi - send message to it. I want RPi as MASTER, because it also can query Arduino anytime. Can I start communication as SLAVE device?

Is it possible somehow? Do I need to use different bus than I2C?

# Answer
> 1 votes
You need to use a separate signalling method to alert the Pi that a sensor value is ready to be collected.

This is usually done using an interrupt signal. Your Arduino changes the state of a GPIO pin which is connected to a GPIO pin (through suitable logic level translation as necessary) on the Pi. When the Pi sees that pin change state it requests the data from the Arduino.

It is most common to have the transition from HIGH to LOW as an interrupt signal (aka Active Low) since that allows a simple wired-OR arrangement (open drain GPIOs with a pullup resistor) to allow more than one device to raise the same interrupt.

# Answer
> 0 votes
Yes you can!

The new pigpio library allows the Pi to act as a slave so all devices are equal.

Before this recent release, the Pi was always a master and had to poll the others, interrupting them.

But now you can let the other devices work on their own time schedules without the interrupts.

Here is where you get it

---
Tags: arduino-uno, i2c, raspberrypi
---


# Question
Title: Reading from software serial with an interrupt
I want to perform a serial read using software serial with Arduino. I am looping for my normal tasks, but whenever something is received on the software serial pins I want to perform a read operation and based on the character received, I want to run a function in the loop. I think this is possible with interrupts only. But I can not see any documentation or help on how to perform this.
How to write an ISR for this task?

# Answer
You can't do it directly with an interrupt. SoftwareSerial already uses an interrupt to do the actual reception - the received byte being placed in a circular buffer.

The only thing you could do would be to modify the source code for SoftwareSerial so that instead of storing the byte in the buffer it calls your custom code instead.

---

Ok, so you're NOT using SoftwareSerial, you're using (something which I have never heard of) "NeoSWSerial". That has the ability to attach an interrupt (by adding it to the reception interrupt ISR), and the README.md file with that library gives you an example of how to use it:

```
#include <NeoSWSerial.h>
NeoSWSerial ss( 4, 3 );

volatile uint32_t newlines = 0UL;

static void handleRxChar( uint8_t c )
{
  if (c == '\n')
    newlines++;
}

void setup()
{
  ss.attachInterrupt( handleRxChar );
  ss.begin( 9600 );
}

```

So just read the character in there, set a flag to say you have a new "mode" arrived, and in your loop react to that flag and run the right function for that mode.

If you want to terminate a mode early you will have to program your modes to also react to the "new mode" flag and terminate. The interrupt cannot do that for you.
> 3 votes

---
Tags: interrupt, softwareserial
---


# Question
Title: 2.4Mhz clock for 3-wire SPI using Arduino Mega 2560
I am trying to develop an Arduino sketch for ADS8320 ADC IC, which is 3-wire SPI. I need a 2.4MHz serial clock for the SPI interface. I tried the code below, but I don't know how to generate clock pulses at 2.4MHz clock speed.

```
#define CLK 22
#define DBIT 24 // so
#define CS 26

#include <SoftwareSerial.h>

int v = 0;
float Ctemp, Ftemp;

void setup()   {
  Serial.begin(9600);
  pinMode(CLK, OUTPUT);
  pinMode(DBIT, INPUT);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  digitalWrite(CLK, LOW);
}

void loop()   {
  v = spiRead();
  if (v == -1)   {
    Serial.print("No sensor \n");
  } else   {
    Serial.println(Ftemp);
  }
  delay(100);
}

int spiRead() {
  int value = 0;
  digitalWrite(CS, LOW);
  delay(2);
  digitalWrite(CS, HIGH);
  delay(220);
  /* Bring CS pin low to allow us to read the data from
    the conversion process */
  digitalWrite(CS, LOW);
  /* 1st 5 clock cycles  */
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  digitalWrite(CLK, LOW);
  digitalWrite(CLK, HIGH);
  delay(1);
  /*
    Read bits 16-0 from ads8320 for the adc. Loop for each bit reading
    the value and storing the final value in 'adc'
  */
  for (int i = 16; i >= 0; i--) {
    digitalWrite(CLK, HIGH);
    value += digitalRead(DBIT) << i;
    digitalWrite(CLK, LOW);
  }
  // check bit D2 if HIGH no sensor
  if ((value & 0x04) == 0x04) return -1;
  // shift right three places
  return value >> 3;
}

```

' i have added the code i tried with arduino spi library still i don't get any result

```
 // inslude the SPI library:
 #include <SPI.h>

 // set pin 10 as the slave select for the digital pot:
 const int slaveSelectPin = 10;

 void setup() {
 // set the slaveSelectPin as an output:
 pinMode(slaveSelectPin, OUTPUT);
 // initialize SPI:
 SPI.beginTransaction(SPISettings(2400000, MSBFIRST, SPI_MODE0))

 void loop() {
 while(1){
 spiread(slaveSelectPin);
 }
 }

 void spiread(int slaveSelectPin) {
 // take the SS pin low to select the chip:
 digitalWrite(slaveSelectPin, LOW);

 receivedVal = SPI.transfer(val);
// take the SS pin high to de-select the chip:
digitalWrite(slaveSelectPin, HIGH);
}

```

# Answer
> 0 votes
The ADS8320 has to have a DCLOCK frequency of between 0.024MHz and 2.4MHz. Using primitive bit-banging with millisecond granularity delays is not going to get anywhere near even the lower end of that range (500Hz is all you could possibly get with a 1ms delay between each clock transition, also you're generating a pulse wave, not a square wave - nasty).

Even using smaller microsecond delays it's not going to give you good results.

Instead you should be using the hardware SPI port which generates a stable clock signal for defining the acquisition timing.

However you cannot get a 2.4MHz SPI clock on the Arduino. But, do you *need* a 2.4MHz SPI clock? That's the absolute top end of the sampling frequency. You can go much slower - all the way down to 0.024MHz (24kHz) and still be sampling.

On the Arduino SPI runs at a division of the system clock frequency. That is, 1/2, 1/4, 1/8, etc. So with a 16MHz system clock you can run SPI at 1/8 that speed and get a 2MHz clock.

You will also need to do a certain amount of bit shifting and unpacking to get the 16 bit data from the 24-bit stream (more bits than you have now) since SPI can only work in 8 bit chunks.

> Minimum 22 clock cycles required for 16-bit conversion. Shown are 24 clock cycles. If CS remains LOW at the end of conversion, a new datastream with LSB-first is shifted out again.
>
> *-- Datasheet: Figure 29. ADS8320 Basic Timing Diagrams*

So you can just ignore what you get in the last two bits of a 24-bit stream.

# Answer
> 1 votes
It's hardly possible to generate a stable and exact frequency with your method.
Imagine you have an interrupt routine interrupting your spiRead() or any function called inside: Your clock will be extended by the ISR runtime.
Apart from this:

* I'm not sure if your LOW phase is long enough (there's no delay between setting CLK from LOW to HIGH. If 2.4 MHz is the max frequency for the chip, it should be at least 208ns.
However:
If you are sure that the runtime of digitalWrite is always longer than 208ns, you could remove your `delay()` at all. The resulting frequency is the maximum possible you can achieve with your method.
* The smallest `delay()` is 1ms, which leads to a maximum of something \< 1 kHz (or even 0.5kHz for a 50:50 signal).
You should use `delayMicroseconds()` to get at least 500kHz.

But what I'm really wondering:
**Why are you implementing bit banging instead of simply using the SPI library?<br>**

# Answer
> 1 votes
The Mega 2560 clock rate is 16 MHz. Your target SPI clock rate is 2.4 MHz. That leaves you with 16/2.4 = 6,67 clock cycles per SPI clock cycle, which means you have an available processing clearly insufficient for the task you intend. Your program will choke and will be unable to meet the hard time deadlines required. It will not work.

Instead, you should use another board with higher processing power, a slower SPI clock rate or a HW solution (instead of SW) for the SPI clock.

---
Tags: spi, adc, oscillator-clock, atmega2560
---


# Question
Title: How to write a digitalWrite array for MCP23017 expander chip?
I'm using multiple expander chips for my project and I was wondering if there is a way to shorten the loop code by using array? So that I don't have a super long code.

```
void setup() {
  mcp.begin(0);
  mcp1.begin(1);
  mcp.pinMode(0, OUTPUT);
  mcp.pinMode(1, OUTPUT);
  mcp.pinMode(2, OUTPUT);
  mcp.pinMode(3, OUTPUT);
  mcp.pinMode(4, OUTPUT);
  mcp.pinMode(5, OUTPUT);
  mcp.pinMode(6, OUTPUT)
  mcp.pinMode(7, OUTPUT);
  mcp1.pinMode(0, OUTPUT);
  mcp1.pinMode(1, OUTPUT);
  mcp1.pinMode(2, OUTPUT);
  mcp1.pinMode(3, OUTPUT);
  mcp1.pinMode(4, OUTPUT);
  mcp1.pinMode(5, OUTPUT);
  mcp1.pinMode(6, OUTPUT);
  mcp1.pinMode(7, OUTPUT);
}

void loop() {
  mcp.digitalWrite(0, LOW);
  mcp.digitalWrite(1, LOW);
  mcp.digitalWrite(2, LOW);
  mcp.digitalWrite(3, LOW);
  mcp.digitalWrite(4, LOW);
  mcp.digitalWrite(5, LOW);
  mcp.digitalWrite(6, LOW);
  mcp.digitalWrite(7, LOW);
  mcp1.digitalWrite(0, LOW);
  mcp1.digitalWrite(1, LOW);
  mcp1.digitalWrite(2, LOW);
  mcp1.digitalWrite(3, LOW);
  mcp1.digitalWrite(4, LOW);
  mcp1.digitalWrite(5, LOW);
  mcp1.digitalWrite(6, LOW);
  mcp1.digitalWrite(7, LOW);
}

```

# Answer
Use a variable ( iterator) and count from 0 to 8 (excluding):

```
void setup()
{
    mcp.begin(0);
    mcp1.begin(1);

    for (uint8 pin = 0; pin  < 8; pin ++)
    {
        mcp .pinMode(pin, OUTPUT);
        mcp1.pinMode(pin, OUTPUT);
    }
}

void loop()
{
    for (uint8 pin = 0; pin < 8; pin++)
    {
        mcp .digitalWrite(pin, LOW);
        mcp1.digitalWrite(pin, LOW);
    }
}

```

If the order in which the digital pins are written to LOW matters than split them like in your example, (however, I do not think that is the case).

```
void loop()
{
    for (uint8 pin = 0; pin < 8; pin++)
    {
        mcp .digitalWrite(pin, LOW);
    }

    for (pin = 0; pin < 8; pin++)
    {
        mcp1.digitalWrite(pin, LOW);
    }
}

```

Note : for clarity I would call the mcp variables mcp1 and mcp2 instead of mcp resp mcp2, or an even more intuitive name if there is a clear function for both mcp's.

Using uint8 creates an unsigned byte instead of an int which saves also one byte of stack memory.
> 3 votes

# Answer
If you are using the Adafruit MCP23017 library there is a shortcut you can use for setting all the GPIO pins in one go:

```
mcp.writeGPIOAB(val);

```

`val` is a 16-bit value which defines the IO level of all 16 pins at once.

There is a similar function for reading:

```
val = mcp.readGPIOAB();

```

You can also read just one bank of GPIO pins (why they didn't have a similar write function I have no idea):

```
valA = mcp.readGPIO(0);
valB = mcp.readGPIO(1);

```

Unfortunately there aren't any shortcut functions for setting the pin modes.
> 1 votes

---
Tags: i2c
---


title: Powering an Arduino with more than 5 V

text:
# Question
Title: Powering an Arduino with more than 5 V
Last time, when I supplied 12 V from a power supply to the Arduino's 5V pin, it blew up. This time I'm going to use an adapter. Why does an adapter with a 12 V input not blow an Arduino up, as in the previous case?

Or, should I have supplied 12 V to Vin pin, instead of the 5 V pin?

Edit: Sorry for saying 12V input, it is written 12V output and I meant a power adapter that is plugged into wall.

# Answer
First of all you should read the tech specs for Arduino Uno here: https://www.arduino.cc/en/Main/ArduinoBoardUno

You will find this important information about power supply:

```
Operating Voltage   5V
Input Voltage (recommended) 7-12V
Input Voltage (limit)   6-20V

```

From documentation also:

*Vin. The input voltage to the Arduino/Genuino board when it's using an external power source (as opposed to 5 volts from the USB connection or other regulated power source). You can supply voltage through this pin, or, if supplying voltage via the power jack, access it through this pin.*

*5V pin.This pin outputs a regulated 5V from the regulator on the board. The board can be supplied with power either from the DC power jack (7 - 12V), the USB connector (5V), or the VIN pin of the board (7-12V). **Supplying voltage via the 5V or 3.3V pins bypasses the regulator, and can damage your board. We don't advise it.***

So answering you question: yes you should have supplied 12v on Vin. Not on 5v.

> Why does an adapter with 12V input not make the same blown up for arduino like in the previous case?

Because you are pluging 12v in the correct input, the 7-12v jack.

Another important link to read: http://playground.arduino.cc/Learning/WhatAdapter
> 12 votes

---
Tags: arduino-uno, power
---


title: Arduino HC-SR04 water experiment

text:
# Question
Title: Arduino HC-SR04 water experiment
I am working on an experiment with the HC-SR04 sound sensor, and i am using it to record the speed of sound. I successfully measured the speed of sound in air, but when measuring it in water, I encountered a small problem. The sound waves emitted by the sensor are both absorbed and reflected off the water. Obviously, the reflected sound waves are the first ones to reach the sensor, and therefore are the ones used for calculating the speed of sound. Is there a way to code the Arduino program in order to ignore the first set of waves and only record the set of waves that were absorbed by the water? I was thinking of increasing the delay time for the pulse, but I'm not sure that would work.

Thanks.

# Answer
All you need to do is ignore any reading within the first milliseconds. Off the top of my head there is a delay statement before reading from this sensor, just alter that. You can work out how long it needs to be by working out how fast sound waves travel through the air and measuring the distance between the sensor and the source of the reflection. I think you might know how to do that :)
> 1 votes

---
Tags: arduino-uno, audio, sound, hc-sr04, speed
---


# Question
Title: How should I initialize a RepRap Discount 12864 on u8glib?
I was taking the advantage of an existing piece of hardware (RepRapDiscount Full Graphic Smart Controller) for my present project.

Here is a link for the RepRap wiki about the controller

```
#define LCD_PIN_SCLK   A4
#define LCD_PIN_MOSI   6
#define LCD_PIN_CS   8
U8GLIB_ST7920_128X64_1X u8g(A4,6,8, U8G_PIN_NONE);

```

But all I got is a blank screen with no light at all. What has happened?

# Answer
> 4 votes
I solved the problem myself. It turns out to be a problem of wrong pinouts.

My PCB of the project was originally designed for the LCD2004 counterpart, and I thought it was a drop-in replacement for 12864. But no, it's not.

This is the "Smart Adaptors". Notice that the orientation are 180 degree different.

If you have the same problem ***not lighting up a 12864 when switching from 2004***, or vice versa. Check your orientation as above.

My solution will be crimping a different JTAG wire instead.

# Answer
> 1 votes
I had a similar issue with figuring out how to get the Zyltech.com RepRapDiscount Full Graphic Smart Controller (with their Mega 2560 clone) to work with u8glib. After some fiddling it looks like the correct settings for me were:

```
// SPI Com: SCK = en = 23, MOSI = rw = 17, CS = di = 16
U8GLIB_ST7920_128X64_1X u8g(23, 17, 16);

```

---
Tags: lcd, u8glib
---


# Question
Title: replacing #define with typedefs for bracket scope
I have a project in which basically i have to concatenate existing code. Each code comes with its own #defines. But defines are not touched by the compiler, but the preprocessor.

Each snippet of the program will exist in its own fucntion.

Is it possible to include the #defines of each program - now each function, inside this function (and visible only to this function's scope)?

The proper way to do it, would be to replace text reassignment from #define to typedef?

I understand typedef is originally for defining types. But can it be used here? Is there another alternative?

# Answer
```
#define value 255

```

Can be replaced with

```
const int value = 255;

```
> 1 votes

# Answer
It is possible to use "namespace { ... }" to create local defines for a \*.cpp file.
In the Arduino IDE all \*.ino files are combined in a single \*.cpp file, therefor the "namespace" is not very useful.

When you create new tabs in the Arduino IDE and name them \*.cpp, then you have different \*.cpp files. Then you can use the "namespace" to create defines that are only valid for that \*.cpp file.

More info: Hackaday: Using Modern C++ Techniques with Arduino
> 1 votes

---
Tags: string
---


# Question
Title: Which connection should I use (preferably wireless)?
For a (for now MIDI only) project I was planning to use multiple Arduinos and send messages around.

However, for the latency, I can have max 10ms (to prevent audible delay).

I hoped to use WIFI modules (ESP-01), however, according to a previous question in Question, one remark that due to HTTP overhead the time/latency would be 15 ms. So that means WIFI is not possible.

My requirements:

* Latency of \<= 3 ms (rationale: I need at least 5 ms for processing, and want to keep total latency \< 10 ms)
* Preferably a wireless solution (rationale: I want to add later more Arduinos and want to prevent cabling)
* Preferably not using a hardware serial (low prio requirement) (rationale: the MIDI box which is a Mega, would preferably need 4 MIDI inputs, using a hardware serial would reduce one, software serial is unacceptable for MIDI).

Situation:

* Arduinos are very close together, probably within centimeters (upto like 50 centimeters)
* Messages are short (like 5-10 bytes max)
* Burst of messages can be possible, but not so likely

Background/message flow:

* Receiving MIDI input by Arduino 1
* Sending (filtered/changed) message to Arduino 2
* Arduino 2 process the manage, takes \<= 5 ms
* Arduino 2 sends message back to Arduino 1
* Arduino 1 converts it to a MIDI message and sends back

This all needs to be done within \<= 10 ms

**My thoughts so far:**

Wireless solutions:

* WIFI: HTTP seems to result in 15 ms delays, which is against my requirement.
* RF: probably overkill since my Arduinos will be very near to each other. Also I would need both a receiver and transmitter in both Arduino's.
* IR: Due to out-of-sight problems not very convenient.

Wired solutions:

* I2C: Might be possible, planning to use later also an I2C display possibly but should not be a problem
* SPI: On Arduino 2, I'm already using an SRAM with SPI which I do not want to stress more (also a time-critical resource). Also an SD card via SPI is used (but this is not a time critical resource).
* Wire: Not checked yet

**Question** Is there any wireless (or wired) solution I can use (probably beyond the ones I analyzed)?

115200 baud is what I need for a Serial connection, probably a SPI/I2C (latter preferred) is also acceptable. Or I might have missed other communication possibilities.

# Answer
I would either use the ESP8266 as a standalone device and directly program it to work with UDP datagrams or a permanently established TCP socket, or the nRF24L01+.

Of the two I would most likely use the nRF24L01+. It's good enough for 99% of wireless keyboards and mice, so plenty good enough for a few MIDI style messages.
> 1 votes

---
Tags: arduino-uno, serial, arduino-mega, midi
---


title: Overflow in bit calculation

text:
# Question
Title: Overflow in bit calculation
I'm having a double buffer to write data from sensors to SD card. `inBuf` points to the buffer that are written into (from sensors). The other buffer write data to SD card.

```
char buffer[2][BUFLEN];
volatile int inBuf = 0;

inBuf = 1 - inBuf;

```

However, the update of `inBuf` does not work. Firstly `inBuf` is 0, and after that `inBuf` becomes 32!!! I tried different data types: `boolean`, `uint8_t`, `int` and the results are the same.

How could I fix this problem? Also, what datatype should I use for `inBuf`, as it's really just one bit?

I ended up using the following:

```
inBuf = inBuf? 0:1;

```

but seems really complicated and unnecessary.

**EDITS:** Sorry for was not being clear previously. It turns out that I had an overflow in the code:

```
char buffer[2][BUFLEN];
volatile uint16_t bufferCounter;
volatile int inBuf = 0;
volatile bool outBufHasData = false;

```

Inside the interrupt handler:

```
if (bufferCounter < BUFLEN - SAMPLESIZEINCHAR + 1) {
  epoch = now();
  proximity = vcnl.readProximity();
  ambientLight = vcnl.readAmbient();

  // format to be fixed length as opposed to variable length
  // sacrifice overhead in written data with simpler and more robust code
  // since we know exactly how much to increment after each write
  int written = snprintf(&buffer[inBuf][bufferCounter], SAMPLESIZEINCHAR,
        "%10lu,%5d,%5d\n",
        epoch, proximity, ambientLight);

  if (written > 0) {
    bufferCounter += written;
  }
} else {
  // only switch buffer if out buffer is written to SD card
  if (!outBufHasData) {
    inBuf = inBuf? 0:1;
    bufferCounter = 0;
    outBufHasData = true;
  }
}

```

Then in the `for` loop, where the buffer is written to SD card when the buffer is full:

```
  if (outBufHasData) {
    myFile.print(buffer[1 - inBuf]);
    myFile.close();
    outBufHasData = false;
  }

```

Previously, I had `bufferCounter < BUFLEN` !! Thus I was writing over the memory of the buffer, and spill into `bufferCounter` and `inBuf`. That's why I got the value 32 of `inBuf`, which is the ASCII code of space. Mystery resolved!!

# Answer
Seeing as your data typpe has the volatile keyword maybe the value of inBuf is being changed on another section of code like an interupt, other wise i see no reason for the variable to have a value of 32.

If you want to only use one bit you should just use the boolean data type with a true or false value.

In that bit of code i assume you are trying to invert the value of the bit, with the boolean you could always use the NOT operator:

```
inBuf != inBuf;

```
> 2 votes

# Answer
If you want a variable to be 'yes' and 'no' or perhaps '0' and '1', then you can use a boolean which is 'true' or 'false'. With a boolean you can use logic operators:

```
boolean dataReady = false;
dataReady = !dataReady;
if( dataReady) ...

```

A `boolean` on a 8-bit AVR chip (Arduino Uno,Leonardo,Nano,Mega) is 8 bit. You could also use a `byte` and make it 0 or 1.

A 8-bit variable is often used when a interrupt routine sets a flag. By making that flag only 8 bit and `volatile`, it can be used in the loop function as well without the need to disable the interrupts. Reading and writing a 8 bit variable can not be interrupted by an interrupt routine.

Using 8 bits when only 1 bit is needed is normal. You don't have to worry about that.

When you need hundreds of 1 bit variables, then it is possible to select each bit with macro's or a lot `#define` to select each bit. This is almost never used in normal code, but almost always used for the registers of a sensor.
And last but not least: a `struct` with bit fields packs the bits. That can be handy sometimes.
> 1 votes

---
Tags: c, bit
---


# Question
Title: Powering multiple (separately enclosed) Arduinos by one adapter
I currently use one Arduino, but my plan is to use multiple Arduinos.

These Arduinos will be relatively close together (within one meter or less), and depending on the configuration I want 2 to 5 Arduinos, all in separate enclosures.

I don't expect a high power consumption from all of them, but I don't want to use batteries. So I would like to use a 9V or 12V adapter with 2A (cannot find higher amperage).

My questions:

* Can I just split the cable, and add extra plugs for the other Arduinos? (so like a parallel circuit of Arduinos)?
* Is it a problem if I only would connect 1 Arduino? (I don't think so)
* Is there a maximum Amperage I can divide this way? (I mean what if I would find a 5A adapter?)
* I see 9V or 12V adapters ... why would this matter, since the Arduino works on 5V anyway. I don't need to drive external motors, just like 5 small LEDs, some ICs (optocouplers, SRAM) and some basic connectors (like MIDI, later DMX, Audio etc), an RF or ESP01 module.

# Answer
> Can I just split the cable, and add extra plugs for the other Arduinos? (so like a parallel circuit of Arduinos)?

Yes.

> Is it a problem if I only would connect 1 Arduino? (I don't think so)

No.

> Is there a maximum Amperage I can divide this way? (I mean what if I would find a 5A adapter?)

You can draw, in total, whatever the power supply can provide. If 10 Arduinos need 500mA and you have a 5A power supply you can power 10 Arduinos from it.

If they draw just 50mA you could power 100 Arduinos from it. It's all just a matter of managing the wiring in a suitable manner (connecting hundreds of wires together gets tiresome).

> I see 9V or 12V adapters ... why would this matter, since the Arduino works on 5V anyway. I don't need to drive external motors, just like 5 small LEDs, some ICs (optocouplers, SRAM) and some basic connectors (like MIDI, later DMX, Audio etc), an RF or ESP01 module.

12V will cause more heat dissipation from the linear regulator in the Arduino than 9V will, since the 12V has to lose more of the voltage as heat.
> 2 votes

---
Tags: arduino-uno, arduino-mega, power
---


# Question
Title: Atmega2560 USART UDR r/w conflict possible?
I'm having a really weird issue with my project right now. I have an Atmega2560 using hardware serial, and the software on the other side is doing full duplex read/write at 500kbps. If I change it to be single duplex, everything works fine. But the second I try to run everything truly full duplex, I start to have some data transfer over from the transmit stream to receive stream on the device (characters that its trying to write, that it somehow ends up reading again).

I've simplified things as much as possible- disabling buffering on the arduino side, using mutexes on the client software side (to prevent overlapping read/write commands, despite the fact the underlying driver will do whatever it wants).

So, there's obviously a few potential problems here, but it has to boil down to:

a) Client software/drivers misbehaving

b) Hardware serial implementation misbehaving on the device.

I really want to rule out B, and from all my digging around, it really comes down to one question:

Is there *any* possible way that data written to the UDR register could somehow be read out again? I understand this register is actually 2 different registers, and just splits out reads and writes. But is there any possible way at all this data could be read again? Like, is it possible to even write to UDR and read that byte ever again? I'd really like to rule that out before I start unnecessarily tracing ISRs and all that garbage.

Here's what I've boiled the hardware serial code down to. Interrupt driven on read and direct write on write:

```
void MarlinSerial::write(uint8_t c) {
  while (!TEST(M_UCSRxA, M_UDREx));

  M_UDRx = c;
}

ISR(M_USARTx_RX_vect) {
  const unsigned char c = M_UDRx;
  store_char(c);
}

```

UPDATE: I'm an idiot. Found a buffer overrun way downstream in the device code. It just so happened that the temp response buffer for one routine butted up against the receive buffer, so it delightfully just over-ran into there. I'm happily chugging away now with 2 totally async command streams, total about 400kbps.

# Answer
> 1 votes
> Is there any possible way that data written to the UDR register could somehow be read out again?

No, there is no possibility. The datasheet says:

> The USART Transmit Data Buffer Register and USART Receive Data Buffer Registers share the same I/O address referred to as USART Data Register or UDRn. The Transmit Data Buffer Register (TXB) will be the destination for data written to the UDRn Register location. Reading the UDRn Register location will return the contents of the Receive Data Buffer Register (RXB).

Further on it says:

> The transmit buffer can only be written when the UDREn Flag in the UCSRnA Register is set. Data written to UDRn when the UDREn Flag is not set, will be ignored by the USART Transmitter. When data is written to the transmit buffer, and the Transmitter is enabled, the Transmitter will load the data into the Transmit Shift Register when the Shift Register is empty. Then the data will be serially transmitted on the TxDn pin.

And for reception it says:

> The receive buffer consists of a two level FIFO. The FIFO will change its state whenever the receive buffer is accessed. Due to this behavior of the receive buffer, do not use Read-Modify-Write instructions (SBI and CBI) on this location. Be careful when using bit test instructions (SBIC and SBIS), since these also will change the state of the FIFO.

So the only thing it is possible to read is data that has been received via the RX pin (and then once and once only). All written data (assuming there is room in the TX buffer) is sent out of the TX pin.

If you are getting TX data appearing in the RX buffer then somewhere there must be some kind of connection between the TX and RX pins - either in software at the remote end (the remote device echoing everything it receives, which is perfectly possible depending on what the remote device is), or though a fault in the cabling or circuit design.

---
Tags: usb, uart, atmega2560
---


# Question
Title: Photoresistor value drops when board stacked on Arduino Uno
I have a simple photoresistor displaying values on a serial monitor every second so I can establish a value that I want to use to have it activate a relay.

It has worked fine for a few weeks, with bright sunlight values about 1000, total dark is 0. I soldered only the headers on a protoshield, and stacked it on the Arduino. I have nothing else on the protoshield and I am still using jumper wires to a breadboard, which I have not changed.

Why would the photoresistor values drop to approximately 40 (from 900's) when I stack the second board on the Arduino?

# Answer
It should not happen.

I have changed this answer, because at first I read that the resulting value was changed by -40, but I think it drops from 900 to 40.

The shield is doing something, so it is not empty. Perhaps it shortcuts the AREF to GND. Perhaps you are reading an open input, and the sensor is at another analog pin. Perhaps the shield does something to the voltage pins.

A breadboard can have bad contacts. The shield can have bad contacts.

Be sure that the sensor is connected to the channel that you are reading. Measure the voltage at that analog input with a multimeter with and without the shield. Check the 5V, 3.3V and AREF pins with and without the shield.
> 1 votes

# Answer
Does the proto-shield have any LEDs on it?

You were probably connected to a pin unknowingly.

How is resistance being measured? A voltage divider with an `analogRead()`? Using a cheapo multimeter can cause problems.

Possibly, his proto-shield has some trace "wires" etched into it that were unseen, and he was connected to a floating pin or ground.

Or maybe the shield was shifted over one pin, and he wasn't connected to the pins he thought.
> 1 votes

---
Tags: photoresistor
---