title: Arduino oscilloscope

text:
# Question
Title: Arduino oscilloscope
I have been working on a recent project to build an Arduino Oscilloscope interfaced with a 4X4 keypad membrane with Nokia 5110 LCD display.I have successful individual code fragments/portions which 1)Generate waves interfaced with the keyboard 2)Display the same on the Nokia LCD 5110

i am using the Arduino Due and the 1st part of my code generates waves on DAC1 with the code as follows:-

```
#include "Waveforms.h"
#include <Keypad.h>
#include <LiquidCrystal.h>

//Set the desired duty cycle in percentage

double dc,t,a,d;
long d_milli,d_micro,a_milli,a_micro,m,n;
int stage =0;

int sample_delay1;
LiquidCrystal lcd(A2, A3, A4, A5, A6, A7);
float sample_delay;
String num1,num2;
int wave1;
String wave_name;
double duty_cycle,k;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','#','D'}
};
byte rowPins[ROWS] = {23,25,27,29}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {31,33,35,37}; //connect to the column pinouts of the keypad
int i = 0;
int sample;
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
boolean in_setup = true;
void setup()
{
  Serial.begin(9600);
  analogWriteResolution(12);  // set the analog output resolution to 12 bit (4096 levels)
  analogReadResolution(12);
  lcd.begin(20,4);
  char key = customKeypad.getKey();
  lcd.setCursor(0, 0);
  lcd.print("choose wave: ");
  lcd.setCursor(0, 1);
  lcd.print("A=Sine");
  lcd.setCursor(8, 1);
  lcd.print("B=Triangular");
  lcd.setCursor(0, 2);
  lcd.print("C=Sawtooth");
  lcd.setCursor(11, 2);
  lcd.print("D=Square");

  while( true)
  {
        char key = customKeypad.getKey();
        if(stage == 0)
        {
              Serial.println("in stage 0");
              if(key == 'A' )
              {
                wave1 = 0;
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print(" Sine?      ");
                wave_name ="Sinusoidal";
                Serial.println(wave_name);

              }
              else if(key == 'B')
              {
                wave1 = 1;
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("Triangular?");
                wave_name ="Triangular";
                Serial.println(wave_name);
              }
              else if(key == 'C')
              {
                wave1 = 2;
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("Sawtooth?  ");
                wave_name ="Sawtooth";
                Serial.println(wave_name);
              }
              else if(key == 'D')
              {
                wave1 = 3;
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("Square?    ");
                wave_name ="Square";
                Serial.println(wave_name);

              }
              else if(key == '#')
              {
                stage++;
                //lcd.clear();
                lcd.setCursor(0,1);
                lcd.print("Frequency=");
                Serial.println("Frequency=");
              }
        }
       else if(stage == 1)
        {
              if(key != NO_KEY &&(key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0'))
              {
                num1 = num1 + key;
                //int numLength = num1.length();
                //to adjust one whitespace for operator
                lcd.setCursor(10,1);
                lcd.print(num1);
              }

              else if(key == '#')
              {
                    k = num1.toInt();
                    Serial.print(k);

                          int sample_delay_int = 1000000/(k*120);
                          float sample_delay_float = 1000000/(k*120);
                          float difference= sample_delay_float-sample_delay_int;
                          sample_delay1 = sample_delay_int - 6;
                          if(difference > 0.5)
                          {
                            sample_delay1++;
                          }

                          Serial.println(sample_delay1);
                          lcd.clear();
                          lcd.print(wave_name);
                          lcd.setCursor(0,1);
                          lcd.print("Frequency=");
                          lcd.print(num1);
                          lcd.print(" Hz");
                          break;
                  }
              }
   }
}

void loop()
  {
  analogWrite(DAC1, waveformsTable[wave1][i] );
  i++;
  if(i == maxSamplesNum)  // Reset the counter to repeat the wave
    i = 0;
  else
    delayMicroseconds(sample_delay1);
  }

```

Next, I input these waves from DAC1 into analog input A0 to display on the LCD with code as below:-

```
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <SPI.h>

#define DISPLAY_WIDTH 84
#define DISPLAY_HEIGHT 48

#define ARDUINO_PRECISION 1023.0
Adafruit_PCD8544 display = Adafruit_PCD8544(8,9,10,12,11);

//Analog Pins
int channelAI = A0;      // probe

#define DELAY_POTENTIMETER //disabled it I don't have it connected
#ifdef DELAY_POTENTIMETER
int delayAI = A1;       // delay potentiometer
#endif

float delayVariable = 0;
float scale = 0;
int xCounter = 0;
int yPosition = 0;
int readings[DISPLAY_WIDTH+1];
int counter = 0;

unsigned long drawtime = 0;
unsigned long lastdraw = 0;
int frames = 0;

void setup(void)
{
  display.begin();
  display.setContrast(30);// you might have a slightly different display so it might not be the optimal value for you
  display.clearDisplay();
}

void loop()
{
  #ifdef DELAY_POTENTIMETER
  delayVariable = analogRead(delayAI);
  delayVariable = (delayVariable/100);
  #endif
  scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION;

  //record readings
  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {
    yPosition = analogRead(channelAI);
    readings[xCounter] = (yPosition*scale);
    #ifdef DELAY_POTENTIMETER
    delay (delayVariable);
    #endif
  }

  display.clearDisplay();

  //Draw Voltage Ref Lines
  display.drawLine( 10, 0, 10, DISPLAY_HEIGHT-1, BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), BLACK);
  //display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), BLACK);

  //Draw Voltage Ref Numbers
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.2));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.4));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.6));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.8));

  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {
    display.drawPixel(xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    if(xCounter>1){
      display.drawLine(xCounter-1, (DISPLAY_HEIGHT-1)-readings[xCounter-1], xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    }
  }
  //Draw FPS
  display.setCursor((DISPLAY_WIDTH-1)-11,0);
  display.print(frames);

  //Draw Voltage
  display.setCursor(((DISPLAY_WIDTH-1)/2),0);
  display.print(analogRead(channelAI)/ARDUINO_PRECISION*5.0);

  display.display();

  //Calculate FPS
  drawtime = micros();
  frames=1000000/*a second*//(drawtime-lastdraw);
  lastdraw = drawtime;
}

```

Now the problem arises when i try doing the 2 things on d same arduino due board. I got perfect results when i used arduino due and arduino uno simultaneously but have not been able to generate waves on the LCD using the same board. Is it possible to do the same. Can some1 help me incorporate the 2 programs into 1 ..Thanxx

I tried playing around with my setup() and loop() and have reached a point where my program does everything ,ie takes keypad input ,displays options on the LCD ,takes in freq and generates a splashscreen but the only thing i'm missing out on is d wave display on the LCD (I'm able to see the selected wave on the DSO) ..So i guess i'm pretty close, and the edited code is as follows:-

```
#include "waveforms.h"
#include <Keypad.h>
#include <SPI.h>

#include <Adafruit_GFX.h>
#include <gfxfont.h>

#include <Adafruit_PCD8544.h>

 //Set the desired duty cycle in percentage
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 12, 11);
double dc,t,a,d;
long d_milli,d_micro,a_milli,a_micro,m,n;
int stage =0;

int sample_delay1;
float sample_delay;
String num1,num2;
int wave1;
String wave_name;
double duty_cycle,k,Z;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','#','D'}
};
byte rowPins[ROWS] = {23,25,27,29}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {31,33,35,37}; //connect to the column pinouts of the keypad
int i = 0;
int t_sample;

#define DISPLAY_WIDTH 84
#define DISPLAY_HEIGHT 48

#define ARDUINO_PRECISION 1023.0
//Adafruit_PCD8544 display = Adafruit_PCD8544(8,9,10,12,11);

//Analog Pins
int channelAI=A0;

#define DELAY_POTENTIMETER //disabled it I don't have it connected
#ifdef DELAY_POTENTIMETER
int delayAI = A1;       // delay potentiometer
#endif

float delayVariable = 0;
float scale = 0;
int xCounter = 0;
int yPosition = 0;
int readings[DISPLAY_WIDTH+1];
int counter = 0;

unsigned long drawtime = 0;
unsigned long lastdraw = 0;
int frames = 0;

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
boolean in_setup = true;
void setup()
{
  Serial.begin(9600);
  analogWriteResolution(12);  // set the analog output resolution to 12 bit (4096 levels)
  analogReadResolution(12);
  display.begin(20,4);

  char key = customKeypad.getKey();

  display.begin();
  display.display();
  display.setContrast(40);// you might have a slightly different display so it might not be the optimal value for you
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(0, 0);
  display.print("choose wave: ");
  display.display();
  display.setCursor(1, 8);
  display.print("A=Sine");
  display.display();
  display.setCursor(1,16);
  display.print("B=Triangular");
  display.display();
  display.setCursor(1,24);
  display.print("C=Sawtooth");
  display.display();
  display.setCursor(1,32);
  display.print("D=Square");
  display.display();

  while( true)
  {
    char key = customKeypad.getKey();
    if(stage == 0)
    {
      Serial.println("in stage 0");
      if(key == 'A' )
      {
        wave1 = 0;
        display.clearDisplay();
        display.setCursor(0,0);
        display.print(" Sine?      ");
        display.display();
        wave_name ="Sinusoidal";
        Serial.println(wave_name);

      }
      else if(key == 'B')
      {
        wave1 = 1;
        display.clearDisplay();
        display.setCursor(0,0);
        display.print("Triangular?");
        display.display();
        wave_name ="Triangular";
        Serial.println(wave_name);
      }
      else if(key == 'C')
      {
        wave1 = 2;
        display.clearDisplay();
        display.setCursor(0,0);
        display.print("Sawtooth?  ");
        display.display();
        wave_name ="Sawtooth";
        Serial.println(wave_name);
      }
      else if(key == 'D')
      {
        wave1 = 3;
        display.clearDisplay();
        display.setCursor(0,0);
        display.print("Square?    ");
        display.display();
        wave_name ="Square";
        Serial.println(wave_name);

      }
      else if(key == '#')
      {
       stage++;
       display.clearDisplay();
       display.setCursor(20, 8);
       display.println("Freq=");
       display.display();
       Serial.println("Frequency=");
      }
    }
    else if(stage == 1)
    {
      if(key != NO_KEY &&(key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0'))
      {
        num1 = num1 + key;
        //int numLength = num1.length();
        //to adjust one whitespace for operator
        display.setTextSize(1);
        display.setTextColor(BLACK);
        display.setCursor(48, 9);
        display.print(num1);
        display.display();
      }
      else if(key == '#')
      {
        stage++;
        k = num1.toInt();
        Serial.print(k);
        display.setTextSize(1);
        display.setTextColor(BLACK);
        display.display();
        display.setCursor(10, 1);

        int sample_delay_int = 1000000 / (k * 120);
        float sample_delay_float = 1000000 / (k * 120);
        float difference = sample_delay_float - sample_delay_int;
        sample_delay1 = sample_delay_int - 6;
        if (difference > 0.5)
        {
          sample_delay1++;
        }

        display.display();
        Serial.println(sample_delay1);
        display.clearDisplay();
        display.print(wave_name);
        display.setCursor(1, 8);
        display.println("Freq=");
        display.print(num1);
        display.println(" Hz");
        break;
      }
    }
  }

  //record readings
  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {
    yPosition = analogRead(A0);
    readings[xCounter] = (yPosition*scale);
    #ifdef DELAY_POTENTIMETER
    delay (delayVariable);
    #endif
  }

  display.clearDisplay();

  #ifdef DELAY_POTENTIMETER
  delayVariable = analogRead(delayAI);
  display.display();
  delayVariable = (delayVariable/100);
  #endif
  scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION;

  //Draw Voltage Ref Lines
  display.drawLine( 10, 0, 10, DISPLAY_HEIGHT-1, BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), BLACK);
  //display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), BLACK);

  //Draw Voltage Ref Numbers
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.2));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.4));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.6));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.8));

  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {
    display.drawPixel(xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    if(xCounter>1){
      display.drawLine(xCounter-1, (DISPLAY_HEIGHT-1)-readings[xCounter-1], xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    }
  }
  //Draw FPS
  display.setCursor((DISPLAY_WIDTH-1)-11,0);
  display.print(frames);

  //Draw Voltage
  display.setCursor(((DISPLAY_WIDTH-1)/2),0);
  display.print(analogRead(A0)/ARDUINO_PRECISION*5.0);

  display.display();

  //Calculate FPS
  drawtime = micros();
  frames=1000000/(drawtime-lastdraw);
  lastdraw = drawtime;
  display.display();
}

void loop()
{
  analogWrite(DAC1, waveformsTable[wave1][i] );
  i++;
  if(i == maxSamplesNum)  // Reset the counter to repeat the wave
    i = 0;
  else
  delayMicroseconds(sample_delay1);

  analogWrite(DAC0, waveformsTable[wave1][i] );
  i++;
  if(i == maxSamplesNum)  // Reset the counter to repeat the wave
    i = 0;
  else
    delayMicroseconds(sample_delay1);
}

```

Can some1 possibly tinker around with this ..It'll b a huge help!!

# Answer
You have two programs. One has a *very* complicated `setup()`, but a very quick `loop()`. The other has a very small `setup()`, but a *very* complicated `loop()`. And you want to merge the two programs?

That will be very, very difficult. Your first program `loop()` looks like this:

```
void loop() {
   analogWrite(...); // Very quick code
   i++;              // Very quick code
   if (..)           // Very quick code
      i = 0;         // Very quick code
   else              // ***BUG!!!*** This shoud not be here!
   delayMicroseconds(...); // Very specific timing delay
} // loop()

```

In other words, to produce the correct waveform it does very few instructions very quickly - and then waits a carefully calculated time.

Your other program's `loop()` does lots of things, and doesn't care about timing. The code is not time-sensitive at all - and writing to the display takes variable time anyway.

Your only choice is to set a timer to interrupt every `sample_delay1` microseconds, and inside the timer interrupt handler do the `analogWrite(...);` call instead of having the `loop()` function do it. That is Advanced Arduino programming!
> 0 votes

---
Tags: arduino-due
---


# Question
Title: How to send Serial.Print only If Serial Connection is open?
So I looked through the Arduino Mega2560 documentation and searched the web for a solution, and so far I haven't had any success.

What I'm trying to accomplish is fairly simple. I need to send a serial command over serial, ONLY if there is a serial connection between the PC and the Arduino. I've tried:

```
If(Serial){
   Serial.Println("COMMAND");
}

```

That doesn't work, and I think it's because the Arduino cannot distinguish between listening to the Serial port versus establishing a Serial connection.

Any help would be appreciated.

Cheers!

# Answer
> 4 votes
The Arduino Mega's "serial" connection comes from an external chip implementing USB-serial conversion. While this chip knows if a session is open with a host, the standard design has no way to share that information with the main ATmega.

In contrast, on a Leonardo type board the main processor implements the USB interface, so it does know.

Your options include changing the requirement, having the PC program send some data to the Arduino, changing the processor to an ATmega or ARM with integrated USB, or perhaps modifying the USB implementation.

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


# Question
Title: Connect GPS module (WeeBee) to Arduino Uno
This is my very first Arduino project. I want to learn about GPS navigation by exploring the NMEA protocol!

Therefore, I bought a WeeBee GPS module. After reading the datasheet, I have two questions:

1. The official Arduino website states

> Note: if you are using an Arduino Uno, keep in mind that you can't use the GPS module at the same time as your computer is connected on the USB port.

But I you go to the end of his tutorial, you will see he can transmit the GPS data to his computer. I don't understand why it would not be possible...
2. The GPS module datasheet (download link here) states that the maximum voltage is 5V. But it also states

> serial connections are 3.3V CMOS Logic Levels

and

> Suitable decoupling must be provided by external decoupling circuitry.

So, does it mean I need a logic level converter to prevent damage to the GPS module?

# Answer
* The article on the Arduino website means that you can't upload sketches from your PC to the Arduino or receive any sort of data, through the serial monitor or otherwise, from your PC, while the GPS module uses the RX pin. Any attempt to send data from PC to Uno in this condition would cause the Arduino to receive only corrupted data, since 2 devices (GPS module and PC) would be trying to send data *at the same time*, *with the same line*. This limitation is easily resolved by connecting the GPS module to a `SoftwareSerial` port instead; this keeps the `HardwareSerial` port (pins 0 & 1) free for bidirectional PC-Arduino communication.
* The datasheet says that the maximum power supply voltage is 5 V. However, the serial connections are 3.3 V logic, so yes, you will need logic level shifters. A simple voltage divider will serve. However, 'external decoupling' refers to circuitry used in decoupling/smoothing out any spikes or dips that may occur in the supply voltage. An untamed spike could damage the device, while a dip (perhaps from large current draw) could cause the device to stop working, if the voltage falls low enough to be considered under-voltage. A 10uF electrolytic capacitor, connected from Vcc to GND close to the GPS module, should be okay.
> 1 votes

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


# Question
Title: Can all Arduino Due pins be used as digital input/output?
I am using an Arduino Due for a project. I am running out of digital pins, using 22 to 53. Can pins 0 to 13 and SCL1, SDA1 be used as digital inputs?

How about analog pins (A0 to A11) and DACs?

Thanks!

# Answer
**Bear in mind that this has nothing to do with "Electrical Engineering". This simply is an arduino question. And should be asked on arduino Stack Exchange.**

Yes.

They can be used as input/output pins. \[Simple 'tutorial'\] If that even isn't enough or not working on your type of arduino, you can use I/O expanders or shift registers. Check them out on the internet. \[I/O expanders\]
> 1 votes

# Answer
Yes, sort of. All the Analogs/digitals can be used as digital outputs with the following exceptions. TX0/RX0 (unless you are aware of what you're doing), SPI buss (SCK/MOSI/MISO), SDA1/SCL1, & CANRX/CANTX. DAC0/DAC1 may be used but be aware the min/max those two pins can output is ~0.55 to 2.75V.

And these exclusions are only for an arduino DUE. Other Arduino's will have more/less exclusions.

Correction: I was able to use CANRX and CANTX as alias pin names to declare these two lines as digital outputs, and set the pin values high/low in the normal way.
> 1 votes

---
Tags: arduino-due
---


# Question
Title: Can I connect my arduino ground to an external battery ground? Are they the same when said battery is powering the arduino?
I need to power my camera peripheral with an external power supply, since apparently I can't power both the camera and the camera's relay switch with my 5V out pin (My relays cut out and continually reset themselves if I try to run my 5V to both the camera relay switch and the relay board VCC.)

So I'm powering the camera with a 5V battery pack and my arduino with my PC, but I still need to communicate with it via UART, so I need the camera ground to be the same as my arduino ground. Can I connect the two? Is this a bad idea? Because I'm doing it now and it seems to work. I just don't want to cause a problem later on down the road, whether I'm connected to my computer or on battery power.Any advice would be greatly appreciated.

# Answer
A battery's ground is floating. That means that it's "happy" to take on any absolute value by simply connecting it to another ground - it just stops floating. This is why it's easy to connect a battery-powered phone directly to a computer to get the photos off or whatever.

The only time you shouldn't connect two grounds is if neither are floating. A good example would be the grounds of two different houses, which are physically connected to the Earth (as in the planet). It'd be difficult to budge the whole Earth's ground level!

But shouldn't they be the same? Unfortunately not. You could measure a distinct voltage difference (sometimes in the hundreds of volts) between two house earths due to the differences in their makeup.

One small note: if you do connect two grounds, only connect them in one spot. If you have two other ground pins a small distance away from the connected ones, there may be a voltage difference between them: now the two are explicitly relative to each other, so neither can be considered floating *relative to each other*. The pair as a system - if neither are earthed at least - is still floating.

These so-called "ground loops' can induce current where none is desired.
> 1 votes

---
Tags: relay
---


# Question
Title: SPI with a level converter in the other end of connection
I have an Arduino MEGA hooked up with a NRF24L01, and working nicely, talking with another Arduino Uno. It works as described, power supply to 3.3V, and SPI lines (MISO,MOSI,CLK) connected directly to the Arduino;

However, when I hook up a level converter in the end (5V to 3V, bidirectional) (making the NRF module in the middle, like in a T connection), the module stops working, and I don't know why. How does the level converter module is interfering in the connection? Is there any way I can prevent this and use it?

I intend in adding in the future, modules that talk in 3.3V SPI;

This is the level converter I'm using:

<sub>(source: at-the.space)</sub>

I suspect it is because of the pullups (5 think that these 10kΩ resistors are pull-ups, but I'm a noob in that part), but I really don't know if that is the problem, as the seller advertises it as being compatible with SPI, I2C, and UART. I have successfully used these for a UART.

I have checked Slaving multiple Arduinos via SPI and tried using an external 5V supply, and a 3.3V supply, but no dice.. However, the 3V side has no connections to it; But, being bi-directional, I don't think there is a problem with this...

I found that 74HCT245D works very well for this, but I'd like to know why with the level converter from JY-MCU this won't work.

Providing the library and connections just in case (the module works without the level converter):

# Answer
> 1 votes
More than probably your level shifter is not fast enough. A level shifter uses a mosfet to copy signals from one voltage level to the other, but each mosfet has a latency or, if you prefer, a rise time. Your board probably doesn't use a fast switching mosfet and so the SPI protocol (which is a quite fast one) is not *copied* correctly.

On top of that you **actually don't need a level switcher** for the nRF24 modules: the power pin must be limited to 3.3V, but the signal pins are 5V tolerant. This means you only need a 3.3V voltage source and all the remaining connections can go directly (and safely) into your Arduino board.

**UPDATE**: the speed concept still applies, it doesn't matter which side of the connection you are using. A mosfet has a little capacitance which *slows* down the signal transmission: higher the capacitance, slower the maximum data rate. The cheap chinese level shifter is not designed for high speed communication, while the Texas Instrument device is clearly designed for high speed. If you look at the SN74HCT245 datasheet you'll notice the switching speed is reported for 50pF capacitance and ranges from 8ns to 16ns: that's the time needed to build enough charge in the switching circuit.

# Answer
> 0 votes
AVR's like all digital have their limits. In this case you're dealing with source resistances that need to charge multiple gate capacitances through series resistances (wires and metal contact connections. Specifically an Absolute MAX 40mA/pin, some milliohms in your copper wire and PCB traces, and pico to nano Farad capacitances, plus depending on how High Speed the SPI is (the spec does not list an upper limit), you will be also contending with frequency limiting parasitics. At MHz frequencies, your wire and PCB traces will have higher resistances due to "skin" effect, where the electrons migrate to the surface of the wire when transferring. Depending on frequency of the wire, adding just a single gate could degredate rise/fall times enough to corrupt data, as the SPI library (whichever you choose) and the SPI peripheral within the AVR probably won't be as sophisticated as a PC based one. The AVR & the SPI library lacks sophistication in that neither has provisions to detect and compensate for extra gate capacitance on the bus line, nor could they compensate for china jumper wires which are quite small (9x40ga) wiring. There are many factors which could corrupt your SPI project that are coming into play to limit performance. You should probably do some internet research on high speed bus anatomy if you intend on pushing the SPI bus on the arduino to it's limits.

I think the gate capacitances are combining with source resistance and skin effect and your 40mA/pin is not in fact 40mA per pin but more like 10-20mA is hitting all gate capacitances when skin effect is considered (it effectively raises the resistance of the wire sufficiently to then be a factor). If connecting the JY-MCU converter AND running SPI at minimum speed corrects communication, then the extra gate capacitances are the factor you should change to higher performance versions. There's the 74AS series with gate times down to 1.7nS and fMAX up to 40MHz!

Hope this helps.

---
Tags: arduino-mega, voltage-level, spi, nrf24l01+
---


# Question
Title: What is the difference between running code with the scope of the void setup() or void loop() vs. outside their scope?
Good evening everyone,

I have bene playing around with making my own library, specifically for the controlling Timer1 on the Arduino Mega 2560. I'm sort of new to OOP but I am trying my hand at it here.

I wrote some code to generate a PWM wave with a 100 ms period and a 25% duty cycle, and I have Siglent SDS 1052DL, 50MHz oscilloscope that I'm using that verifies the code is successful. I am using clear-timer-on-compare-match mode and timer interrupts to generate the PWM wave. My code is below:

```
#include "Timer1.h"

Timer1 timer;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  timer.begin();
}

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

```

I made a Timer1.cpp file and a Timer1.h to go along with this file. They are below.

Timer1.cpp

```
#include "Arduino.h"
#include "Timer1.h"

float frequency = 10.0;
float period_ms;
float clock_pulse = 16.0;

unsigned long opening_time = 25000;

unsigned int ocr1a;
unsigned int ocr1b;

Timer1::Timer1() { // Object used to control 16-bit timer1

}

void Timer1::begin() {
  CRITICAL_SECTION_START; // Clear I bit
  CLEAR_TCCR1A; // Reset TCCR1A
  CLEAR_TCCR1B; // Reset TCCR1B
  SET_CTC_MODE; // Set to CTC mode
  DISABLE_TIMER1_INTERRUPTS; // Disable OCIE1A/B
  TCCR1B |= (1 << CS12); // 256
  period_ms = (1000.0f / frequency);
  ocr1a = 1000UL * (period_ms / clock_pulse);
  OCR1A = ocr1a;
  TIMSK1 |= (1 << OCIE1A);

  ocr1b = (unsigned int)float(opening_time) / clock_pulse;
  OCR1B = ocr1b;
  TIMSK1 |= (1 << OCIE1B);
  TCNT1 = 0; // Reset counter

  CRITICAL_SECTION_END; // Set I bit
}

ISR(TIMER1_COMPA_vect) {
  digitalWrite(13, HIGH);
}

ISR(TIMER1_COMPB_vect) {
  digitalWrite(13, LOW);
}

```

Timer1.h

```
#ifndef TIMER1_H
#define TIMER1_H

// ========== HANDY MACROS ========== //
#define CLEAR_TCCR1A                  TCCR1A = 0
#define CLEAR_TCCR1B                  TCCR1B = 0
#define SET_CTC_MODE                  TCCR1B |= (1 << WGM12)
#define DISABLE_TIMER1_INTERRUPTS     TIMSK1 &= ~((1 << OCIE1B) | (1 << OCIE1A))
#define CLEAR_CLOCK_SELECT_BITS       TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10))

#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli()
#define CRITICAL_SECTION_END   SREG = _sreg

class Timer1{
  public:
  // Constructor:
  Timer1();
  // Begin:
  void begin();

};

#endif // TIMER1_H

```

This code works exactly as I would expect. I originally had placed the whole block of code found in the Timer1::begin() method in the Timer1::Timer1() constructor method. When I did this, I was getting a completely different signal (2.04 ms period with about an 80% duty cycle). Is there a simple explanation for what is occurring?

# Answer
> 3 votes
In your test code, you declare `Timer1` in global scope. This means its constructor will be called right when the program starts, even before `main()` is called. The first thing the Arduino `main()` does is to call `init()`, which configures all the timers for PWM operation, as expected by `analogWrite()`. Then, any initialization of Timer1 done by the constructor will be undone by `init()`. That's why you want to defer that initialization until `setup()`.

**Edit**: I took the liberty to do a code review on your post. Below are a few suggestions. I hope some of them might be useful.

1. Put the empty constructor in the .h file, this avoids it being compiled into a real empty function.
2. Qualify `frequency`, `clock_pulse` and `opening_time` as `const`, and make `period_ms` local to `Timer1::begin()`. This way all the floating point operations are performed at compile time and you don't get all the floating point support compiled into your program.
3. Your `CRITICAL_SECTION_*` macros are redundant with `ATOMIC_BLOCK(ATOMIC_RESTORESTATE)` from avr-libc. But then, do you really need to block the interrupts the whole time?
4. I don't find the other macros in Timer1.h really useful either: just put comments next to each access to a hardware register.
5. I would set `TCCR1B` last: the timer starts counting the moment you set this register.
6. You should subtract 1 from the values you set in `OCR1A` and `OCR1B`: the period and HIGH time are `OCR1A+1` and `OCR1B+1` respectively.
7. You may want to round the period and HIGH time to the nearest integer. It may make no difference here but you users may want to change `frequency` and `opening_time`.
8. Your variables `ocr1a` and `ocr1b` serve no useful purpose, they just needlessly eat RAM.
9. You casting `opening_time` to `float`, then back to `unsigned int`, serves no useful purpose either.
10. You may want to replace `digitalWrite()` with direct port access, as this function is really slow and you are calling it from an ISR.

Below is my throw at Timer1.cpp. Note that `port` and `bit` could be made private data of the class, and the pin number could be a parameter to the `begin()` method.

```
#include "Arduino.h"
#include "Timer1.h"

/* The three constants below can be tuned to taste:  */

const float frequency    = 10;  // hertz
const float opening_time = 25;  // milliseconds
const int   pin          = 13;

/* Nothing should need to change below this line. */

const uint16_t prescaler = 256;
const float f_timer = float(F_CPU) / prescaler;
static volatile uint8_t *port;
static uint8_t bit;

void Timer1::begin() {
    // Prepare the output.
    port = portOutputRegister(digitalPinToPort(pin));
    bit = digitalPinToBitMask(pin);
    pinMode(pin, OUTPUT);

    // Configure Timer 1.
    TCCR1A = 0;  // undo the configuration done by...
    TCCR1B = 0;  // ...the Arduino core library
    TCNT1  = 0;  // reset counter
    OCR1A  = round(f_timer / frequency) - 1;
    OCR1B  = round(f_timer * opening_time * 1e-3) - 1;
    TIMSK1 = _BV(OCIE1A)   // enable TIMER1_COMPA interrupt
           | _BV(OCIE1B);  // enable TIMER1_COMPB interrupt
    TCCR1B = _BV(WGM12)    // CTC mode
           | _BV(CS12);    // prescaler = 256
}

ISR(TIMER1_COMPA_vect) {
    *port |= bit;
}

ISR(TIMER1_COMPB_vect) {
    *port &= ~bit;
}

```

# Answer
> 1 votes
I believe you should be able to put your code back into the constructor if you move all the variable you defined with file scope in Timer1.cpp:

```
float frequency = 10.0;
float period_ms;
float clock_pulse = 16.0;

unsigned long opening_time = 25000;

unsigned int ocr1a;
unsigned int ocr1b;

```

...to the Timer1 class definition (either in the public or private section). This way all the variables will have the scope of the class and the code should work the same regardless where in the class it is.

---
Tags: arduino-mega, c++, interrupt, timers
---


# Question
Title: Programming Problem with a hand gesture controlled robot; the analogwrite() function doesn't work
So I recently tried to make a hand gesture controlled robot but ran into some programming error. Here are the specs:

For the transmitter module, I used the following:

\*Arduino Nano 3.0 as the Microcontroller development platform
\*Grove 3 axis digital accelerometer 16g for sensing hand gesture
\*RF transmitter 433 Mhz (Transmitter: JMR-TX1)
\*Power source: 7.2V rechargeable battery unit to power up the Arduino Nano

For the robot, I used the following: \*Pololu Chassis \*Two DC geared motors, compatible wheels \*L293D Dual DC motor controller module \*Arduino Nano 3.0 \*RF receiver 433 Mhz (Receiver: RXB6) \*Power source: 7.2V rechargeable battery unit to power up the Arduino Nano

I hooked up all the parts carefully. I uploaded the code entitled "Transimitter\_code" to the transmitter. I uploaded a code called "Receiver\_test" and used serial monitor to see if the robot's arduino received data from the transmitter, the data I wanted to receive was the angle that the accelerometer was tilted on x and y axis measured by the accelerometer. Fortunately, the Arduino was receiving data wirelessly and displaying it in the serial monitor, which means my basic concept was ok. You can see the code attached to this thread. P.s. You will need three libraries: Wire.h, VirtualWire.h and ADXL345.h to run the codes. You can google them up and get them for free. **See the code for the transmitter below:**

```
/* Code for the transmitter of the mind controlled bot */

#include <Wire.h>
#include <ADXL345.h>
#include <VirtualWire.h>

ADXL345 adxl; //variable adxl is an instance of the ADXL345 library
int ledPin = 13; //a sign when the transmitter is working

int TX_PIN = 11;// Tell Arduino on which pin you would like to Transmit data NOTE should be a PWM Pin
int TX_ID = 3; // Transmitter ID address

typedef struct roverRemoteData// Data Structure
{
 int    TX_ID;      // Initialize a storage place for the outgoing TX ID
 int    x1;// Initialize a storage place for the first integar that you wish to Send
 int    y1;// Initialize a storage place for the Second integar that you wish to Send
};

void setup() {
 vw_setup(2000);//Bits per second
 pinMode(ledPin,OUTPUT);
 vw_set_tx_pin(TX_PIN);// Set Tx Pin
 Serial.begin(9600);//Initialise the serial connection

 adxl.powerOn();

//set activity/ inactivity thresholds (0-255)
adxl.setActivityThreshold(75); //62.5mg per increment
adxl.setInactivityThreshold(75); //62.5mg per increment
adxl.setTimeInactivity(10); // how many seconds of no activity is inactive?

//look of activity movement on this axes - 1 == on; 0 == off
adxl.setActivityX(1);
adxl.setActivityY(1);
adxl.setActivityZ(1);

//look of inactivity movement on this axes - 1 == on; 0 == off
adxl.setInactivityX(1);
adxl.setInactivityY(1);
adxl.setInactivityZ(1);

//look of tap movement on this axes - 1 == on; 0 == off
adxl.setTapDetectionOnX(0);
adxl.setTapDetectionOnY(0);
adxl.setTapDetectionOnZ(1);

//set values for what is a tap, and what is a double tap (0-255)
adxl.setTapThreshold(50); //62.5mg per increment
adxl.setTapDuration(15); //625us per increment
adxl.setDoubleTapLatency(80); //1.25ms per increment
adxl.setDoubleTapWindow(200); //1.25ms per increment

//set values for what is considered freefall (0-255)
adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment
adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment

//setting all interrupts to take place on int pin 1
//I had issues with int pin 2, was unable to reset it
adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT,   ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT,   ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT,    ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT,     ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT,   ADXL345_INT1_PIN );

//register interrupt actions - 1 == on; 0 == off
adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1);
adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1);
adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT,  1);
adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT,   1);
adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1);
}

void loop()
{
struct roverRemoteData payload;
payload.TX_ID = TX_ID; // Set the Radio Address
int x, y, z;
adxl.readXYZ(&x, &y, &z); //read the accelerometer values and store them in variables  x,y,z
payload.x1 = x;
payload.y1 = y;
vw_send((uint8_t *)&payload, sizeof(payload)); // Send the data
vw_wait_tx();// Wait for all data to be sent
if ((x>80) || (x<-80) || (y>80) || (y<-80))
{
digitalWrite(13, HIGH); //ledpin indicator
}
else
{
 digitalWrite(13, LOW);
}
delay(100);

}

```

Now, I tried to use the received data to control the motion of the bot, that is: run the motors in specific direction. However, this time, the code seems to have some problem. **Here's the code for the robot**:

```
/* Mind controlled car - Car's code */

#include <VirtualWire.h>

int RX_PIN = 11;// Tell Arduino on which pin you would like to receive data NOTE should be a PWM Pin
int RX_ID = 3;// Recever ID address
int TX_ID;

typedef struct roverRemoteData// Data Structure
{
int    TX_ID;      // Initialize a storage place for the outgoing TX ID
int    x1;// Initialize a storage place for the first integar that you wish to Send
int    y1;// Initialize a storage place for the Second integar that you wish to Send
};

void setup() {
pinMode(5, OUTPUT); //in 1
pinMode(6, OUTPUT); //in 2
pinMode(9, OUTPUT); //in 3
pinMode(10, OUTPUT); //in 4
Serial.begin(9600);
vw_setup(2000);// Setup and Begin communication over the radios at 2000bps( MIN Speed is 1000bps MAX 4000bps)
vw_set_rx_pin(RX_PIN);// Set RX Pin
vw_rx_start();

}

void loop() {

struct roverRemoteData receivedData;
uint8_t rcvdSize = sizeof(receivedData);//Incoming data size
vw_wait_rx();// Start to Receive data now
if (vw_get_message((uint8_t *)&receivedData, &rcvdSize)) // Check if data is available
{
if (receivedData.TX_ID == RX_ID) //Check if the radio signal recieved matches the ID of the Reciever
{
  if (((receivedData.x1 < 80) && (receivedData.x1 > -80)) && ((receivedData.y1 < 80) && (receivedData.y1 > -80))) //halt
  {
    halt();

  }
  else if (((receivedData.x1 < 80) && (receivedData.x1 > -80)) && (receivedData.y1 > 80)) //forward
  {
    int a = receivedData.y1;
    goForward(a);

  }
  else if (((receivedData.x1 < 80) && (receivedData.x1 > -80)) && (receivedData.y1 < -80)) //backward
  {
    int b = -receivedData.y1;
    goBackward(b);

  }
  else if ((receivedData.x1 > 80) && ((receivedData.y1 < 80) && (receivedData.y1 > -80))) //left
  {
    int c = receivedData.x1;
    goLeft(c );

  }
  else if ((receivedData.x1 < -80) && ((receivedData.y1 < 80) && (receivedData.y1 > -80))) //right
  {
    int d = -receivedData.x1;
    goRight(d);

  }
  }
  }
  }

  void goForward(int y)
  {
  analogWrite(5, y);
  analogWrite(6, 0);
  analogWrite(9, y);
  analogWrite(10, 0);
  delay(50);

  }

  void goBackward(int z)
  {
  analogWrite(5, 0);
  analogWrite(6, z);
  analogWrite(9, 0);
  analogWrite(10, z);
  delay(50);

  }

  void goLeft(int w)
  {
  analogWrite(5, w);
  analogWrite(6, 0);
  analogWrite(9, 0);
  analogWrite(10, 0);
  delay(50);

  }

  void goRight(int x)
  {
  analogWrite(5, 0);
  analogWrite(6, 0);
  analogWrite(9, x);
  analogWrite(10, 0);
  delay(50);

  }

  void halt()
  {
  analogWrite(5, 0);
  analogWrite(6, 0);
  analogWrite(9, 0);
  analogWrite(10, 0);
  delay(50);

  }

```

**I wanted to use the analogWrite() function to control the speed of the motor. However, the code does not work at all if I use the analogWrite() function within the goForward(), goBackward(), goLeft(), goRight() functions to control the speed of the motor, only one of the motors keeps rotating at a certain speed without responding to the transmitter. Surprisingly, if I use digitalWrite() to control the motors, they work fine, instantly responding to the change in direction of the transmitter. P.S. I connected my motors to PWM pins of the Arduino.**

**What's the problem?**

# Answer
> 0 votes
VirtualWire uses timer1, which would disable PWM on pins 9 and 10.

---
Tags: programming, arduino-ide, arduino-nano, robotics
---


# Question
Title: Serial.readString() not working becaue of outdated IDE?
I've searched google honestly but can't find an answer nor changelogs for Arduino that might be the answer.

Basically I'm trying to use Serial.readString() to input commands to the Serial Monitor but it shows an error that readString is not a member of 'HardwareSerial'.

I am using Arduino 1.0 as IDE because the device I'm using (Aceduino) seems to have a custom IDE derived from 1.0 so I'm not sure if it will work with newer IDE versions. Wondering if that was what's causing the eror

# Answer
> 1 votes
`Stream::readString()` is available since version 1.0.1. See:

---
Tags: serial
---


title: use more then one timer

text:
# Question
Title: use more then one timer
I'm working on Arduino uno and trying to use more then one timer. I'm using timer1 for my software watchdog (I needed bigger interval for that, so my program won't reset itself after 8 seconds). In addition, I'm using timer2 for regular interrupt like turn off pin after 8 seconds. The problem is that the timer1's interrupt override timer2's interrupt.

Is it possible to to use both of them?

# Answer
> 1 votes
In general, once an embedded processor's interrupt fires, the interrupt routine clears the interrupt. Usually inside the interrupt routine. Failure to clear the interrupt normally inhibits further interrupts.

That said, in the Arduino paradigm, this is "taken care of" by the Arduino Timer library described here. In the example code:

```
/*
 *  Timer1 library example
 *  June 2008 | jesse dot tane at gmail dot com
 */

#include "TimerOne.h"

void setup()
{
  pinMode(10, OUTPUT);
  Timer1.initialize(500000);         // initialize timer1, and set a 1/2 second period
  Timer1.pwm(9, 512);                // setup pwm on pin 9, 50% duty cycle
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
}

void callback()
{
  digitalWrite(10, digitalRead(10) ^ 1);
}

void loop()
{
  // your program here...
}

```

...you can see that the example does not actually contain "the" Timer interrupt routine but rather a callback() routine which the Timer library calls when the Timer interrupt occurs. Code to clear the Timer interrupt is missing and assumed to be in the Timer library.

Consider this if you are writing you own interrupt routine instead of using the Arduino's Timer library.

*I'm going to have to call foul on myself. Clearing interrupts in their own interrupt routine is very common. But looking at this page, where the Atmel timer hardware is directly controlled (that is, the normal Arduino Timer library is not being used) and the real interrupt handler exists in the sketch, I see where this is not done. So, for the Atmel, there must be at least one timer mode where the timer interrupt does not have to be clear for the interrupt to happen again.*

If you are using the Arduino's Timer library consider this warning from the Timer's library web page linked to above:

> Be careful about trying to execute too complicated of an interrupt at too high of a frequency, or the CPU may never enter the main loop and your program will 'lock up'.

Finally, hardware timed interrupts are normally reserved for operations which are time sensitive and occur much faster than executing code can handle. For events that happen on the order of seconds, most applications setup 1 timed interrupt to count off a convenient interval. Say 1 second. Code is used to keep count and call the proper functions at the intended time.

---
Tags: arduino-uno, timers
---


# Question
Title: Timer function without the use of a library
Trying to do my own timer function. I was wondering if there is any other ways to make my code more efficient without the use of a library. I noticed if I only use one timer function, I wont have multiple instances of the timer. My current code works though.

```
unsigned long previousMillis1 = 0;
unsigned long currentMillis1 = millis();
unsigned long previousMillis2 = 0;
unsigned long currentMillis2 = millis();
unsigned long previousMillis3 = 0;
unsigned long currentMillis3 = millis();

bool timer1(int preset){
  unsigned long currentMillis1 = millis();

  if(currentMillis1 - previousMillis1 >= preset ){
    previousMillis1 = currentMillis1;
    return true;
  }
  else{
    return false;
  }
}

bool timer2(int preset){
  unsigned long currentMillis2 = millis();

  if(currentMillis2 - previousMillis2 >= preset ){
    previousMillis2 = currentMillis2;
    return true;
  }
  else{
    return false;
  }
}

bool timer3(int preset){
  unsigned long currentMillis3 = millis();

  if(currentMillis3 - previousMillis3 >= preset ){
    previousMillis3 = currentMillis3;
    return true;
  }
  else{
    return false;
  }
}

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

void loop() {
  if(timer1(1000)){Serial.println(1);}
  if(timer2(2000)){Serial.println(2);}
  if(timer3(3000)){Serial.println(3);}
}

```

# Answer
Your code is not bad in terms of efficiency. You have, however, duplicated code, which is bad in terms of program size, but also makes the program harder to read and to maintain. A good rule for programmers is “do not repeat yourself”. Then, when you find yourself writing almost identical functions, you should try to find a way to merge them into a single function.

Here it is easy: the only difference between your timer functions is that they use a different `previousMillis` variable. Also, the name of the `currentMillis` variable is different, but it being a local variable, this difference is irrelevant. Then, to merge them into a single function, you only have to give to this function a *reference* to the relevant `PreviousMillis`.

```
bool timer(unsigned long &last_time, unsigned long period)
{
  unsigned long now = millis();
  if (now - last_time >= period) {
    last_time = now;
    return true;
  }
  return false;
}

```

And you use it like this:

```
void loop() {
  static unsigned long previousMillis1;
  static unsigned long previousMillis2;
  static unsigned long previousMillis3;

  if (timer(previousMillis1, 1000)) Serial.println(1);
  if (timer(previousMillis2, 2000)) Serial.println(2);
  if (timer(previousMillis3, 3000)) Serial.println(3);
}

```

I took the liberty of making all the `previousMillis` local to `loop()`, since they are only used there. Making them `static` means their values are remembered between call to `loop()`, much like global variables.

In plain C you would use pointers instead of references. It is basically the same, except that with pointers you are *explicitly* manipulating addresses, while this is implicit with references:

```
bool timer(unsigned long *last_time, unsigned long period)
{
  unsigned long now = millis();
  if (now - *last_time >= period) {
    *last_time = now;
    return true;
  }
  return false;
}

void loop() {
  /* [...] */
  if (timer(&previousMillis1, 1000)) Serial.println(1);
  /* [...] */
}

```

The next step in code modularity would be to wrap this timer function, together with the associated data (`last_time` and `period`), inside a class:

```
class Timer
{
public:

  Timer(unsigned long _period)
  : period(_period), last_time(millis()) {}

  bool shouldRun() {
    unsigned long now = millis();
    if (now - last_time >= period) {
      last_time = now;
      return true;
    }
    return false;
  }

private:
  unsigned long period;
  unsigned long last_time;
};

```

Then, you would use it like this:

```
Timer timer1(1000);    // period = 1000 ms
Timer timer2(2000);    // period = 2000 ms
Timer timer3(3000);    // period = 3000 ms

void loop() {
  if (timer1.shouldRun()) Serial.println(1);
  if (timer2.shouldRun()) Serial.println(2);
  if (timer3.shouldRun()) Serial.println(3);
}

```
> 3 votes

# Answer
You can simplify **a lot** by using arrays. The example code below just uses a single variable (array) to store all the time intervals you are interested in.

```
const int NUMBER_OF_TIMERS = 5;

unsigned long intervalStarted [NUMBER_OF_TIMERS];

void resetTimer (const int whichTimer)
  {
  if (whichTimer < 0 || whichTimer >= NUMBER_OF_TIMERS)
    return;   // sanity clause
  intervalStarted [whichTimer] = millis ();
  }  // end of resetTimer

// interval in milliseconds
bool timeUp (const int whichTimer, const unsigned long whatInterval)
  {
  if (whichTimer < 0 || whichTimer >= NUMBER_OF_TIMERS)
    return false;   // sanity clause
  return  millis () - intervalStarted [whichTimer] >= whatInterval;
  }  // end of timeUp

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  Serial.println (F("Starting ..."));
  }  // end of setup

void loop ()
  {

  if(timeUp(0, 1000))
    {
    Serial.println(1);
    resetTimer (0);
    }  // end of if timer 0 up

  if(timeUp(1, 2000))
    {
    Serial.println(2);
    resetTimer (1);
    }  // end of if timer 1 up

  if(timeUp(2, 3000))
    {
    Serial.println(3);
    resetTimer (2);
    } // end of if timer 2 up

  }  // end of loop

```

I have allowed for 5 "timers" in the code but only used 3 to be consistent with the original post. You can see that you can have as many as you want (until you run out of RAM) with only an overhead of 4 bytes per "timer".

Two functions are provided. One checks if a nominated interval is up, the other one "resets" the timer by setting its start time to now. The checking function should work correctly even during millis() wrap-around, providing you are not trying to time more than 4294967296 milliseconds in one hit (49.71 days).

Note that the timer numbers are zero-relative, so the first timer is timer 0. You could make them one-relative if you prefer that with a slight adjustment to the two functions.

You could also, if you chose to, put the resetTimer function call inside the timeUp function (if the time is up) so that the timer automatically resets. I didn't do that because I think starting timing, and detecting the end of a period could be two different things. For example, when you boil an egg, you start timing from the time the egg goes onto the boil, not from when you last cooked an egg.
> 2 votes

# Answer
It depends on what kind of efficiency you want. In coding we can often between better execution speed and less memory required. And in the case of Harvard-architected machines such as the AVR devices, which have separate memories for code and data, there may be a further balance between those, too.

But it looks like you're trying to reduce your code space requirement. So notice how alike your three timer functions are. I'd combine those into one, and pass another argument that indicates which timer value to operate on.

Secondly, (and this is probably a bug more than an inefficiency), you have three globals that are not being used (in your example, anyway): `long currentMillis1`, ..2, & ..3. You have redeclared each of those names as a local variable in the respective timer function, which, within that function over-rides (hides) the global declaration. There is no code that uses those globals.
> 0 votes

# Answer
Happened across this page which explains Arduino timer interrupts with out using any libraries. The Atmel timer hardware is discussed and the sketches not only control the hardware directly but also include the actual interrupt service routine. So addresses the OP's question very well.
> 0 votes

# Answer
1. Those lines like

currentMillis1;

are completely useless
2. You do not really have "timers", especially if your goal is to be more efficient. What you have done is to create some convoluted way to perform a test that could be done as:

int PERIOD = something; for (int target = millis() + PERIOD; millis() \< target;);
3. If you really care about efficiency and timed actions, check some library that deals with timer interrupts.
4. Start reading the code of existing libraries and try to understand it. Chances are that who wrote them knew a great deal more than you know. You will learn much more from first reading the code than trying to accomplish something that is clearly too much beyond your current knowledge (the fact you think what you did is an optimization proves it).
> -1 votes

---
Tags: arduino-uno, timers
---


# Question
Title: How do I get the Itead 3G shield to work?
I've tried a pretty standard code but the Serial Monitor yields zero response.

Using a standard Arduino Uno (tried a second one as well, just to be sure) and am now trying the second shield with this code:

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

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

}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

```

There is nothing coming back whatsoever in the serial monitor (yep, I checked the baud rate and tried several others).

Any ideas?

What should I be seeing if anything?

# Answer
> What should I be seeing if anything?

Usually, a GSM module will not send (unsollicited) messages. Everything it sends will be an response to an received message.

Try sending `AT` (with a new line/carriage return (depending on the GSM module)) to the GSM module, it will send something like `AT OK` or just `OK`

And you didn't set the pin directions (output/input), might be doen by the serial libraries, but beter be safe if you're not sure.

Also check your wiring (jumpers on UART multiplexer in this case?) and share it with us, Rx/Tx wiring often gets messed up :) If your GSM module has a USB connection, you might even test it with a terminal (taking out the Arduino in the middle, thus any wiring/code between.)

I also suggest you change the name of the serial connection to the GSM to something like `gsmSerial` rather than mySerial (which could be anything).

Be sure the 3G shield has enough power (amperes), otherwise they might reset when attempting to make an connection. (Put the external supply in the Arduino, rather than USB powered)
> 1 votes

# Answer
I have one, and I haven't figured out how to get it to accept input, but have received responses. Here are some things to try:

* Make sure you have your jumpers set for D2 and D3. Just telling software serial to look at 2 and 3 doesn't mean your board is jumpered that way.

+ Also, remember that Tx for the board = Rx on the arduino and in your code. Software serial is (rx, tx), so (2,3) means your board will be jumpered with tx on 2 and rx on 3.
* There are four LEDs on the board. If all four aren't lit, the board is powered down, and won't do anything.

+ First, make sure your power switch is set right - "VCC Switch", by the USB connector, is set to the power level of your board. I'm using an Uno at 5V, so for me that's set to 5V.
    + It's best to provide power through your barrel connector on your Arduino *and* connection through the USB. GSM modules *are* power hogs.
    + With all of that plugged in, your board should show two lights, the first and third.
    + Now hit the "PWR" button. The second light will come on dimly, then stronger. Now the module has power.
    + Finally, the fourth light will come on when the module has detected network. At that point, the 5216 will start sending you messages.
* You need to make sure your baudrate is set properly. Anything less than a Mega can't handle communication at 115200, which is the default for the module. At best, you'll set both Serial and SoftwareSerial for 115200 baud, and you'll get mostly correct characters from the board, but an occasional bad character.
* Here are some great instructions for changing the default baudrate at Github from some JeanBritz
    + One caveat to those instructions: make sure you have your Itead board powered by the Uno *before* plugging into the mini USB.

Here's a bit of light at the end of the tunnel for you -
> 1 votes

---
Tags: softwareserial
---


# Question
Title: Controlling a NC connection from two sources?
I'm trying to control a garage door opener. The button that lets you open the door from the inside is a NC connection (press the button and it goes to "open" and makes the motor run).

I want to keep that AND add another source (an Arduino w/ an RF module) that taps in to this.

Is there some sort of splitter I'd add to the garage door button wires to do this?

# Answer
> 0 votes
Are you certain that your existing circuit is NC?

The typical garage door opener button is a momentary switch. Many third party remote devices, including two that I have installed, tap directly into this circuit. Because the contacts short across the existing switch, activating one, two or three is insignificant. These switches are connected in parallel.

It would be a good idea to use an external isolation circuit to the Arduino, either a relay or SSR in order to ensure that there is no "injected" power from your circuit to the garage door circuit.

If your circuit is indeed an NC type, you would connect your new relay or SSR in series, using the device's NC connections. The locations for tapping into the circuit would be where your existing button resides or where those two wires engage your garage door mechanism.

I suppose my older garage door opener is NO, while newer models would use a different architecture, aka NC.

---
Tags: wires
---


# Question
Title: Strange problem. Arduino stops working after few hours. Opinions please
I am trying to setup an automated relay for my aquarium. The Arduino should switch off the pump every 3 hours for 20 minutes, and feed at particular times during the day. The code works fine for the first two on/off cycles. However after that the system stops responding.

I have tried many ways to solve the issue, I am led to believe that the issue could be a memory leak, which I have tried to fix that with watchdog timer reset, I have also tried resetting the Arduino but it doesn't work after the first reset.

I am still not sure what the problem could be, so any information would be appreciated.

I have included the code that I have stitched together using references from the web and a schematic of my circuit along with a picture of a tiny RTC module.

Schematic:

Tiny RTC:

My code is below, any advice would be appreciated.

```
#include "Wire.h"
 #define DS1307_ADDRESS 0x68
 #define RELAY_PIN 2
 #define Feed_PIN 4
 #define led13 13

 void setup() {
   Wire.begin();
   Serial.begin(9600);
   pinMode(RELAY_PIN, OUTPUT);
   pinMode(Feed_PIN, OUTPUT);
   pinMode(led13, OUTPUT);
 }

 void loop() {
   printDate();
   // digitalWrite(led13, HIGH);
   //delay(500);
   //delay(500);
   //digitalWrite(led13, LOW);
   // byte zero = 0x00;
   ///Wire.write(zero);
 }

 byte bcdToDec(byte val)  {
   // Convert binary coded decimal to normal decimal numbers
   return ( (val / 16 * 10) + (val % 16) );
 }

 void printDate() {
   // Reset the register pointer
   Wire.beginTransmission(DS1307_ADDRESS);
   byte zero = 0x00;
   Wire.write(zero);
   Wire.endTransmission();
   Wire.requestFrom(DS1307_ADDRESS, 7);
   int second = bcdToDec(Wire.read());
   int minute = bcdToDec(Wire.read());
   int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
   int weekDay = bcdToDec(Wire.read()); //0-6 -> sun-sat
   int monthDay = bcdToDec(Wire.read());
   int month = bcdToDec(Wire.read());
   int year = bcdToDec(Wire.read());
   //print the date EG   3/1/11 23:59:59
   Serial.print(month);
   Serial.print("/");
   Serial.print(monthDay);
   Serial.print("/");
   Serial.print(year);
   Serial.print(" ");
   Serial.print(hour);
   Serial.print(":");
   Serial.print(minute);
   Serial.print(":");
   Serial.println(second);
   if ( (hour ==  9 && (minute >= 00 && minute <= 20)) ||
        (hour == 12 && (minute >= 20 && minute <= 40)) ||
        (hour == 15 && (minute >= 40 && minute <= 59)) ||
        (hour == 18 && (minute >= 00 && minute <= 20)) ||
        (hour == 20 && (minute >= 20 && minute <= 40)) ||
        (hour == 22 && (minute >= 40 && minute <= 59)) ||
        (hour ==  1 && (minute >= 00 && minute <= 20)) ||
        (hour ==  3 && (minute >= 20 && minute <= 40)) ||
        (hour ==  5 && (minute >= 40 && minute <= 59)))
   {
     Serial.print(month);
     Serial.print("/");
     Serial.print(monthDay);
     Serial.print("/");
     Serial.print(year);
     Serial.print(" ");
     Serial.print(hour);
     Serial.print(":");
     Serial.print(minute);
     Serial.print(":");
     Serial.println(second);
     Serial.print(':');
     Serial.print(':');
     Serial.println(", pump off!");

     digitalWrite(RELAY_PIN, HIGH);
   } else {
     digitalWrite(RELAY_PIN, LOW);
   }

   if ((hour ==  2 && minute == 43 && second >= 52) ||
       (hour == 10 && minute == 00 && second >= 52) ||
       (hour == 13 && minute == 00 && second >= 52) ||
       (hour == 16 && minute == 00 && second >= 52))
   {
     digitalWrite(Feed_PIN, HIGH);
     Serial.println("feeding fish.....");
   } else {
     digitalWrite(Feed_PIN, LOW);
   }
 }

```

# Answer
> 1 votes
Your code seems fine, I cannot give a comment yet due to me not being a high enough ranked member, so i will try to phrase this as annswer instead.

Your arduino might be the problem, but I don't think it is likely as the clock is known to be troublesome, but as "transistor" suggested you should let it run on the serial for some time so that you can see if time is reported correctly.

I time is not working then I would like to direct your attention to this thread on the arduino forum, as this is apperently a very poor module. Several people have clocks that doesn't function properbly and there is many post adressing troubleshooting, but since this is supposed to be answer I have taken the top issues and put in below.

https://forum.arduino.cc/index.php?topic=177297.0

primarely they problems come from:

an unrechargeable **Cr**2032 battery is shipped, instead of a rechargeable **li**2032, this cause the charging Circuit on the board to act up.

Fix : replace to **li**2032 or remove charging circuitry - se link

ungrounded crystal - may or may not be a real issue

Fix: ground the crystal

Bad crystal:

Fix: replace crystal

Error in design - Resistor nr. 7 in place

Fix: remove resistor

# Answer
> 0 votes
Perhaps you can try `while (Wire.available() != 7);` before calling `Wire.read()` 7 times in succession. Also remove leading zeros in the integer literals of 0 in your IF conditions. And make `bcdToDec` return an `int` instead of a `byte`, in the unlikely case of any overflow issues.

# Answer
> 0 votes
I know a very rough brute force idea, but I'm afraid you won't like it.

Here, how it goes: Use additional relay for powering arduino: While arduino is turned on, let the power be connected to NC contact and after each cycle, just turn this output to HIGH. How it works, you ask? Well, after a cycle, you will with logic 1 (HIGH) state cause to "unplug" the arduino power, which will lead to loosing power supply. However, the relay has a spring, that in case of loosing power, it goes back to NC, in which case, your arduino will be reset and working for another cycle.

That should 100% work, but as I said before: It's a horrible brute force idea :)

# Answer
> -1 votes
I had something same with my Arduino UNO weather station until I switch to the PSU with lead battery. The most common thing is the power supply. Try to use more powerful and use the ferrites on the PSU wires.

---
Tags: motor, i2c, timers, relay, rtc
---


# Question
Title: does eeprom_write_block function of avr.eeprom.h writes a NULL terminated string or we have to manually null terminate it
http://www.nongnu.org/avr-libc/user-manual/group\__avr\__eeprom.html

I am trying to figure out that if we use `eeprom_write_block` function or `eeprom_update_block` function do we need to manually null terminate it?

I came across this tutorial on avr-freaks where in one comment it is said that you have to read the strings and null terminate them but there is no word about writing. Couldnt get anything the avr-libc manual as well.

**UPDATE**

I have reserved some parts of eeprom using `EEMEM` and they are strings. I am not sure how long the string would be except that it would be smaller than a max value. Now When I would read the string back from the eeprom I would just be reading the maximum number of bytes as again I would have no idea of the size of the string. If the eeprom has a null value at the end of the string when writing to it, the read string will have that null at the correct place.

**Situation**

I am saving mobile numbers of users as:

```
uint8_t EEMEM users[numberOfUsers][maxChar4Number];

```

Now when I get a number parsed and then save it to eeprom

```
#define eepu(message, EEADDR, BLKSIZE) eeprom_update_block((const void *)message, (void *)EEADDR, BLKSIZE);

eepu(user, users[0], strlen(user)); //strlen(user) will be less than the maxChar4Number

```

This will write the number to eeprom. When I read the i would be reading maxChar4Number bytes and a number could have been shorter than that length.

# Answer
> 1 votes
If you write a block which happens to be null-terminated, then reading it back should be fine. I do that when I want to save a filename in EEPROM. Just declare a suitable length (allowing room for the null terminator) and write the entire block to EEPROM.

# Answer
> 1 votes
Since one normally does not know how long a character string is, we need a way to convey this information. One technique used to avoid confusion is to add a NULL character (which is a zero) to the end of the string. Another is to explicitly state how long the string is.

In the case of the function eeprom\_write\_block() talked about here, we see that we are formally passing not only a pointer to the string but also the size of the string.

---
Tags: avr, eeprom
---


# Question
Title: Potentiometer on motor for position control
I am using a wiper motor as a rotor. I am trying to get it to at least point in different azimuths (compass azimuths eg. 180 degrees) In order to do this, I am thinking about attaching a potentiometer on the axle inside the motor housing to see where the motor is pointing.

So lets say the pot gives me a range of 0-1023. If I divide 1023 by 360 i get 2.84. So lets say the pot gives the Arduino a 1, I can relate that to 2.84 degrees?

Also, what if the motor is pointing at 350 degrees, and I want it to point at 2 degrees. Instead of it turning around 348 degrees, it just cross pass 360 and go to 2 degrees. How would a pot handle going over a single step? If the motor passed a single step would it consistently give me a 1023 reading?

I am trying to get a wiper motor to have a known position 360 degrees around.

# Answer
> 1 votes
> I am trying to get a wiper motor to have a known position 360 degrees around.

There might be a few possibilities.

First there **are** continuous rotation potentiometers on the market. They seem expensive though and I can't comment on how accurate they are.

Second, **if** your device is only ever going to turn through say ten revolutions then go back, you could just get a multiturn pot that will handle that range of turns. (Depends what you're building of course - for example I've heard of servo winches for model sailboats that use this method.)

Thirdly, and I accept this may not be a good answer to your question, but have you thought about using incremental encoders instead? In theory they could be more accurate too. The hardware is quite easy but a bit more programming is required to make these work...

# Answer
> 0 votes
> So lets say the pot gives the Ardunio a 1, I can relate that to 2.84 degrees?

Yes, if the pot goes from 0 to 1023 in 360 degrees of rotation, and it can rotate continuously. That sounds unlikely - f/ex, thinking about how a pot is made, how will it get from its maximum resistance to its minimum resistance in 2.8 degrees?

> Instead of it turning around 348 degrees, it just cross pass 360

Smart software. :) You would need to read the pot, decide which direction of rotation will get from the current position to the new position, and select that direction in the motor drive circuit.

Update: A pot doesn't really "output" anything; it is a variable-resistor, whose resistance can be measured by placing it in a known electric circuit and using an Arduino A2D input to measure a voltage in that circuit which depends on the resistance of the pot. The reading you get is a 10-bit integer. If you divided that by 1024, you'd have a pure fraction representing the measured voltage as a fraction of the A2D's full-scale voltage, which you select as INTERNAL (1.1v internal reference voltage), or EXTERNAL and apply a reference voltage to the chip's Aref pin. Usually that is the power-supply voltage, and in any case must not exceed the power-supply voltage.

So, back to reality, if you use the EXTERNAL reference with Aref connected to +5v, then the A2D readings would mean:

```
 A2D  Volts  Mag.Azimuth
   0   0       0
 256   1.25   90
 512   2.5   180
 768   3.57  270
1023   4.99+ 359.6

```

In this case you probably don't care about the measured voltage, only it's relationship to 5v, which the A2D already gives you. That relationship equals the pot's relationship to 1 full rotation. So the azimuth, Az, you're seeking:

Az/360 = A2D / 1024, and

Az = (A2D * 360)/1024

---
Tags: potentiometer
---


# Question
Title: How to include <SPI.h> outside the .ino file
As I understand, Arduino IDE considers two paths for the libraries:

first,

> "C:\Program Files\Arduino\libraries"

and second, the "libraries" folder next to the schetchbook.

I have a configuration.h file, that I include in the main file, `Test.ino`, like this:

```
#include <configuration.h>

```

and in the `configuration.h` file I try to include `SPI.h` like this:

```
#include <SPI.h>

```

But I get the following error:

```
fatal error: SPI.h: No such file or directory

```

It seems that I am obliged to include `SPI.h` only from the ino file. But why? And how can I do what I want here? do I have to change IDE?

P.S: the software is large and I am improving maintainability.

# Answer
> 3 votes
> It seems that I am obliged to include SPI.h only from the ino file. But why? And how can I do what I want here? do I have to change IDE?

The background is how the Arduino IDE pre-processor works together with the GCC AVR compiler and build tools.

The compiler needs to know the include path to the libraries. This is created by the pre-processor by scanning the ino file and searching the known libraries. A compiler command line is built with the include paths to the located libraries.

If you move the library includes to a configuration file the IDE pre-processor will not be able to locate the libraries and create the include paths. The pre-processor does not recursively scan library files.

Cheers!

# Answer
> 5 votes
See my answer How the IDE organizes things. There is no easy way to avoid having to put an include in the main .ino file, unless you write your own build process (or perhaps use another toolchain).

I think you could put SPI.h (and other things, like Wire.h) in the main .ino file, even if they aren't used due to your configuration parameters. The linker would strip them out because the modules were not referenced.

# Answer
> 2 votes
The IDE has to be explicitly told each and every library that you use. It also has to be told each and every library that every library that you use uses. And so on.

The Arduino IDE only looks in the INO files. As a result: if the library is not included in the main INO file then the IDE doesn't know that you intend to use it, and so it doesn't look for it.
Only when it's in the INO file will the IDE actually look for where that library is located and append the right flags (-I...path...) to the compilation commands to be able to get at the files for it.

Further, it is only then that it actually knows that it should compile the source code for a library. Without that knowledge, even if you explicitly point to the header file with a relative path, the IDE won't know that it should compile and link the source code.

There is no way around it, it's just the way the IDE works. The only option is to change to a different IDE that has more intelligence and can recursively deep-scan the libraries to maintain a list of prerequisites (such as my popular UECIDE IDE).

---
Tags: arduino-ide, spi, compile
---


# Question
Title: Arduino i2c communication between another arduino and a sensor
Can the following scenario exist?  Microcontroller 1 sends a code to microcontroller 2 to start reading sensor data. Then Microcontroller 2 reads sensor data from sensor and sends it back to microcontroller 1.

If such a scenario is possible, then how would the pseudo code for microcontroller 2 receive-event be?

Need help with this badly!!

# Answer
> Can the following scenario exist? Yes. Such a scenario is called *Multi-Master*.
>
> If such a scenario is possible, then how would the pseudo code for microcontroller 2 receive-event be?

MCU 2 would just be set up as any other slave. It waits, as normal, for an instruction in whatever for you like. Once it receives that instruction in then switches into master mode and makes a normal request exactly as you would from MCU 1 if you wanted it to read the sensor.

* On receive:
    + Set "run as master flag"
    + Disable slave mode

In loop:

* If "run as master flag" is set:
    + Perform request to get data from sensor
    + Clear "run as master flag"
    + Enable slave mode

Running a multi-master system does have its own set of caveats and things you have to watch out for. You can read more about it here:
> 1 votes

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


# Question
Title: How to use code for OV7670 on Arduino Uno
I want to interface my OV7670 camera (without FIFO) to my Arduino Uno. I have browsed internet quite a lot about it and found people either saying it's not possible or they just give me the link to this github repository (As this guy has done exactly what I want). As the author of this repository is a man of few words, he did not help me very much. I just want to know how to use this to get image sent to my PC serially. I only know how to use Arduino IDE in windows platform and no other platform.

# Answer
I am ComputerNerd. I read this post and realized the real problem and why I am having difficulty helping you. You are asking the wrong question. What you should be asking is "how do I compile it using GNU Make and Avr-Gcc on Windows?". Instead you are asking "how can I use this code in the Arduino IDE?".

The answer to what you should be asking is simple. Use what you already have. The Arduino IDE ships with Avr-gcc and (maybe) GNU Make. Just run the programs directly. Better yet download MinGW and compile GCC to target the AVR yourself.
> 1 votes

# Answer
ComputerNerds work is good, but it is has only code and limited description. I have prepared detailed instruction using his code. You can try it: How to use OV7670 and Arduino uno
> 1 votes

# Answer
I have successfully compiled the project in arduino IDE, simply concatenated main.c and ov7670.c ov7670.h into .ino file

didn't test it with the camera yet, but it uploaded to my arduino (Duemilanove) Tell me if it worked for you...

see here: https://github.com/eranws/ov7670-no-ram-arduino-uno
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Unusual behaviour over serial communication
I am sending data over serial connection from a python script to my Arduino UNO. Now initially whenever I tried to send data to the arduino, it would reset. The fix was to put a 10 microFarad capacitor between the 5V and RESET pins. I did that and everything started working.

Now after while, mistakenly today I ran the same script without the capacitor between the 5V and RESET pins and for some reason it was working perfectly well. No more resetting when a value was received over serial communication.

Is something wrong with my Arduino?

# Answer
> -1 votes
Knowing the entire setup would help. For instance, knowing if the RS232 source will drive the Arduino input's dangerously past the Arduino's power rails.

If you have connected a real RS232 signal to the Arduino, the +12 to -12 volt swings could adversely affect the processor. Causing unexpected behavior. In such a case you would need a converter like this one.

Over driving inputs is discussed in this Stack Exchange question where the highest scoring answer says:

> If you violate the spec sheet normal operating conditions requirements you can expect to experience abnormal operating conditions. These may range fro perfectly normal opration through complete maloperation...

That answer also links to this tutorial about logic level conversion.

Finally, there is this tutorial which specifically addresses converting RS232 to safe TTL level signals appropriate for a micro processor.

---
Tags: arduino-uno, serial, python
---


# Question
Title: Can you output to D+ and D- so that Arduino Uno can be used as a USB device?
My project is basically a set of 5 audio signals (analog) that get altered slightly by Arduino Uno. I convert to MIDI and would then output it to USB, so that it can be used in a program of my choice on the computer. I found a vaguely similar project online with a guide. In that project they write a serial to a MIDI out, and then plug that into a computer. I'm fairly sure I can't just use the TX and run that into the USB, that wouldn't work. So I'm looking for an alternative method.

# Answer
Not with an Uno, no. You can only use USB Serial (CDC/ACM) through the on-board USB chip\[1\].

Your best bet is probably with a Teensy 3 (or 3.1 or whatever they are up to now) which has built-in support for USB MIDI emulation.

---

1: I believe there is MIDI firmware for the USB chip on the Uno, but installing that requires a hardware programmer and then breaks the normal sketch upload.
> 1 votes

# Answer
As noted in Majenko's answer, an Uno would require some non-trivial modifications before it would be usable as you want.

Some Arduino models – Leonardo and early Pro Micros – were based on ATmega32U4 chips instead of ATmega168 or ATmega328 chips. The 32U4 has USB support built in. The Mouse and Keyboard libraries allow interacting with a host computer such that from the host the Arduino looks like a mouse or keyboard.
> 0 votes

# Answer
The simpler thing would be to output the MIDI through the serial port, and then convert that into MIDI voltage levels like this:

Then plug that into a suitable MIDI-to-USB adapter. However I would have thought that that extra step (converting to MIDI voltage and back again) would be unnecessary. Can't your computer read MIDI directly from serial? I mean, the Uno has a USB interface. If you send MIDI data at 31250 baud, how is the program on the PC going to know it isn't a real MIDI device on the USB port?
> 0 votes

---
Tags: arduino-uno, serial, usb, audio
---


# Question
Title: Driving single-character alphanumeric (16-segment) displays
I would like to drive three sixteen-segment displays (https://www.sparkfun.com/products/retired/9934) using an Arduino Micro. These displays would output an alphabetic character that a user would scroll through using rotary encoders, and constitute a subsystem of a larger project where the user enters a "combination" made from the three letters to "unlock" functionality in the larger device.

The best option, if it could be called that, is this retired product from SparkFun: https://www.sparkfun.com/products/retired/10103 that would allow me to drive the displays without a huge wiring mess, and spares me a lot of pins on the Micro to use on the rotary encoder. Unfortunately, the product is retired because the A6282 IC it was based on reached end of life, so even the schematics available on the product page aren't much use to me.

I am aware that four-character 16-segment displays are available, but for "aesthetic" reasons I am constraining myself to using single-character 16-segment displays. I do wonder how possible it would be to run three or four individual 16-seg displays from one of those LCD backpacks, but I don't think that would be trivial to do (I'd need to, probably, fabricate some sort of printed circuit board that spaced each display as far out as I need them to be, hook the pins of each display into a key matrix, and then at that point it'd be substantially easier to just get a MAX6954 (https://www.maximintegrated.com/en/app-notes/index.mvp/id/3212) and try to figure that out). It would be very clumsy to prototype.

So, I'm looking for a solid method of prototyping this "combination entry" subsystem and its 16 segment displays without needing to put each dial and alphanumeric display on its own AVR or something.

# Answer
> 1 votes
If you need additional IO lines, a typical “LCD backpack” supplies at most eight additional lines of IO; 16-channel TLC59116 LED Driver Board as mentioned by Majenko would be more elegant than using several backpacks.

You might try an approach like the following to see if it works well enough.

Use 16 IO lines to pull down 16 segment lines. Use three IO lines to drive three digit-select PNP or PFET transistors for digit multiplexing. Use pin-change interrupts on two IO lines to read rotary encoder (RE) data. Use one input to read the RE pushbutton. Use one IO line to notify the bigger unit of success. Total 23 IO lines.

In operation, your code will need to implement a state machine that frequently refreshes the multiplexed digits while keeping track of digit values, selected digit, etc. Each time you click the RE have your sketch go on to the next digit. To tell the user which digit is working, blink the selected digit a couple of times after the RE press. Each time that selection wraps around to the first digit, check if the combination is correct.

If you feel it's necessary to have three different digit-setting knobs, vs clicking through to each digit, you could use one less IO line by using three pots instead of one RE. The pots would be read in analog. A6 and A7, IIRC not usable for output lines, could be used as analog inputs for two of the pots.

# Answer
> 1 votes
The other answers give great suggestions, but to add to them you could consider the MAX7219 driver chip. I have a page about using it. It can drive a 8x8 pixel display (like one alphanumeric character) or 8 x 7-segments displays (a 7-segment display usually has a decimal place so that is really an 8-LED display).

Example of 64-pixel display:

Example of 8 x 7-segment displays:

Those displays come as a unit (2 x 4 digits) but there is nothing stopping you running wires to individual 1-digit displays if you want to.

Here is a possible schematic:

If you are running to individual displays you just parallel-up the anodes (A to G, plus DP) and run a "digit" line to the cathode of each display.

---

That will only take 3 signals from your processor (MOSI, SCK, SS) plus power and ground.

---

I notice you are talking about 16-segment displays and not 8-segment displays, but the chip allows any bit patterns to be sent out, so you could consider a 16-segment display to be the same as 2 x 8-segment displays. You would just have to make up a suitable bit-pattern to show each digit.

The MAX7219 also handles the requirement for constant-current driving of the LEDs.

---
Tags: arduino-micro, display
---


title: Append to .h file through arduino code

text:
# Question
Title: Append to .h file through arduino code
I'm at the stage where I can #include headerFiles.h into my arduino sketches.

I'm just beginning to wonder whether it's possible to append strings that are concatenated from integers which are analogRead from sensors to a .h file?

It'd make the arduino a lot more portable and would negate having to buy an SD card module.

How would the data be extracted? EEPROM is too small for datalogging past what you'd rack up in text over a reading every minute for a few hours.

Any clever clogs got ideas for this?

# Answer
> 3 votes
Header files are part of your source code. The result of a build is a set of ones and zeros which are sent to your arduino and written in its Flash memory (the program space). The way you put these zeroes and ones together is completely up to you. You could write C and/or C++ code (where you have header files), you could write assembly code or you could write the zeroes and one directly on the disk, if you are crazy enough. Header and Source files live only in the world of the developer and its toolchain, Arduino doesn't know they exist at all.

That being said, if you want to store log data you could use a SD card like you said, or send it over the network, or you could use a serial connection. But I'm sure there are plenty of other options.

# Answer
> 1 votes
Header files are used to "encapsulate" functionality of your code. When you #include a header file, what you are actually doing is, as perhaps an oversimplification, "pasting" the code from that header file into your sketch above where the main code you've written in that file resides. You can then call on functions defined in the header file. Usually, at this level, you are using header files to include useful code that other programmers have contributed to a "library" that has some functionality that makes your life easier -- UART or Wire for communication, or perhaps being able to write to one of Adafruit's LCD displays with a single function call.

Programmers will also write their own header files to improve readability of their code -- for example, by encapsulating all code related to a particular functionality, perhaps troubleshooting, in one file. Another header file in the same program might, a bit ironically, be dedicated to input/output functions (but in the sense that it handles the reading and writing of data on some storage medium, such as an SD card). Header files can also #include other header files (if you're careful about how you do so).

However, header files are not usable "input/output." The compiler will read it all as one program and flash it to the Arduino just like any other code you have written.

http://www.learncpp.com/cpp-tutorial/19-header-files/

# Answer
> 0 votes
> I'm just beginning to wonder whether it's possible to append strings that are concatenated from integers which are analogRead from sensors to a .h file?

No, you have the wrong end of the stick here. You can't **write** to a .h file, certainly not on the Arduino, because it is running independently of the development environment.

> It'd make the arduino a lot more portable and would negate having to buy an SD card module.

An SD module, like the one below, only costs about $US 15, and then you can write gigabytes of data to it, and then easily move the SD card to your PC to process it.

---
Tags: c++
---


# Question
Title: Using two digits to display a number using TM1637 and a 4-digit display
I decided to build a digital clock using a *4-Digit Display* (TM1637) from Grove.

For that, I have been using the *DigitalTube library* by Grove for the TM1637 controller.

My idea is to use the two first digits of the display (left to right) to display the hour and the two last digits to display the minutes. However, managing displays is difficult and all the libraries I have found for the previously mentioned controlled can only display one number per digit.

Here you have an example: Using `tm1637.display(1,2);`, lets you display a "2" in the second digit (L to R), using `tm1637.display(0,3);` lets you display a 3 on the firt digit and etc.

As I said, I want to display the hour on the first two digits and the minutes in the two last digits. I've have readed all the examples coming with the *DigitalTube* library but nothing was useful.

**Note**: I'm using the *DS3231* for managing the time with a RTC.

I don't know if you undestand my question. If not, let me know please. *Arduino UNO R3.*

# Answer
> 2 votes
Using `tm1637.display(digit#, value);` calls, you can display a two-digit number using division to isolate the tens digit and mod to isolate the units digit. For example, if `hour` and `mins` have hour and minute values, respectively, consider code like:

```
tm1637.display(0, hour/10);
tm1637.display(1, hour%10);
tm1637.display(2, mins/10);
tm1637.display(3, mins%10);

```

Code like the above is suitable in cases where values don't exceed 99, and where displaying a leading zero is ok.

If you don't want to display the leading zero when hour is less than 10, add an `if` test and blank the first digit in that case.

---
Tags: arduino-uno, display, rtc
---


title: rs485 and serial ISP

text:
# Question
Title: rs485 and serial ISP
I made a couple of arduino mini pro and esp8266 pcbs with an rs485 transceiver just to find out that I forgot to think about in-system-programming:

Assuming that I don't need to disable the transceiver i tied \*RE/DE to gnd/vcc. It turned out that id *do* need disable the transceiver (at least the receiving part) in order to be able to program the mcu because otherwise the transceiver disrupts the serial data.

But I don't want to lose one pin for this (which in case of an esp8266 are rare) and I don't want to use jumpers because I really like the workflow without.

Is this even possible?

EDIT: The transceiver is an SP3485. Currently it is connected like:

```
Mini Pro     SP3485
A-rx ------  RO
GND  --1k-- *RE   A  ---- somwhere else
Vcc  --1k--  DE   B  ----        "
A-tx ------  DI

```

Which blocks serial programming because of a) the "echo" and b) holding A-rx line high.

If I connect `*RE --1k-- Vcc` and `DE --1k-- GND` I can ISP the Arduino, but now I obviously can't use the transceiver anymore.

# Answer
I'm not sure why you used an RS-485 transceiver if you were only going to permanently enable the two halves? You've basically turned the RS-485 multi-drop into an RS-422 balanced pair-of-pairs. Ah well!

So you wired the transceiver to TX and RX on the ESP8266? And you want to still use those pins to reprogram it, by going "behind" the transceiver and temporarily connect them to your FTDI/whatever? Yeah, sorry: that's not going to work.

The `*RE` pin and `DE` pin only affect the balanced side of the transceiver. The `RX` and `TX` pins on the logic side are still an output and input respectively, regardless of the state of the two Enable pins.

That means that to reprogram, you're going to have to connect your development machine to the balanced side of the transceiver, and you won't have to worry about the Enable pins. Look for RS-422 USB cable adapters - they're out there!
> 1 votes

# Answer
I can't understand the purpose of connecting \*RE/DE to GND/Vcc. With this setup, the driver inside the transceiver is always enabled, and it's always driving the A/B pair. Meaning the device at the other end of the link cannot drive the pair itself without making a collision. Basically you have a simplex link, where the Pro Mini is always the sender.

The normal way to connect an RS-485 transceiver is to have DE driven by a GPIO pin of the MCU. You pull this pin HIGH when you want to talk, and leave it LOW the rest of the time so you can hear other devices talking. The \*RE pin is connected either to GND (if you want to hear the echo of what you say) or to DE (if you don't).

That being said, you are correct in that the transceiver may cause problems when uploading the firmware on the Pro Mini. One possible solution is to put a resistor between RO and A-RX. The TX of the FTDI cable should have a low output impedance and be able to overpower that resistor. Another option is to use ICSP (in-circuit serial programming) instead of going through the bootloader. It would be easier if you can put an ICSP header on your board.
> 1 votes

---
Tags: esp8266, isp, rs485
---