# Question
Title: Switch between timer2 and manually setting output of pin 3
I have a 62.5 kHz square wave created by timer2 on the pin 3. I would like to be able to use digitalWrite(3, HIGH) to force pin 3 high for several clock cycles, but then I would like it to return the 62.5 kHz square wave. Is there a way to reset a single output without resetting the entire program?

```
void setup() {
  Serial.begin(9600);
  pinMode(3, OUTPUT); //Output for OCR2B (Timer 2)
  //The following block allows sets the Timer2 properties for PWM
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(WGM22) | _BV(CS20);
  OCR2A = 255; //Sets the period to 16us (62.5kHz)
  OCR2B = 0; //Sets the duty cycle of the signal (8-bit(255) resolution)
}

void loop() {
  int pot = analogRead(A0);
  int duty = map(pot, 0, 1023, 0, 255); //scale to duty cycle resolution
  OCR2B = duty; //set duty cycle
  delay(10000); //arbitrary wait time
  digitalWrite(3, HIGH);
  delay(10000); //arbitrary wait time
  //undo the digitalWrite to continue the pulse train here
}

```

# Answer
> 1 votes
If you clear the clock select bits in `TCCR2B`, then the PWM stops and you can control the port normally. To re-start the PWM, set the `CS20` bit just as you did in `setup()`.

---
Tags: pwm
---


# Question
Title: Buy a genuine arduino board or a sainsmart board?
Arduino Day is so popular! Many boards are cheap during arduino day. So should I buy a genuine arduino board or a sainsmart board?

# Answer
Buying an official board can be a good choice for a couple of main reasons. First of all, you're guaranteed a good quality board which conforms to the official schematic, and is definitely compatible with any relevant official software and hardware. If the board turns out to be faulty when you get it, you'll be able to get it replaced. Additionally, buying official boards means some of the money you spend goes towards funding future Arduino projects.

As you've no doubt seen, cloned (i.e. unofficial) boards based on Arduino are often much cheaper. Nonetheless, many of the boards are very good. Functionally, you might not see any difference whatsoever from the official/genuine boards. Some of them actually have some additional features which you might find useful depending on your project, such as switching the IO pins between 3.3v and 5v.

However, not all cloned boards are worth using. Some of them may have lower quality components. It's even possible that they weren't designed/constructed correctly in the first place. This could lead to a range of problems, from incompatibilities through to outright failure of the hardware. Given the geographic location of some of the manufacturers/sellers, you may not have any way to get a refund if something goes wrong.

If you choose to use a clone, look for a brand which other people have had success with. Also do your best to ensure the board uses the correct microcontroller (e.g. the Atmega328 for boards based on the Uno).

Ultimately, the decision is up to you. There's no 'right' answer necessarily.
> 3 votes

# Answer
Going by the number of complaints seen about Sainsmart assemblies in the Arduino forum, I would suggest original.

You're also less likely to get a "go ask in the Sainsmart forum" reply when you ask for help in the Arduino forum.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Coding force sensitive resistor to give output based on time used?
I have a basic set up of having a force sensitive resistor being used to power an LED as can be seen below. I am wondering how I can code it so that the LED is lit after a pressure has been applied to the FSR for a specified amount of time. Leading on from that I would like to use an RBG LED and have it so that after specified intervals on continuous pressure the LED changes colour. Any advice would be greatly appreciated.

```
//Constants:
const int ledPin = 3;     //pin 3 has PWM funtion
const int sensorPin = A0; //pin A0 to read analog input

//Variables:
int value; //save analog value

void setup(){

  pinMode(ledPin, OUTPUT);  //Set pin 3 as 'output'
  Serial.begin(9600);       //Begin serial communication

}

void loop(){

  value = analogRead(sensorPin);       //Read and save analog value from potentiometer
  Serial.println(value);               //Print value
  value = map(value, 0, 1023, 0, 255); //Map value 0-1023 to 0-255 (PWM)
  analogWrite(ledPin, value);          //Send PWM value to led
  delay(100);                          //Small delay

}

```

# Answer
You'll need to declare a variable to hold the start time (`millis()`) of when the force has exceeded the threshold.

You'll need to declare a constant to hold the threshold value (with analog data, you likely don't want to have your pressure threshold be "anything greater than 0", because noise and other things like small vibrations will trigger.

Also declare a constant to hold your "hold-off time" in milliseconds.

In your `loop()`, when you have an analog value that exceeds the pressure threshold, store the value of `millis()`. Also in your `loop()`, when the current `millis()` minus the start value is greater than the "hold-off time", activate your LED.

For RGB, same setup, but you can set your color based on **how much** greater the time difference is than the hold-off time.
> 1 votes

---
Tags: arduino-uno, resistor
---


# Question
Title: Attiny85 not able to understand data from 433Mhz using VirtualWire.h
The basic plan is to have a Attiny85 pass information from a 433Mhz RF module to another chip/Arduino via I2C using VirtualWire and Wire libraries. I have been able to make this system work on their own using Arudino Nano's to debug, but the Attiny85 (A85) seems unable to grab the data from the RF 433 Mhz.

So have spent a few days doing some more research, and basically putting each component separate, to make sure what is being sent is correct.

1. 433 Mhz transmitter is working by sending a 9 digit number, using VirtualWire.h.
2. Nano with a 433 Mhz receiver is receiving 9 digit number, VirtualWire.h.
3. Attiny85 is sending either a no data, or the 9 digit number, to another Nano using Wire.h.
4. The Nano is getting only No Data, so the I2C is working between A85 and Nano.

Attiny85, on Pin 1 (pin 6 on chip) is not getting any data from the 433 Mhz, which works on (2). I connect the GND of the 433 RX to the chip.

Here is the **Receiver** code:

```
#include <VirtualWire.h>
#include <Wire.h>
void setup() {
  pinMode(A3, OUTPUT);
  Wire.begin(); // join i2c bus (address optional for master)
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(4000);   // Bits per sec
  vw_set_rx_pin(1);
  vw_rx_start();       // Start the receiver PLL running
}
void loop() {
  uint8_t buf[15];
  uint8_t buflen = 15;
  if (vw_get_message(buf, &buflen)) // Non-blocking
    {
      digitalWrite(A3, LOW);
      Wire.beginTransmission(8); // transmit to device #8
      for (int i = 0; i < buflen; i++) {
        Wire.write(buf[i]);
      }
      Wire.endTransmission();    // stop transmitting
    } else {
      digitalWrite(A3, HIGH);
      Wire.beginTransmission(8); // transmit to device #8
      Wire.write("no DATA");
      Wire.endTransmission();    // stop transmitting
     }
}

```

Here is the **Transmitter** code:

```
#include <VirtualWire.h>
int xPin = A7;
int yPin = A6;
int buttonPin = 2;

int xPosition = 0;
int yPosition = 0;
int buttonState = 0;
const char *controller;
void setup() {
  Serial.begin(9600);
  pinMode(12,OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(yPin, INPUT);
  pinMode(xPin, INPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  vw_set_ptt_inverted(true); //
  vw_set_tx_pin(12);
  vw_setup(4000);// speed of data transfer Kbps
}

void loop(){
   xPosition = analogRead(xPin);
   yPosition = analogRead(yPin);
   buttonState = digitalRead(buttonPin);
if(xPosition > 0 || yPosition > 0) {
  String Data = (xPosition + yPosition);
  controller = Data;
  vw_send((uint8_t *)controller, strlen(controller));
  vw_wait_tx(); // Wait until the whole message is gone

} else {
  digitalWrite(13, 0);
  digitalWrite(4, 1);
  controller = "#s0_0";
  vw_send((uint8_t *)controller, strlen(controller));
  vw_wait_tx(); // Wait until the whole message is gone
}

Serial.println(controller);

}

```

So basically the A85 is not getting past if (vw\_get\_message(buf, &buflen)) { on pin 1. But does when using the Nano on pin D2, from the same transmitter, but not at the same-time of-course.

Am I using the wrong Pin on the A85? Chip pin 5 and 7 are used for the I2C so it only leaves analog pins so not sure they would work either. I also tried 8 Mhz and 1 Mhz when loading the A85.

I have tried different Cores as suggested from Google, different versions of VirtualWire and clocked the Attiny 1Mhz, 8Mhz and 16Mhz. None of have worked.

Not sure what else I am missing?

# Answer
> 2 votes
Have you tried using the Radiohead library? I know you said you tried different versions of Virtual Wire. The RH\_ASK class works on a 328p and a nano for sure and they claim a simple Rx program can run on a ATTiny85. They have documentation under RH\_ASK regarding the changes you need make to the library. Another possible fix is to edit the Virtual Wire library files, they might have variables like "Max\_payload" (Radiohead does) whose size can be decreased. I haven't actually read the Virtual wire library, but I am sure Radiohead should fix your problems.

If this doesn't work, do you have an oscilloscope? Maybe we can try debugging it like that.

Edit: Maybe try commenting out the `vw_set_ptt_inverted` line first. I don't think you are using the DR3100. Might not make a difference because you haven't actually set a pin for ptt. Next thing you can try is just connecting the data pin of the Tx to the Rx. You should be able to check if the module is actually connected to the ATTiny with this.

---
Tags: arduino-nano, rf, attiny85
---


title: Purpose of capacitors in this project

text:
# Question
Title: Purpose of capacitors in this project
I'm currently working on a project where I am making a wheeled robot using the Hack-e-bot library on the arduino. The circuit board which I have planned to put together through soldering will eventually look similar to this:

Here is a schematic:

I understand my circuit quite well but my mentor recommended using a capacitor for this and although I have got it on my schematic, I've never actually worked with capacitors before. Why should they be used in this project?

# Answer
> 3 votes
A capacitor is a device that can store (and release) charge. It is made up of 2 metallic electrodes (or plates) that are separated by a thin dielectric material.

> When you apply a voltage over the two plates, an electric field is created. Positive charge will collect on one plate and negative charge on the other. - build-electronic-circuits.com

In short, a capacitor lets the AC component through and blocks the DC component.

---

Capacitors can be used in the following ways:

# Decoupling Capacitors

**(Also called Bypass capacitors)**

> A decoupling capacitor’s job is to supress high-frequency noise in power supply signals. They take tiny voltage ripples, which could otherwise be harmful to delicate ICs, out of the voltage supply.

Image reference http://www.seattlerobotics.org/encoder/jun97/basics.html

> In a way, decoupling capacitors act as a very small, local power supply for ICs (almost like an uninterupptable power supply is to computers). If the power supply very temporarily drops its voltage (which is actually pretty common, especially when the circuit it’s powering is constantly switching its load requirements), a decoupling capacitor can briefly supply power at the correct voltage. This is why these capacitors are also called bypass caps; they can temporarily act as a power source, bypassing the power supply.
>
> Decoupling capacitors connect between the power source (5V, 3.3V, etc.) and ground. It’s not uncommon to use two or more different-valued, even different types of capacitors to bypass the power supply, because some capacitor values will be better than others at filtering out certain frequencies of noise.
> \- sparkfun.com

# Power Supply Filtering

DC power supplies can be quite noisy on their own. Take the output of a bridge rectifier for example, there is a lot of ripple on the output. Capacitors are a perfect solution for reducing the ripple/noise of power supplies.

Image Reference: http://www.electronics-tutorials.ws/diode/diode\_6.html

> Capacitors are stubborn components, they’ll always try to resist sudden changes in voltage. The filter capacitor will charge up as the rectified voltage increases. When the rectified voltage coming into the cap starts its rapid decline, the capacitor will access its bank of stored energy, and it’ll discharge very slowly, supplying energy to the load. The capacitor shouldn’t fully discharge before the input rectified signal starts to increase again, recharging the cap. This dance plays out many times a second, over-and-over as long as the power supply is in use.

Also see Keelan's answer over at electronics stack exchange.

# Signal Filtering

> You can also combine capacitors and resistors to form filters that target specific frequencies. - build-electronic-circuits.com
>
> They can block out low-frequency or DC signal-components while allowing higher frequencies to pass right through. They’re like a bouncer at a very exclusive club for high frequencies only. - sparkfun.com
>
> For example in an audio system you can target the high frequencies to remove them (e.g. in a sub-woofer). This is called a low-pass filter. - build-electronic-circuits.com

Image Reference: Wikipedia

---

Back to your application.

Motors are notoriously noisy. Your mentor has recommended a capacitor to decouple the noise of the motors and protect the IC from voltage drops/spikes.

Side note: D1 in your schematic is a power indication LED. It needs a current limiting resistor in series with the LED to limit the current and prevent the LED from burning out.

---

Resources:

# Answer
> 1 votes
Based on the schematic shown, the capacitor acts as a decoupling or smoothing capacitor. When the circuit components such as a motor require a sudden source or produce a sudden spike of energy, this would help filter out the noise and balance the power line.

More info regarding decoupling capacitor may be found on wikipedia here.

---
Tags: arduino-uno, capacitors
---


title: Send serial data to local server

text:
# Question
Title: Send serial data to local server
I am new to arduino coding. I am reading data from serial port and storing it in char array. I want to send that data to the local server but it is not getting converted to string

Code :

```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server;
char* ssid = "Office RTPL";
char* password = "********";
char data[64];
char data1[64];
String str;
void setup()

{
  // put your setup code here, to run once:
  WiFi.begin(ssid,password);
  Serial.begin(115200);
  while(WiFi.status()!= WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.print(WiFi.localIP());
  server.on("/",[](){server.send(200,"text/plain","Data Test");});
  server.on("/toggle",serialData);
  server.begin();
}
void loop()
{
  // put your main code here, to run repeatedly:
  server.handleClient();
 ;
}
void serialData()
{
  if(Serial.available() > 0)
      {

        server.send(200,"text/plain","Data");
         for(int n=0; n<64; n++)
         {
           data[n] = (Serial.read());

         }
         String str (data);
         server.send(200,"text/plain",str);

  else
        {
        String no_data = "No Serial Data";
        server.send(200,"text/plain",no_data);
        delay(5000);
        }

}

```

Please help

# Answer
As I mention in my answer about serial communication:

> Before reading, always make sure data is available. For example, this is wrong:
>
> ```
> if (Serial.available ())
>   {
>       char a = Serial.read ();
>       char b = Serial.read ();  // may not be available
>   }
>
> ```
>
> The Serial.available test only ensures you have **one** byte available, however the code tries to read two. It may work, if there are two bytes in the buffer, if not you will get -1 returned which will look like 'ÿ' if printed.

In your code:

> ```
> if(Serial.available() > 0)
>     {
>     server.send(200,"text/plain","Data");
>      for(int n=0; n<64; n++)
>      {
>        data[n] = (Serial.read());
>
> ```

So you know that **one** byte is available, but you are reading 64. No, that won't work.
> 1 votes

---
Tags: serial, esp8266, softwareserial, wireless
---


title: Using a rotary switch

text:
# Question
Title: Using a rotary switch
I don’t have a sketch for this project, just doing some thinking before I pullout the keyboard (this is my phone). I was interested in writing a program that uses a predetermined time limit, for instance having a definition like...

```
#define RUNTIME 30000

```

So the game runs for 30 seconds. By doing this it would be a simple matter of changing the 30000 to 60000 and uploading to the Arduino.

After thinking about that a while, I would prefer to be able to adjust the time using a selector switch.
So my question is.... if I use a 1p4t (on-on-on-on) rotary selector switch, assign each position to a pin and run 5v to the common. Each pin would defined as RUNTIME and a different time limit, 30000, 60000, 90000, 120000, three pins would be LOW and one HIGH depending on position. Then using IF and ELSE statements in the loop setup would I be able to switch the times? I know once the Arduino is powered up the selector switch would need to be at the correct location and if you choose to change the “RUNTIME” a reset would need to be pressed.

Thank you for any assistance or ideas.

# Answer
> 2 votes
If I understand you well, it's very easy.

Assuming the 4 outputs of the switch will be connected to 4 GPIO's you just can check for the state of each GPIO and act on it

```
// Pin numbers where switch 1 to 4 are attached to.
#define PIN_SWITCH_1  8
#define PIN_SWITCH_2  9
#define PIN_SWITCH_3 10
#define PIN_SWITCH_4 11

unsigned long timer_value = 1000; // No switch selected

void setup()
{
     // Set switch pins to input mode.
     pinMode(PIN_SWITCH_1, INPUT);
     pinMode(PIN_SWITCH_2, INPUT);
     pinMode(PIN_SWITCH_3, INPUT);
     pinMode(PIN_SWITCH_4, INPUT);

     // Check switches
     if (digitalRead(PIN_SWITCH_1) == HIGH)
     {
         timer_value = 30000;
     }
     else if (digitalRead(PIN_SWITCH_2) == HIGH)
     {
         timer_value = 60000;
     }
     else if (digitalRead(PIN_SWITCH_3) == HIGH)
     {
         timer_value = 90000;
     }
     else if (digitalRead(PIN_SWITCH_4) == HIGH)
     {
         timer_value = 120000;
     }
     else
     {
         // Keep default value
     }
 }

 void loop()
 {
     // Here you can use timer_value to check for the end of the game.
 }

```

---
Tags: programming
---


title: Power Down Interrupt Arduino

text:
# Question
Title: Power Down Interrupt Arduino
Does anyone know a way to call an interrupt when an Arduino loses power to have it fire a small function real quick?

It'd be a quick EEPROM write of one variable.

I know you can use interrupts on certain pins when they get pulled low, I'm just not sure if it's possible on the power pin.

Or if there would still be enough power in the controller to finish that function.

I have the Node MCU board but it's programmed in Arduino c++.

# Answer
Not directly, no. When an Arduino or ESP8266 has lost power it's lost power. You need external circuitry to keep providing power after the power input has been removed, and alert your target chip that power has gone.

simulate this circuit – Schematic created using CircuitLab

C1 wants to be massive. The ESP8266, because of the WiFi interface in it, consumes a lot of power. Also, writing to EEPROM or Flash (which the ESP8266 has instead of EEPROM) takes extra power.

Ideally, C1 wants to be a small Super-Cap to keep the physical size small. For an ESP8266 you're probably talking thousands of uF.

An alternative is to use the 47L16 (or similar) EERAM chip which is designed to save its internal SRAM contents to internal EEPROM when power is lost using its own dedicated capacitor-based power reservoir.
> 3 votes

---
Tags: c++, nodemcu
---


# Question
Title: How to work with analog readings using RPi and Firmata?
For context: I'm working on a project where I need to use sensors to figure out the current state of the environment. This process is done using an Arduino UNO and a RPi. The easiest way that I found to perform communication between both boards is by uploading Standard Firmata and reading the code from RPi using Serial communication. I'm using pyfirmata to write the code in Python on the RPI side. Also, the Arduino is powered by the RPi using the USB port.

My problem was: The ADC component in the Arduino uses as the analog reference the 5V provided by the USB. When I tested the integration, I was using my laptop. So, the computer was providing 5V to the Arduino. So far so good. When I integrated the Arduino board to the RPi, I got some problems related to the precision of the sensor. I figured out that the RPi was only giving 4.75 V to the Arduino Board. This was messing with my readings since the ADC was using 4.75V while my code had 5V to compute things. After adjusting the code, everything proceeded as planned. Both 4.75 V and 5 V were hardcoded in my code.

So, these are my questions:

* Is there a way to read the Vcc using pyfirmata to figure out the correct voltage without having this hardcoded?
* Is there a way to modify the analog reference to use the INTERNAL reference of 1.1V?

About the analog reference, I found this: https://github.com/firmata/arduino/issues/39 . So, pyfirmata implements send\_sysex method, I just have to execute these steps, but I still don't know how.

# Answer
> 2 votes
It does not appear that Firmata has proceeded with the ability to change the analog reference source. You referenced one of the issues opened for it, but I don't see anywhere where it committed to the current master branch.

There's no way for an Arduino to read a voltage without some reference, and as you are experiencing, the default reference is Vcc. That means everything must be compared to Vcc, and if you compare Vcc to itself, you will always find out that Vcc is equal to Vcc.

The pull request to implement is here, so you could play around with it yourself.

---
Tags: arduino-uno, python, raspberrypi, firmata, analogreference
---


# Question
Title: Switch case does not work after booting system
```
int value1;
int value2;
int runs1 = 0;
int runs2 = 0;

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
int inPin = 6;
int val = 0;
int push_count = 0;
int buttonState = 0;
unsigned long previousMillis = 0;
const long interval = 1800000;
int currentTime;

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

void loop() {

  unsigned long currentMillis = millis();
  currentTime = 30-(currentMillis - previousMillis)/60000;
  if (currentMillis - previousMillis >= interval || previousMillis == 0) {
    previousMillis = currentMillis;

  measure();
  }

  buttons();
}

void measure() {
 value1=300;
 value2=300;

  if (value1 <= 650)
{
   lcd.setCursor(8,0);
   lcd.print("Plant");
   lcd.setCursor(10,1);
   lcd.print("1");
   delay(2000);

}
else
{
  lcd.clear();
  lcd.print("Pump 1 turned ON");
  lcd.setCursor(0,1);
  lcd.print("Water for 40 sec");
  runs1++; // increment the number of times pump 1 has run

}

  if (value2 <= 550)
{
   lcd.setCursor(8,0);
   lcd.print("Plant");
   lcd.setCursor(10,1);
   lcd.print("2");
   delay(2000);
   Serial. print("Pump 2 OK");
}
else
{
  lcd.clear();
  lcd.print("Pump 2 turned ON");
  lcd.setCursor(0,1);
  lcd.print("Water for 40 sec");
  runs2++; // increment the number of times pump 2 has run
  Serial. print("Pump 2");
}
  }

void buttons() {
  val = digitalRead(inPin);

  if (val != buttonState && val == HIGH){
    push_count++;
  }
      else {
      // do nothing
    }

  buttonState = val;
  switch (push_count) {
    case 0:
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Sensor 1 reads");
      lcd.setCursor(0,1);
      lcd.print(value1);
      delay(20);
      Serial. print("Case 0");
      push_count++;
      break;
    case 1:
      Serial. print("Case 1");
      break;
    case 2:
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Sensor 2 reads");
      lcd.setCursor(0,1);
      lcd.print(value2);
      delay(10);
      push_count++;
      break;
    case 3:
      break;
    case 4:
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Pump 1 ran");
      lcd.setCursor(0,1);
      lcd.print(runs1);
      lcd.setCursor(5,1);
      lcd.print(" times");
      delay(10);
      push_count++;
      break;
    case 5:
      break;
    case 6:
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Pump 2 ran");
      lcd.setCursor(0,1);
      lcd.print(runs2);
      lcd.setCursor(5,1);;
      lcd.print(" times");
      delay(10);
      push_count++;
      break;
    case 7:
      break;
    case 8:
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Next cycle in");
      lcd.setCursor(0,1);
      lcd.print(currentTime);
      lcd.setCursor(5,1);
      lcd.print(" Minutes");
      delay(10);
      push_count++;
      break;
    case 9:
      break;
    default:
      push_count=0;
  }
}

```

When I boot the system (standalone atmega328p circuit) the connected LCD either shows

> Plant
>
> 2

originating from

```
   lcd.setCursor(8,0);
   lcd.print("Plant");
   lcd.setCursor(10,1);
   lcd.print("2");
   delay(2000);
   Serial. print("Pump 2 OK");

```

or in my real code (where value1 and value2 are actually measured)

> Pump 2 turned ON
>
> Water for 40 sec

originating from

```
  lcd.clear();
  lcd.print("Pump 2 turned ON");
  lcd.setCursor(0,1);
  lcd.print("Water for 40 sec");
  runs2++; // increment the number of times pump 2 has run
  Serial. print("Pump 2");

```

after I use the button to cycle through all the cases everything works fine. On the next button press I get to case 2 (-\> 3). After a full cycle case 0 (-\> 1) gets displayed correctly.

The above MCVE runs perfectly on my breadboard setup, but not in the real setup.

Here's the schematic of the real setup.

So somewhere in the real setup has to be something that my code does not handle properly. The breadboard setup is minimal, just all GND and VCC connections, a 16 Mhz crystal with 22 pF caps.

# Answer
> 1 votes
```
int buttonState = 0;

```

So buttonState is initially zero (LOW).

```
  val = digitalRead(inPin);

  if (val != buttonState && val == HIGH){
    push_count++;
  }

```

Since you have an external pull-up on inPin it will read HIGH initially. Thus push\_count will be incremented immediately.

```
  switch (push_count) {
    case 0:
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Sensor 1 reads");
      lcd.setCursor(0,1);
      lcd.print(value1);
      delay(20);
      Serial. print("Case 0");
      push_count++;
      break;
    case 1:
      Serial. print("Case 1");
      break;

```

Therefore you execute case 1 initially.

---

Also, I don't see how this works:

```
 value1=300;
 value2=300;

  if (value1 <= 650)
{
   lcd.setCursor(8,0);
   lcd.print("Plant");
   lcd.setCursor(10,1);
   lcd.print("1");immediately
   delay(2000);

}
else
{
  lcd.clear();
  lcd.print("Pump 1 turned ON");
  lcd.setCursor(0,1);
  lcd.print("Water for 40 sec");
  runs1++; // increment the number of times pump 1 has run

}

  if (value2 <= 550)
{
   lcd.setCursor(8,0);
   lcd.print("Plant");
   lcd.setCursor(10,1);
   lcd.print("2");
   delay(2000);
   Serial. print("Pump 2 OK");
}
else
{
  lcd.clear();
  lcd.print("Pump 2 turned ON");
  lcd.setCursor(0,1);
  lcd.print("Water for 40 sec");
  runs2++; // increment the number of times pump 2 has run
  Serial. print("Pump 2");
}

```

Since you are doing both `if` tests it seems likely (indeed certain) that you will display "Plant 1" and then immediately\* overwrite it with "Plant 2" so quickly that you wouldn't notice it.

* apart from the 2-second delay of course. :)

# Answer
> 2 votes
Personally I don't like the way you handle the "state machine", and I'd implement it in what I perceive is a more robust way (I may be wrong, though).

Moreover if you have a button please add a debounce; I usually do this with the Bounce2 library (or alternatives I code which are modified versions of that library). So... Let's change the things in the way I prefer.

```
// Include the library
#include <Bounce2.h>

// declare a bounce object
Bounce buttonDebounce = Bounce();

//in the setup:
pinMode(IN_PIN, INPUT); // or INPUT_PULLUP?
buttonDebounce.attach(IN_PIN);
buttonDebounce.interval(5);

//in the loop:
buttonDebounce.update();

```

Then in the `loop` you can use the `buttonDebounce.rose()` function or `buttonDebounce.fell()` to detect the button presses.

Now, for the state machine. You have four meaningful states (let's call them DISPLAY\_1 to 4). It's better to give them more meaningful names. And let's add an invalid state. I usually prefer to use const bytes to force the size rather than enums or defines, but.. whatever ;)

So outside loop or setup declare the values and the state variable:

```
const byte SM_ErrorState = 0;
const byte SM_Display_1 = 1;
const byte SM_Display_2 = 2;
const byte SM_Display_3 = 3;
const byte SM_Display_4 = 4;
const byte SM_Display_5 = 5;
byte SM_currentState;

```

Now, the function `buttons` can be implemented in the classical way I learned to implement state machines, which is first make a switch case to test whether you have to advance, then advance to the next state if necessary and perform the entry action.

```
void buttons()
{
    buttonDebounce.update();

    nextState = SM_currentState;

    // Check if a new state is requested
    switch (SM_currentState)
    {
    case SM_Display_1:
        if (buttonDebounce.rose())
            nextState = SM_Display_2;
        break;
    case SM_Display_2:
        if (buttonDebounce.rose())
            nextState = SM_Display_3;
        break;
    case SM_Display_3:
        if (buttonDebounce.rose())
            nextState = SM_Display_4;
        break;
    case SM_Display_4:
        if (buttonDebounce.rose())
            nextState = SM_Display_5;
        break;
    case SM_Display_5:
        if (buttonDebounce.rose())
            nextState = SM_Display_1;
        break;
    default:
        nextState = SM_Display_1;
        break;
    }

    // If an advancement is requested, advance and then perform the entry action
    if (nextState != SM_currentState)
    {
        SM_currentState = nextState;
        switch (SM_currentState)
        {
        case SM_Display_1:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Sensor 1 reads");
            lcd.setCursor(0,1);
            lcd.print(value1);
            delay(20);
            Serial. print("Case 0");
            break;
        case SM_Display_2:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Sensor 2 reads");
            lcd.setCursor(0,1);
            lcd.print(value2);
            delay(10);
            break;
        case SM_Display_3:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Pump 1 ran");
            lcd.setCursor(0,1);
            lcd.setCursor(5,1);
            lcd.print(runs1);
            lcd.print(" times");
            delay(10);
            break;
        case SM_Display_4:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Pump 2 ran");
            lcd.setCursor(0,1);
            lcd.print(runs2);
            lcd.setCursor(5,1);;
            lcd.print(" times");
            delay(10);
            break;
        case SM_Display_5:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Next cycle in");
            lcd.setCursor(0,1);
            lcd.print(currentTime);
            lcd.setCursor(5,1);
            lcd.print(" Minutes");
            delay(10);
            break;
        default:
            break;
        }
    }
}

```

Now, the initialization. Remember that I told you to add an error state? This way you can force a state change on initialization by setting the variable to the `SM_ErrorState` value.

Then, the millis management in the loop. I'd avoid the particular case of the variable equal to 0 to trigger an immediate execution, since this will lead to errors later. Then I also prefer to sum the interval, to avoid having a drift. So I changed your way to another one. I also changed some code for better readability (for instance, letting the "timer" reset every minute rather than every 30 minutes, and changing the defines accordingly).

Here is my complete code; I left out the measure function since it does not impact the other code.

Let me know if this solves your problem. Oh, BTW, UNTESTED CODE, so some bugs may appear...

```
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Bounce2.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

int value1; // I think it is better if these
int value2; // two variables are initialized
int runs1 = 0; // Unsure if this is needed
int runs2 = 0; // Unsure if this is needed
int val = 0; // Unsure if this is needed

int inPin = 6;
unsigned long previousMillis = 0;
const unsigned int millisInOneMinute = 60000U;

byte elapsedMinutes;
const byte intervalMinutes = 30;

Bounce buttonDebounce = Bounce();

void setup() {
    Serial.begin(9600);
    lcd.begin();
    pinMode(inPin, INPUT);
    buttonDebounce.attach(inPin);
    buttonDebounce.interval(5);
    previousMillis = millis();
    elapsedMinutes = intervalMinutes; // Force a new measure
}

void loop() {
    if (((unsigned int)(millis() - previousMillis)) >= millisInOneMinute)
    {
        previousMillis += millisInOneMinute; // Avoid drifting
        elapsedMinutes++;
    }

    if (elapsedMinutes >= intervalMinutes)
    {
        elapsedMinutes = 0;
        measure();
    }

    buttons();
}

void measure() {
    // do your stuff
}

void buttons()
{
    buttonDebounce.update();

    nextState = SM_currentState;

    switch (SM_currentState)
    {
    case SM_Display_1:
        if (buttonDebounce.rose())
            nextState = SM_Display_2;
        break;
    case SM_Display_2:
        if (buttonDebounce.rose())
            nextState = SM_Display_3;
        break;
    case SM_Display_3:
        if (buttonDebounce.rose())
            nextState = SM_Display_4;
        break;
    case SM_Display_4:
        if (buttonDebounce.rose())
            nextState = SM_Display_5;
        break;
    case SM_Display_5:
        if (buttonDebounce.rose())
            nextState = SM_Display_1;
        break;
    default:
        nextState = SM_Display_1;
        break;
    }

    if (nextState != SM_currentState)
    {
        SM_currentState = nextState;
        switch (SM_currentState)
        {
        case SM_Display_1:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Sensor 1 reads");
            lcd.setCursor(0,1);
            lcd.print(value1);
            delay(20);
            Serial. print("Case 0");
            break;
        case SM_Display_2:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Sensor 2 reads");
            lcd.setCursor(0,1);
            lcd.print(value2);
            delay(10);
            break;
        case SM_Display_3:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Pump 1 ran");
            lcd.setCursor(0,1);
            lcd.setCursor(5,1);
            lcd.print(runs1);
            lcd.print(" times");
            delay(10);
            break;
        case SM_Display_4:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Pump 2 ran");
            lcd.setCursor(0,1);
            lcd.print(runs2);
            lcd.setCursor(5,1);;
            lcd.print(" times");
            delay(10);
            break;
        case SM_Display_5:
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Next cycle in");
            lcd.setCursor(0,1);
            lcd.print(elapsedMinutes);
            lcd.setCursor(5,1);
            lcd.print(" Minutes");
            delay(10);
            break;
        default:
            break;
        }
    }
}

```

**EDIT**: Generic implementation of a state machine

Ok, here I post my generic scheme for a state machine. Usually I use the "state-based" state machine, which is actions are linked to states; sometimes I also saw "transition-based" state machines, where actions were linked to transitions, but... Ok, I'm not a real expert, so I don't want to write a lot of (wrong) things.

In this kind of machines, each state can have up to three kind of actions and a check:

* actions you perform when you ENTER the state
* actions you perform continuously when you are INSIDE the state
* actions you perform when you EXIT the state
* and of course, you have to CHECK whether you need to make a transition to another state

For instance, when you have in a microwave a state corresponding to the ON state, you have to:

* when you ENTER the state, turn on the heater
* when you are INSIDE the state, update the timer value
* when you are done and you are EXITing the state, turn off the heater
* when during the CHECK you see that the timer has expired or the stop button was pressed, you switch to another state

So there are four kind of actions: ENTER, INSIDE, EXIT and CHECK. For linearity I learned that it is much better to write each of them in a separate switch case. This is my usual implementation scheme:

```
void stateMachine()
{
    byte nextState = currState; // currState of course is defined outside

    switch (currState)
    {
    // Here you have to CHECK, for each state, the conditions
    // needed to switch to another state; if you switch, put
    // the new state in nextState
    }

    if (nextState != currState)
    {
        switch (currState)
        {
        // Perform the EXIT functions for each state
        }

        // Advance to the next state
        currState = nextState;

        switch (currState)
        {
        // Perform the ENTER functions for each state
        }
    }
    else // See note below
    {
        switch (currState)
        {
        // Perform the actions to be performed continuously
        // INSIDE each state
        }
    }
}

```

NOTE: the `else` can be omitted or not. If you leave it, in the cycle that you detect the change you do not perform the INSIDE action; if you omit it, the INSIDE action will be performed. This is useful in different cases.

Now, usually (and yours is one of these cases) you only need the CHECK and ENTER sections (if you look at the code, you will see that only these two sections were implemented). Once in a while you will need also the INSIDE section, and once in your life you will also need the EXIT ;) (at least in my experience)

# Answer
> 1 votes
You haven't ever set `value1` or `value2`, but your if-else statements depend on them.

Before you can test a variable to have a specific value, you must set the variable at some point prior to using it. In your code, `value1` and `value2` are declared global, but never initialized and never set, so they are undefined and could have any value in them at the start.

---
Tags: arduino-uno, atmega328, code-optimization
---


title: Can Arduino control 8 solenoids?

text:
# Question
Title: Can Arduino control 8 solenoids?
I know very little about Arduino and even less about programming one. Before I purchase a board, and learn how to program it, I was wondering if my idea is feasible.

I want to program the Arduino to sequentially open one after another irrigation valve. There would be approximately eight 24 volt solenoid valves. Each one would need to be open for approximately 15 minutes, then open the next valve in sequence and finally close the previous valve. Similar to a multi-zone irrigation controller.

I see that I may need to use a transistor in the power circuit of the solenoid. But it is not clear to me if the Arduino can control eight solenoids and if so, does each solenoid require its own transistor?

# Answer
An Arduino can control (at least) 8 devices. Instead of a transistor, it might be much easier to use an 8 way relay controller, something like this:

8 relay module

Just connect all 8 valves to the relays, you power the relay with a separate source for the valves, and connect the pins to the Arduino.

These ones have opto couplers, which give an extra security between the valves and the Arduino.

8 relay module with opto couplers (note I just put the first entry I found, you might find better/cheaper similar items, e.g. at AliExpress for $4).

As Andre said in a comment below, you can use an Arduino Mega if you need more outputs. Or if you want a challenge you can use use a multiplexer IC like 74HC595 (plenty of examples to be found with Arduino).

For controlling one relay with an Arduino enough examples can be found, for 8 it's similar (just use 8 GPIOs), or a multiplexer IC.
> 10 votes

# Answer
Yes, you will need something to drive 24 volt solenoids, because the Arduino cannot do it alone.

My preferred method would be to use a ULN2803 device, which will allow you to drive all those eight solenoids (assuming they take less than 500mA or current) and has inbuilt protection against the voltage spike when the solenoid switches off.

http://www.ti.com/lit/ds/symlink/uln2803a.pdf

These devices are available on eBay.

The software will be quite simple for this application and should be well within the capabilities of anyone who reads an Arduino tutorial.
> 3 votes

# Answer
There are 2 wires to a solenoid, and 2 ways to operate them:

1- Closing a relay sends 24V out, with return wires going to 0 volts.

2- 24V Always goes out, and a relay can short the return wire to 0 volts.

Either way, test 2 by running the wires to a control board, and manually activating solenoids. When that works, add Arduino relay control as other suggest.

Keeping the switches will help, if you want to operate a solenoid manually OR you suspect you have a broken relay / solenoid.
> 3 votes

# Answer
Most irrigation valves are AC operated, typically using 24VAC at about 250mA (Double that to 500mA for the inrush current). The best way to drive these is via a triac. If you want isolation between your controller and the valve voltage an opto coupler with a triac output is the best way to go. A good choice given the typical irrigation valve is the Vishay VO3023: 5mA LED input current and 1A output current and only about $0.50 per unit. Triacs are pretty tough devices and have no moving parts like relays so they are quite reliable.
> 3 votes

# Answer
An Arduino board is merely a microcontroller with the stuff around it that is necessary to keep it running. By stufff, I mean thinks such as the voltage regulator that provides the power, the oscillator that provides the frequency for the controller, the GPIO pin connectors, and so on.

This is a very simple application and could easily be done by an Arduino. The programming doesn't have to run quickly. You are only doing one thing at a time.

I found an 8-channel relay module that should do what you need. You would need four of them, but they are only about $11 apiece. I have never used this device before, so I don't know how well it works, but the specifications seem right. They can be controlled by almost any computer with output pins that have 5 volts. So you'd need to use an Arduino with 5V output pins.

You will probably need more output pins than a standard Arduino, but that is easy enough to do with the Mega version.
> 2 votes

# Answer
Yes, Arduino can control eight transistors.

Each solenoid will need a transistor.

Ideal would be to use logic level N-channel MOSFETs that the Arduino 0/5V output can drive directly. IRFL540 is mentioned a lot, you can get them at digikey.com. Drive the gate thru a 150 ohm resistor, and have a 10K resistor from the gate to Gnd so the transistor is off while the Arduino is reset (and the IO pins all revert to Inputs).

Depending on the current draw, you may able to use a shift register with Open Drain outputs. TPIC6C595, 100mA. TPIC6B595, 150mA. TPIC6595, and TPIC6A595 are even higher current capable parts.

Add a diode with the same current rating across the solenoid coil, cathode to +24V, so the burst of current generated by the coil when the transistor closes has somewhere to dissipate. (current in a coil wants to keep flowing as the magnetic field in the coil collapses, it can't go thru the turned-off transistor, so it goes thru the coil and dissipates in the coil's wire-resistance).
> 1 votes

# Answer
An alternative method is to use an I2c port expander such as a PCF8574. These are available as break out boards. By selecting a different I2C address on each break out board up to 64 relays can be controlled using opto isolated relay modules. Thus 64 0utputs or inputs with just two Arduino pins.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Change Arduino Uno clock from 16MHz external to 1MHz internal
I've got a project where I need to program an ATmega328P on an Arduino Uno board, then transplant it into a custom PCB - however, this board does not have an oscillator installed, and so I need to run the microcontroller off its internal clock.

My goal here is to be able to code my software with the Arduino IDE, insert a factory-fresh ATmega328P straight from the tube into the socket on the Arduino Uno board, then move the device from the board to the PCB without any changes along the way. What's the best way to go about this?

# Answer
That will not work. To change the clock source, you'd need to change the fuses. I don't know of any way to do this while the chip is inside the UNO.

Secondly, a factory fresh 328P won't work in an UNO board, because it doesn't have the correct fuses, and doesn't have the bootloader programmed.

I'd suggest placing the 328P chips in a breadboard; connect the ISP pin to the UNO, and use the Arduino-as-ISP to change the fuses, and upload your program.

PS why run at 1Mhz. The internal oscillator runs at 8Mhz. By default the divide-by-8 fuse is set, so it runs at 1Mhz out of the factory, but you can unset this fuse.

PPS use this website http://www.engbedded.com/fusecalc/ to generate the right fuse settings for your project.
> 2 votes

# Answer
You can set the fuses to run on the internal oscillator easily enough. You can still run at 8 MHz which the IDE supports (choose Lilypad in the IDE) and then the delays, serial prints, etc. will still work properly.

As for programming a new chip, you can use an Arduino as ISP, an external ISP programmer (available cheaply from eBay), or see my page about uploading hex files which just needs a few hook-up cables, and a $15 SD card adapter like this:

You upload the sketch onto your Uno to make it into a programmer. Then you compile the code for your target chip and get the .hex file that the compiler produces.

Example setup:

The hex uploader sketch also lets you change fuses.

The AVR Fuse Calculator page will help you with getting the correct fuse settings.
> 1 votes

---
Tags: arduino-uno
---


title: function returning String-Array

text:
# Question
Title: function returning String-Array
i'm still new to arduino and also to C++ and have a short question. What i want to do is to write a function (in my case to parse the query-string of an URL) to get the parameter names and values (varying number of parameters).

My function looks like the following:

```
String function readParams()
{
   String params[x]; // x: number of params

   // fill params[0]... params[x] with parameter names

   return params;
}

void loop()
{
   // do some stuff

   String params[x] = readParams();

   for(int i=0; i < x; i++)
   {
      debug(params[i]);
   }
}

```

What is the correct return-type for the readParams() function in this case? And how to access the params in the main (loop) -function?

I hope the code makes it clear what i want to do.

Thanks, Marius

# Answer
Some tips:

1. Don't use `String`.
2. Use `char *` and slice the string in-place.
3. Pass a pointer to an array of pointers and fill that with pointers to the portions of the string you have sliced.
4. Return the number of entries in the array you used.

I do something similar in my CLI library. I use a custom "getWord" function, but similar can be done with `strtok()`.

You can read more about working with C strings here.
> 2 votes

# Answer
I'm inclined to agree with Majenko that you shouldn't use String in the first place, but if you want to, you can pass by reference:

```
const int numParams = 2;

void readParams(String (& params) [numParams])
  {
  params [0] = "foo";
  params [1] = "bar";
  }

void setup()
{
  Serial.begin (115200);
  String params [numParams];
  readParams (params);
  for (int i = 0; i < numParams; i++)
    Serial.println (params [i]);
}

void loop() { }

```

An easier thing is to make the parameters a global variable.
> 2 votes

---
Tags: string, array
---


# Question
Title: Powering 24 volt solenoid valve with Arduino uno
Today I received normally closed solenoid valve which I am going to use in automated pot watering system , I realised the valve takes 24 dc volt as input and Arduino has maximum of 5volt , using some power booster I can convert it to some extent but I think 24 volt is too much .

So how should power 24volt solenoid valve from Arduino uno?

# Answer
Since the solenoid requires higher current than the arduino can provide you can use an alternative power source for the solenoid (maybe a couple of batteries) and switch it with a TIP120 transistor.
> 3 votes

# Answer
You have 2 choices:

1 - Preferably, use a N-channel MOSFET. Best for usage of voltage between 9 and 60, these are great little modules that can control voltage flow.

2 - Use a relay. A little more expensive, but can handle main's voltage.
> 0 votes

# Answer
24V AC or DC? Relay would be good for either.

Low Rds N-channel logic level MOSFET (IRFL540) would be good for sinking DC current.
> -1 votes

---
Tags: arduino-uno
---


# Question
Title: Is there a way to disable modules like ADC without a sleep mode?
I'm working on a binary watch project. I want my circuit to live off of batteries for as long as possible, so I want to decrease the power consumption of my chip.

I'm using a barebones ATmega328P-PU with two 74HC595 shift registers. The ideal situation would be to keep the CPU, clock, flash, and I/O going so my program can continuously count the time on its own, but disable everything else that I'm not using, such as the ADC, BOD, TWI, timer1 and timer2, USART0, etc.

I took a look at the ATmega328P datasheet for the sleep modes, and it seems as though they all disable the CPU/Clock. Is this true? And if so, are there ways to disable the modules without enacting a sleep mode?

# Answer
> 9 votes
Certainly there is.

```
  // disable ADC
  ADCSRA = 0;

```

You can disable lots of internal modules like this:

```
  power_all_disable();  // turn off all modules

```

See my page about power saving.

---

Majenko commented that turning off the ADC, while leaving the processor running was pointless. The real way to save battery power is to sleep, and it is possible to do that and still keep track of the time.

On my page about timers there is code to use a 32.768 kHz clock crystal to sleep and wake every second, which you could then use to alter the display on your watch.

Code from that page:

```
#include <avr/sleep.h>
#include <avr/power.h>

const byte tick = 3;

// interrupt on Timer 2 compare "A" completion - does nothing
EMPTY_INTERRUPT (TIMER2_COMPA_vect);

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

  // clock input to timer 2 from XTAL1/XTAL2
  ASSR = bit (AS2);

  // set up timer 2 to count up to 32 * 1024  (32768)
  TCCR2A = bit (WGM21);                             // CTC
  TCCR2B = bit (CS20) | bit (CS21) | bit (CS22);    // Prescaler of 1024
  OCR2A =  31;              // count to 32 (zero-relative)

  // enable timer interrupts
  TIMSK2 |= bit (OCIE2A);

  // disable ADC
  ADCSRA = 0;

  // turn off everything we can
  power_adc_disable ();
  power_spi_disable();
  power_twi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_usart0_disable();

  // full power-down doesn't respond to Timer 2
  set_sleep_mode (SLEEP_MODE_PWR_SAVE);

  // get ready ...
  sleep_enable();

  }  // end of setup

void loop()
  {

  // turn off brown-out enable in software
  MCUCR = bit (BODS) | bit (BODSE);
  MCUCR = bit (BODS);

  // sleep, finally!
  sleep_cpu ();

  // we awoke! pulse the clock hand
  digitalWrite (tick, ! digitalRead (tick));

  }  // end of loop

```

Whilst asleep, the processor uses very little power. In the example sketch I measured 1.46 µA current consumption, when the output was LOW, if running from 5V power supply, and 1.1 µA if running from 3.3V power supply.

---

Example setup:

I have two decoupling capacitors (the blue ones). A pull-up resistor on Reset. A 32.768 kHz crystal between pins 9 and 10. A 22 pF capacitor between each leg of the crystal and ground.

A current-limiting resistor and a LED. It works, and toggles at 1 Hz. When asleep (LED not on) it draws 1.46 µA as mentioned above.

---
Tags: atmega328
---


# Question
Title: How to speed application up (if possible)
I have an ARD 2560, which I communicate with through a special written Delphi 7 program (USB handling is done in the D-7 program).

I use the command syntax:

```
<REG> <COMMAND) <:> <NUMBER> <CR>

```

where
REG is A - K (the registers in the ARD 2650)
COMMAND can be a 2-chars command, but mostly 1-char commands.

```
EG:  AR:255<cr>  // AR configures DDRA to out- or in-put , depending on the parameter - (here 255 / 0xff) .

AI:0<cr>  Read port A input (actually return content of ARD2560 port A input register)

AO:<number><CR>   Send Number to port A (and return result to D-7 ).

......

```

All those command are valid for Reg A to Reg K.

The response time from transmit (d7) to I ("D/7") get the answer is approx. 1 1/2 second. I have a feeling that my code is a big, big kludge (it actually works), but I would like any advice(s) to to improve code // speeding it up.

If I drop the line:

```
 if (char (pport[0] == '*' ))  // '*' can be 'A' to 'K'

```

The response time increases to appr. 2 seconds.

(sorry that there are no comments!)

Here's the code:

```
#include <Esplora.h>

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

void loop()
{

  String chr;

  if (Serial.available() > 0)
  {
    String pport = Serial.readStringUntil(':');
    {
      String pos = Serial.readStringUntil('\n');

      if (char (pport[0] == 'A' ))        /* A */
      {
        if (pport == "AR")
        {
          DDRA = pos.toInt();
          DOCRLF("//AR+", pos.toInt());
        }
        else
        if (pport == "AI")
        {
          if (DDRA == B00000000)
          {
            Serial.print(PORTA);
            chr = "//AI";
          }
          else
          {
            chr ="//AI-";
          }
          DOCRLF(chr , pos.toInt());
        }
        else
        if (pport == "AO")
        {
          if (DDRA == B11111111)
          {
            PORTA = pos.toInt();
            chr = "//AO+";
          }
          else
          {
            chr = "//AO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "AU")
        {
          Serial.print(PORTA);
          DOCRLF("//AU+", pos.toInt());
        }
        else
        if (pport == "ABW")
        {
          PORTA = pos.toInt();
          DOCRLF("//ABW+", pos.toInt());
        }
        else
        if (pport == "ABR")
        {
          Serial.print(PORTA);
          DOCRLF("//ABR+", pos.toInt());
        }
      }
      else
      if (char (pport[0] == 'B' ))        /* B */
      {
        if (pport == "BR")
        {
          DDRB = pos.toInt();
          DOCRLF("//BR+", pos.toInt());
        }
        else
        if (pport == "BI")
        {
          if (DDRB == B00000000)
          {
            Serial.print(PORTB);
            chr = "//BI+";
          }
          else
          {
            chr = "//BI-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "BO")
        {
          if (DDRB == B11111111)
          {
            PORTB = pos.toInt();
            chr = "//BO+";
          }
          else
          {
            chr = "//BO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "BU")
        {
          Serial.print(PORTB);
          DOCRLF("//BU+", pos.toInt());
        }
        else
        if (pport == "BBW")
        {
          PORTB = pos.toInt();
          DOCRLF("//EBW+", pos.toInt());
        }
        else
        if (pport == "BBR")
        {
          Serial.print(PORTB);
          DOCRLF("//BBR+", pos.toInt());
        }
      }
      else
      if (char (pport[0] == 'C' ))        /* C */
      {
        if (pport == "CR")
        {
          DDRC = pos.toInt();
          DOCRLF("//CR+", pos.toInt());
        }
        else
        if (pport == "CI")
        {
          if (DDRC == B00000000)
          {
            Serial.print(PORTC);
            chr = "//CI+";
          }
          else
          {
            chr = "//CI-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "CO")
        {
          if (DDRC == B11111111)
          {
            PORTC = pos.toInt();
            chr = "//CO+";
          }
          else
          {
            chr = "//CO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "CU")
        {
          Serial.print(PORTC);
          DOCRLF("//CU+", pos.toInt());
        }
        else
        if (pport == "CBW")
        {
          PORTC = pos.toInt();
          DOCRLF("//CBW+", pos.toInt());
        }
        else
        if (pport == "CBR")
        {
          Serial.print(PORTC);
          DOCRLF("//CBR+", pos.toInt());
        }
      }
      else
      if (char (pport[0] == 'D' ))        /* D */
      {
        if (pport == "DR")
        {
          DDRD = pos.toInt();
          DOCRLF("//DR+", pos.toInt());
        }
        else
        if (pport == "DI")
        {
          if (DDRD == B00000000)
          {
            Serial.print(PORTD);
            chr = "//DI+";
          }
          else
          {
            chr = "//DI-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "DO")
        {
          if (DDRD == B11111111)
          {
            PORTD = pos.toInt();
            chr = "//DO+";
          }
          else
          {
            chr = "//DO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "DU")
        {
          Serial.print(PORTD);
          DOCRLF("//DU+", pos.toInt());
        }
        else
        if (pport == "DBW")
        {
          PORTD = pos.toInt();
          DOCRLF("//DBW+", pos.toInt());
        }
        else
        if (pport == "DBR")
        {
          Serial.print(PORTE);
          Serial.println("//DBR+");
        }
      }
      else
      if (char (pport[0] == 'E' ))        /* E */
      {
        if (pport == "ER")
        {
          DDRE = pos.toInt();
          DOCRLF("//ER+", pos.toInt());
        }
        else
        if (pport == "EI")
        {
          if (DDRE == B00000000)
          {
            Serial.print(PORTE);
            chr = "//ER+";
          }
          else
          {
            chr = "//ER-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "EO")
        {
          if (DDRE == B11111111)
          {
            PORTE = pos.toInt();
            chr = "//EO+";
          }
          else
          {
            chr = "//EO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "EU")
        {
          Serial.print(PORTE);
          DOCRLF("//EU+", pos.toInt());
        }
        else
        if (pport == "EBW")
        {
          PORTE = pos.toInt();
          DOCRLF("//EBW+", pos.toInt());
        }
        else
        if (pport == "EBR")
        {
          Serial.print(PORTE);
          DOCRLF("//EBR+", pos.toInt());
        }
      }
      else
      if (char (pport[0] == 'F' ))        /* F */
      {
        if (pport == "FR")
        {
          DDRF = pos.toInt();
          DOCRLF("//FR+", pos.toInt());
        }
        else
        if (pport == "FI")
        {
          if (DDRF == B00000000)
          {
            Serial.print(PORTF);
            chr = "//FI+";
          }
          else
          {
            chr = "//F1-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "FO")
        {
          if (DDRF == B11111111)
          {
            PORTF = pos.toInt();
            chr = "//FO+";
          }
          else
          {
            chr = "//FO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "FU")
        {
          Serial.print(PORTF);
          DOCRLF("//FU+", pos.toInt());
        }
        else
        if (pport == "FBW")
        {
          PORTF = pos.toInt();
          DOCRLF("//FBW+", pos.toInt());
        }
        else
        if (pport == "FBR")
        {
          Serial.print(PORTF);
          DOCRLF("//FBR+", pos.toInt());
        }
      }
      else
      if (char (pport[0] == 'G' ))        /* G */
      {
        if (pport == "GR")
        {
          DDRG = pos.toInt();
          DOCRLF("//GR+", pos.toInt());
        }
        else
        if (pport == "GI")
        {
          if (DDRG == B00000000)
          {
            Serial.print(PORTG);
            chr = "//GI+";
          }
          else
          {
            chr = "//GI-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "GO")
        {
          if (DDRG == B11111111)
          {
            PORTG = pos.toInt();
            chr = "//GO+";
          }
          else
          {
            chr = "//GO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "GU")
        {
          Serial.print(PORTG);
          DOCRLF("//GU+", pos.toInt());
        }
        else
        if (pport == "GBW")
        {
          PORTG = pos.toInt();
          DOCRLF("//GBW+", pos.toInt());
        }
        else
        if (pport == "GBR")
        {
          Serial.print(PORTG);
          DOCRLF("//GBR+", pos.toInt());
        }
      }
      else
      if (char (pport[0] == 'H' ))        /* H */
      {
        if (pport == "HR")
        {
          DDRH = pos.toInt();
          DOCRLF("//HR+", pos.toInt());
        }
        else
        if (pport == "HI")
        {
          if (DDRH == B00000000)
          {
            Serial.print(PORTH);
            chr = "//HI+";
          }
          else
          {
            chr = "//HI-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "HO")
        {
          if (DDRH == B11111111)
          {
            PORTH = pos.toInt();
            chr = "//HO+";
          }
          else
          {
            chr = "//HO-";
          }
          DOCRLF(chr, pos.toInt());
        }
        else
        if (pport == "HU")
        {
          Serial.print(PORTH);
          DOCRLF("//HU+", pos.toInt());
        }
        else
        if (pport == "HBW")
        {
          PORTH = pos.toInt();
          DOCRLF("//HBW+", pos.toInt());
        }
        else
        if (pport == "HBR")
        {
          Serial.print(PORTH);
          DOCRLF("//HBR+", pos.toInt());
        }
      }
      else
      if (pport == "RA")
      {
        int aport = (pos.toInt());

        if (aport > -1 && aport < 16)
        {
          Serial.println (" OK ");
        }
      }
      else
      if (pport == "KO")
      {
        Serial.print("//KO+");
        if (DDRA == B11111111)
        {
           Serial.print("A");
        }
        else
        {
           Serial.print("a");
        }
        if (DDRB == B11111111)
        {
           Serial.print("B");
        }
        else
        {
           Serial.print("b");
        }
        if (DDRC == B11111111)
        {
           Serial.print("C");
        }
        else
        {
           Serial.print("c");
        }
        if (DDRD == B11111111)
        {
           Serial.print("D");
        }
        else
        {
           Serial.print("d");
        }
        if (DDRE == B11111111)
        {
           Serial.print("E");
        }
        else
        {
           Serial.print("e");
        }
        if (DDRF == B11111111)
        {
           Serial.print("F");
        }
        else
        {
           Serial.print("f");
        }
        if (DDRG == B11111111)
        {
           Serial.print("G");
        }
        else
        {
           Serial.print("g");
        }
        if (DDRH == B11111111)
        {
           Serial.print("H");
        }
        else
        {
           Serial.print("h");
        }
        Serial.println();
      }
    }
  }
}

void DOCRLF (String txt, int vval)
{
  Serial.print(txt);
  Serial.println(vval);
}

```

# Answer
This is not really a proper answer to your question. As I mentioned in a comment, I believe your actual problem is the Delphi program not sending the LF character you sketch expects. Instead, I am giving here a coding style suggestion: *do not repeat yourself*.

Whenever you find yourself coding with copy-paste, you should try to simplify the program using arrays and/or loops. Below is a suggested alternative version of your `loop()`, with most of its redundant repetitive repetitions removed:

```
struct port_t {
    volatile uint8_t *ddr;
    volatile uint8_t *port;
};

static const port_t ports[] = {
    { &DDRA, &PORTA },
    { &DDRB, &PORTB },
    { &DDRC, &PORTC },
    { &DDRD, &PORTD },
    { &DDRE, &PORTE },
    { &DDRF, &PORTF },
    { &DDRG, &PORTG },
    { &DDRH, &PORTH },
    { NULL,  NULL   },  // there is no port I
    { &DDRJ, &PORTJ },
    { &DDRK, &PORTK },
    { &DDRL, &PORTL }
};

void loop()
{
    // Read the command line.
    if (Serial.available() == 0) return;
    String pport = Serial.readStringUntil(':');
    String pos = Serial.readStringUntil('\n');

    // The "KO" command reads all ports.
    if (pport == "KO") {
        Serial.print("//KO+");
        for (char port_id = 'A'; port_id <= 'H'; port_id++) {
            if (*ports[port_id - 'A'].ddr == 0xff)
                Serial.print(port_id);
            else
                Serial.print(tolower(port_id));
        }
        Serial.println();
        return;
    }

    // Identify the port to act on.
    char port_id = pport[0];
    if (port_id < 'A' || port_id > 'L' || port_id == 'I') {
        Serial.println(F("Error: unknown port."));
        return;
    }
    port_t port = ports[port_id - 'A'];

    // Perform the requested action.
    String command = pport.substring(1);
    String chr = String("//") + port_id + command;
    if (command == "R") {
        *port.ddr = pos.toInt();
        DOCRLF(chr + "+", pos.toInt());
    } else if (command == "I") {
        if (*port.ddr == 0)
            Serial.print(*port.port);
        else
            chr += "-";
        DOCRLF(chr , pos.toInt());
    } else if (command == "O") {
        if (*port.ddr == 0xff) {
            *port.port = pos.toInt();
            chr += "+";
        } else {
            chr += "-";
        }
        DOCRLF(chr, pos.toInt());
    } else if (command == "U" || command == "BR") {
        Serial.print(*port.port);
        DOCRLF(chr + "+", pos.toInt());
    } else if (command == "BW") {
        *port.port = pos.toInt();
        DOCRLF(chr + "+", pos.toInt());
    }
}

```
> 1 votes

---
Tags: arduino-mega
---


# Question
Title: RTC and SD work separately but not together
I am running a small project. I want to use an Arduino Mega 2560 v3, a PIR sensor, a micro SD card module, an RTC 1307 module, some LEDs, buttons and a buzzer. To enable and disable motion detection and when detection is found the time is saved to the SD card.

I wired everything together, coded and started to test. During tests, Arduino on bootup was restarting over and over. First, I was thinking that the problem is in the breadboard and connection. I checked it a few times and I didn't notice anything wrong. So I checked the code over and over. Still nothing.

So I started to test modules. And I found a problem. When I don't use in the sketch either the RTC or the SD card (physically they are still connected, because I am lazy) everything works fine. Arduino doesn't restart. I didn't use the SD module to write data, instead I used the serial port to show data. Everything works fine: I can see at what time is motion detected and Arduino prints it on the terminal.

In the second scenario, I didn’t use the RTC, only the SD module. This time again everything works fine. On the SD card I could read how many times motion was detected. This is weird because when I mix all together it doesn't work.

Here is my code:

```
// *********************************************
// INCLUDE
// *********************************************
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include "RTClib.h"
// *********************************************
// DEFINE
// *********************************************
#define GREENLED 39
#define BTNON 11
#define REDLED 41
#define BTNOFF 9
#define BUZZ 3
#define PIR_PIN 10
//SD (na mega)
#define SD_CLK_SD 52
#define SD_MI 50
#define SD_MO 51
#define SD_CS 4

//RTC
#define RTC_SDA 20
#define RTC_SCL 21
#define RTC_DS 2

// *********************************************
// VARIABLES
// *********************************************
RTC_DS1307 rtc;
File myFile;
char godz[8];
char data[5];

int btnON;
int btnOFF;
int pirD;
bool stan_alarmu;

void wlAlarmu() {
  digitalWrite(REDLED,LOW);
  digitalWrite(GREENLED, HIGH);
  stan_alarmu=true;
  gettime();
  myFile = SD.open("dane.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("### Wlaczenie alarmu ### ");
    myFile.print(" ");
    myFile.print(godz);
    myFile.print(data);
    myFile.println("");
    myFile.close();
  }
}

void wylAlarmu(){
  digitalWrite(GREENLED, LOW);
  digitalWrite(REDLED,HIGH);
  stan_alarmu=false;
  gettime();
  myFile = SD.open("dane.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("### Wylaczenie alarmu ### ");
    myFile.print(" ");
    myFile.print(godz);
    myFile.print(data);
    myFile.println("");
    myFile.close();
  }
}

void alarm(){
  digitalWrite(GREENLED,LOW);
  digitalWrite(REDLED,HIGH);
  digitalWrite(BUZZ,HIGH);
  delay(500);
  digitalWrite(BUZZ,LOW);

  gettime();
  myFile = SD.open("dane.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("Alarm: ");
    myFile.print(" ");
    myFile.print(godz);
    myFile.print(data);
    myFile.println("");
    myFile.close();
  }
  delay(5000);
  digitalWrite(REDLED,LOW);
  digitalWrite(GREENLED,HIGH);
}

void blad() {
  while(1){
    digitalWrite(REDLED,HIGH);
    delay(500);
    digitalWrite(REDLED,LOW);
    delay(500);
  }
}

void gettime() {
  DateTime now = rtc.now();
  sprintf(godz,"%02d:%02d:%02d ",now.hour(),now.minute(),now.second());
  sprintf(data,"%d.%d",now.day(),now.month());
}

// *********************************************
// SETUP
// *********************************************
void setup() {
  //RTC
  Wire.begin();
  // Shield I2C pins connect to alt I2C bus on Arduino Due
  rtc.begin();
  if (!rtc.isrunning()) {
    blad();
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
  pinMode(BTNON,INPUT);
  pinMode(GREENLED, OUTPUT);
  pinMode(BTNOFF,INPUT);
  pinMode(REDLED, OUTPUT);
  pinMode(PIR_PIN,INPUT);
  pinMode(BUZZ,OUTPUT);

  //test seq
  digitalWrite(GREENLED,HIGH);
  digitalWrite(REDLED,HIGH);
  digitalWrite(BUZZ,HIGH);
  delay(100);
  digitalWrite(BUZZ,LOW);
  digitalWrite(GREENLED,LOW);
  digitalWrite(REDLED,LOW);
  delay(500);
  pinMode(SD_CS, OUTPUT);
  if (!SD.begin(SD_CS)) {
    blad();
  }
  digitalWrite(GREENLED,HIGH);
  delay(1000);
  digitalWrite(GREENLED,LOW);
  gettime();
  Serial.begin(9600);

  myFile = SD.open("dane.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("####START SYSTEMU: ");
    myFile.print(godz);
    myFile.print(data);
    myFile.print(" ####");
    myFile.println("");
    myFile.close();
  }
  wylAlarmu();
}

void loop() {
  btnON = digitalRead(BTNON);
  btnOFF = digitalRead(BTNOFF);
  pirD = digitalRead(PIR_PIN);

  if(btnON == HIGH) {
    wlAlarmu();
    delay(2000);
  }
  if(btnOFF == HIGH) {
    wylAlarmu();
    delay(2000);
  }

  if(pirD==HIGH && stan_alarmu==true) {
    alarm();
  }
  delay(1000);
}

```

# Answer
A common issue when using strings (character vectors) is that the vector size is not updated when the format is update. Check the size required for this data. Does it fit for the sprintf() statements?

```
char godz[8];
char data[5];

void gettime()
{
  DateTime now = rtc.now();
  sprintf(godz,"%02d:%02d:%02d ",now.hour(),now.minute(),now.second());
  sprintf(data,"%d.%d",now.day(),now.month());
}

```

What is the worst case size required?

Cheers!
> 1 votes

# Answer
I ran into the same problem lately. I have a work-around but don't have a clear explanation of this problem. As you initialize the different modules in your `setup()`, make sure to perform the SD card initialization first, then followed by the RTC's. Doing this completely sorted me out. However, I am yet to explain these results.

Though it is late, just in case anyone else runs into the same problem.
> 1 votes

# Answer
You should start to debug your code stepwise. I.e. insert debug output commands (print via serial) at some crucial points to find the block of code which resets your device. Then narrow it down, until you know the very command which breaks your setup.

Maybe, there will be more than one point in your software, which is responsible for the failure. Nonetheless you will be wiser after that.

Then you will probably have to dive into the guts of the libraries.

If you have identified some command or procedure call responsible for the reboot, it may be still a hardware issue. Writing SD-cards consumes considerable amount of power. If you supply your device solely via USB, I recommend buying an additional PSU and see, if the behaviour changes.

The next thing is to check the reset-signal on all of your shields and daughter-boards for unwanted connections like solder-bridges or single wire threads snipped of elswhere. Another funny thing are stacking connectors not matching the mainboard and shorting something on it.
> 0 votes

# Answer
Are you using breakout boards as pictured in your links? Or Arduino shields?

Many Uno shields are almost, but not quite, compatible with Mega boards. It is possible there there is one or more pins that are not compatible between them.

If you're using breakout boards, double check all of the connections to the Mega. Could something be dragging down your power supply? Or actually grounding the reset pin? It would probably be one of the programmable I/O pins since the failure only depended on whether you used the SD library and seems not affected by the mere presence of the board.
> 0 votes

# Answer
When using Catalex Micro SD Card module, there is a problem with the MISO output. It is not disabled on the SPI bus because of a hardware failure. To correct the problem pin 13 on the IC must be liftet from ground connection and put together with pin 8, that have the CS signal. Now the Card Works fine with other SPI modules. Take care when soldering - it is very small pins. Best regards OZ7LM Leif
> 0 votes

# Answer
It is too late to answer but I had the same issue and spent a week to solve it. This will not be the exact solution. It worked and I think this is the easiest way to solve it.

First let me tell you my components:

* WeMos D1 R2 (ESP8266)
* MicroSD Card Adapter
* DS3231 RTC (I tried with DS1302 but it did not work).

How I solved is, on setup part, first I initialized the RTC DS3231 then I set the built in Arduino clock to DS3231 RTC values. After that I initialized SD card. In this case you are not able to get RTC data in loop but you have it in built in Arduino clock and SD card works. If your Arduino lose electricity, then it will get the RTC data in setup again.

This solution solves it in someway.

Also there is no tutorial for how to connect these cards to WeMos D1 R2 so I want to share my connections.

```
SD Card    WeMos D1 R2
-------    -----------
SC      -> D14/SDA/D5
SCK     -> D13/SCK
MOSI    -> D11/MOSI
MISO    -> D12/MISO
VCC     -> 5V
GND     -> GND

RTC DS3231   WeMos
----------   -----
SCL        -> SCL/D15
SDA        -> SDA/D14
VCC        -> 3.3V
GND        -> GND

```

Also my code:

```
#include <Wire.h>
#include "RTClib.h"
#include <SD.h> //Load SD library
#include <SPI.h>
#include <time.h>
#include <TimeLib.h>
File file;
int chipSelect = 5;
RTC_DS3231 rtc;
bool not1024prev;
unsigned long timepast;
unsigned long timecurr;
int cnt = 0;
int rpm;

char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

void setup()
{

#ifndef ESP8266
    while (!Serial)
        ; // for Leonardo/Micro/Zero
#endif

    Serial.begin(9600);

    delay(3000); // wait for console opening

    if (!rtc.begin()) {
        Serial.println("Couldn't find RTC");
        while (1)
            ;
    }

    if (rtc.lostPower()) {
        Serial.println("RTC lost power, lets set the time!");
        // following line sets the RTC to the date & time this sketch was compiled
        //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        // This line sets the RTC with an explicit date & time, for example to set
        // January 21, 2014 at 3am you would call:
        //rtc.adjust(DateTime(2018, 3, 11, 16, 29, 30));
    }
    DateTime now = rtc.now();
    setTime(now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());

    if (!SD.begin(chipSelect)) { // Initialize SD card
        Serial.println("Could not initialize SD card."); // if return value is false, something went wrong.
    }
}

void loop()
{
    String curtime = String(year()) + "." + String(month()) + "." + String(day()) + "-" + String(hour()) + ":" + String(minute()) + ":" + String(second());

    Serial.println(curtime);
}

```
> 0 votes

---
Tags: arduino-mega, sd-card, rtc
---


# Question
Title: Is it possible to disable functions/methods?
I recently started using the TimeAction library (which allows for proto-threading) and I noticed it has a really useful function for enabling/disabling threads. I want to use the same idea but apply it to a general function, though I haven't been able to find a possible solution to doing such a task on the internet. Here is a potential way for how I would like to implement it:

```
#include <TimedAction.h>

boolean disableCheck = false;
boolean checking = false;
boolean state = false;
const int motionPin = 5;
void checkMotion();
void motion();
void DisableCheckMotion();

TimedAction checkable = TimedAction(6000, DisableCheckMotion);

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

void loop() {
  checkMotion(); //this will be the function I wish to enable and disable

  if(checking == true)
  {
    motion();
  }
  if(disableCheck == true)
  {
    checkable.check();
  }

}
void checkMotion()
{
   checking = true;
}
void motion()
{
   if(digitalRead(motionPin) == HIGH)
{
   Serial.println("motion");
   checking = false;
   checkable.check();
}
}
void DisableCheckMotion()
{
  state ? state = true : state = false;
  if(state == false)
{
  checkMotion.disable(); //this is where I would like to disable the function
  disableCheck = true;
}

  if(state == true)
{
  checkMotion.enable(); //this is where I would like to enable the function
  disableCheck = false;
}
}

```

The purpose of this task is to output one value for whenever a PIR scanner (set at pin 5) picks up motion. Without any form of delaying it will flood the output with values (which is undesirable). A thread is used to offer this delay, I cannot put the code for checking for motion within the thread as I could risk the chance of a reading being missed.

The ideal setup would be for the Arduino board to receive the input and then delay the input from being received again for a period of time while not delaying the entire program. What would be the best way to implement this?

# Answer
If you don't want a function to run you can just return at the start of that function:

```
void myFunction() {
    if (!myFunctionShouldRun) return;
    ... rest of function ...
}

```

If `myFunctionShouldRun` is false the `if` will be true (due to the `!`) and the function will return. If it's `true` the rest of the function will execute.
> 1 votes

---
Tags: arduino-uno, time
---


title: Genuino UNO 5V pin is reading 0.3V

text:
# Question
Title: Genuino UNO 5V pin is reading 0.3V
So I was trying to set up the LCD screen that came with my Genuino starter kit when I noticed that the board screen did not power on at all, unlike a few days ago when it worked.

In order to verify that the UNO was delivering power I simply connected an LED in series with a 220Ω resistor, between the 5V and ground pins. The LED did not power on.

I then, with the UNO still connected over USB, measured the voltage between across the resistor and LED and found it to be around 0.2-0.3V. Going further, reading the voltage between the 5V and ground solder connections on the back of the board and the reading is about the same.

I can power the LED from a digital pin that I set to HIGH, the issue seems to just be with the 5V pin.

Is there anything simple that I am missing (I hope there is) or is there likely a problem with my board? If there is a problem, could I use a digital pin to power a larger circuit such as that with an LCD or would the current supplied be too low?

# Answer
There are a couple more places you can sample the 5V signal, see the photo here:

On the right, on the ICSP header, the pin marked VCC is also connected to the 5V signal. Try testing that.

(The other one is pin 2 of the ICSP interface for the USB chip, but the one on the right should be adequate for testing).

I don't know why you are mucking around with LEDs and resistors, just put your meter between Gnd and 5V.

I find sometimes that the hookup cable has failed, try testing that (or try with a different cable).
> 0 votes

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


title: Logic level converter 12v to 5v

text:
# Question
Title: Logic level converter 12v to 5v
What is the cheapest and best method to convert 12v(14)\<-\>5V(3.3)? Need to connect Arduino to a car.

I need logical shifter not buck converter to connect Arduino to car 12v circuit. I would like to control electrical equipment of car by Arduino. For example, I want to connect input pin to heater, when heater is on from 12v circuit I get HIGH 12v signal which processes by Arduino, but like everyone knows, Arduino can handle only 5/3.3V. Then Arduino going to change state of equipment by connecting optocoupler/relay/transistor to button(of elect. equip.) and will act like physical press. P.P.S I know that more clever to hack and control by CAN bus. But not all eq. are connected to CAN bus and it\`s a little bit risky but I'm working on it as well. I'm looking for best low cost solution. I have found it on ebay . Will it work like I want? Offer DIY solutions as well.

# Answer
Ok, so... I can see your question is a bit obscure, so I'll try to cover a generic approach.

1. **Power** If you need to power the arduino, you can get a cheap car USB adapter. If you want a "solderable" solution, I'd avoid linear regulators (such as a 7805)and go with a cheap switching module. For low power applications I usually buy some modules called mini360 (for instance here is a link from aliexpress) which are cheap and ok for even some hundreds of milliamps. You FIRST turn the potentiometer to set the output voltage (checking with a multimeter) and THEN connect the arduino to it.
2. **Get status** If you need to get the status of something (e.g. whether the lamp is on or off) you have to analyse the circuit. If you have to detect if either 12V or GND are applied, you can solve the problem with a voltage divider. But if the lamp is always connected to 12V and then the GND side is he controlled one then you will always force a (small) current inside it. If this is the case, maybe an optocoupler is the best solution. If the signal is a PWM maybe you need some filtering, if it is a digital wire maybe it is already at the correct voltage, .... You have to figure out what is the best solution for you
3. **Set status** If you need to control something (e.g. turn on a light) your best bet is to use a 5V relay. There are plenty of them, even modules with the transistor and diode necessary to control them with an arduino.

Here are some ideas and rough schematics for the three points

simulate this circuit – Schematic created using CircuitLab

Just one **very big** WARNING: you have to carefully double check that the modification does not blow something up (for instance, you can make a short circuit if the body computer tryes to force a wire to 12V and you close the relay to ground). So... Be very careful, since what you do can break a lot of things, and if you are very lucky the bill can be *only* some couple of thousand dollars (I'll let you figure out what happens if you are not lucky enough)
> 3 votes

# Answer
Use LM7805 linear voltage regulator to regulate to 5 v , it's all about 2-4$, you need LM chip and 2 capacitors, that's all :) and if you need 3.3 just search for linear voltage regulator
> 1 votes

# Answer
Your safest option is to use an opto-isolator. Connect the LED side in parallel with the load with a suitable resistor, then the transistor side becomes, effectively, a button connected to the Arduino.

As far as the car is concerned you have just connected an LED. As far as the Arduino is concerned you have a button connecting to ground.

It provides complete isolation of the car's electrics from your Arduino.
> 1 votes

# Answer
This might be what you need — a multi-channel level shifter with input and output voltage ranging from 3.3V to 18V: https://www.ezsbc.com/index.php/featured-products-list-home-page/ls2.html#.WqmSZ2aZNGU

It's no bi-directional: you'll need a couple of boards if you want inputs and outputs from an Arduino to 12V.
> 1 votes

# Answer
What are you trying to achieve?

It's simply unclear if you want to run the Arduino on 12v of the car battery. Or if you want to control the car-windows by hooking into them? Or if you want to read out your car using the arduino.

I'll go with the later since otherwise the question would be stated a little different.

Also, you're looking for something good/cheap. You don't tell what type of car you want to connect to.

But I think this might help you out: https://www.sparkfun.com/products/13262

25€ isn't that pricey, compared to the car you're fiddling with... So you should go with a little quality (also, you don't need them in batch?).

While a bit subjective, sparkfun could be considered a better vendor than most e-bay suppliers. Both in documentation and support. And in this case, their price isn't that bad. (I'm not affiliated with sparkfun, I actually never bought stuff of them, since e-bay works well for me. There may be hundreds of other good/better suppliers, but this one popped up first on google)

Also, "hacking" your car can have serious safety risks.
> -1 votes

---
Tags: arduino-mega
---


# Question
Title: Esp8266 and HttpClient not working properly
I am working on a project to send data to an API. Here is my code

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

#include <ESP8266HTTPClient.h>

#define USE_SERIAL Serial

ESP8266WiFiMulti WiFiMulti;

const char* key="***********";

void setup() {

    USE_SERIAL.begin(115200);
    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

    WiFi.mode(WIFI_STA);
    WiFiMulti.addAP("******", "*********");

}
String data=" ";
void loop() {
    data+="{";
    data+="\"";
    data+="light";
    data+="\"";
    data+=":";
    data+=830;
    data+=",";
    data+="\"";
    data+="temperature";
    data+="\"";
    data+=":";
    data+=23;
    data+=",";
    data+="\"";
    data+="humidity";
    data+="\"";
    data+=":";
    data+=202;
    data+="} ";

    // wait for WiFi connection
    if((WiFiMulti.run() == WL_CONNECTED)) {

        HTTPClient http;

        USE_SERIAL.print("[HTTP] begin...\n");
        // configure traged server and url
        http.begin("https://us-central1-sensorapp-d2a64.cloudfunctions.net/getData",key);      //Specify request destination
        http.addHeader("Content-Type", "application/json");  //Specify content-type header
        int httpCode = http.POST(data);   //Send the request
        String payload = http.getString();                  //Get the response payload
        USE_SERIAL.println(httpCode);   //Print HTTP return code
        USE_SERIAL.println(payload);    //Print request response payload

        USE_SERIAL.print("[HTTP] GET...\n");
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == HTTP_CODE_OK) {
                //   String payload = http.getString();
                USE_SERIAL.println(payload);
            }
        } else {
            USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        http.end();
    }

    delay(30000);
}

```

After one successful request, it gives `error 400 (Bad Request)` until I reset the nodemcu. But then again it sends the data once successfully and continues with `400 (Bad Request)`.

Why are all the following requests bad? Is there something I haven't done?

# Answer
You declare and initialize `data` as a `String` in the global space. Then, in loop, you use a bunch of concatenations to build your request string.

You never clear the contents of `data`, but back at the top of `loop()` on the next round, you concatenate all the string data again, which duplicates it.

Side note, the `String` type is terrible for low-memory devices, and especially bad when you use a lot of concatenations. Because of the way the `String` type works internally, when you concatenate strings, you end up leaving "holes" in the RAM that aren't likely to be able to be re-used.

Even if you do fix the code by clearing `data` after you submit your HTTP request, your program will still run out of RAM pretty quickly.

Better would be to build the constant parts of the string as constant globals and just concatenate the variable parts when needed and clear it after use.

Best would be to stop using `String` and use instead a `char data[DATA_SIZE]` type of string buffer and use the standard C string utilities like `strncpy()`, `strnlen()`, `strncat()`, etc.
> 3 votes

---
Tags: arduino-uno, esp8266, nodemcu, http
---


# Question
Title: How to measure the supply voltage of Arduino without using an analog pin
I'm using Arduino Nano to measure temperature with a 10 kohm thermistor and a voltage divider. My problem is I'm getting only 4.2V on the 5V pin. The power is supplied via a USB cable from a desktop PC.

I measured the output voltage of a USB port on the PC and it was around 4.5V. It doesn't look normal. So I suspect the power supply unit of the PC is not strong enough.

But it still makes sense to measure the voltage at the 5V pin since there is no guarantee it's exactly 5V. Its error will affect the calculated resistance of the thermistor. So I got it by connecting the pin directly to the A1 pin.

On the other hand, it seems to me Arduino internally and digitally knows the value of the supply voltage. So it would be faster and easier to get it rather than using the A1 pin. But I don't know how to do it.

After searching on the Internet, I could find only these things which didn't help me much.

I also considered using an external power supply, say 9V to the VIN pin but I don't feel like doing that much.

How can I measure the supply voltage of Arduino without using an analog pin?

# Answer
> 6 votes
Yes, you can do it.

You can measure the voltage of the internal (approximately) 1.1V reference voltage using the ADC and use the results of that to calculate what the reference voltage you used (VCC) must have been to get the results you did.

This is a function I commonly use:

```
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}

```

Depending on how close to 1.1V your internal reference voltage is, you may need to adjust the value `1125300L` in the code above. Measure the actual VCC voltage and adjust that value until it results in the same voltage being returned (multiplied by 1000 since that function returns millivolts).

However, as Edgar Bonet mentions, you don't need to care about the supply voltage in your situation, since your thermistor readings are just a ratio that input voltage, whatever it is. Change the input voltage and you will get the same results, since the ADC returns a value between 0 and Vcc in 1024 steps. With different supply voltages you still get 1024 steps.

# Answer
> 0 votes
The Nano has an ATMega328P MCU, which has an internal 1.1V reference voltage.

You use `analogReference()` to change the reference voltage that analogRead() compares the analog inputs against.

You will need to use a voltage divider to ensure that your maximum possible supplied voltage ends up being no higher than the 1.1V reference.

You'll still need to use an analogInput pin.

---
Tags: arduino-nano, analogread, voltage-level, temperature-sensor
---


# Question
Title: "Bad request" error (HTTP) while posting to PHP server using Arduino and ESP8266
I'm doing an IoT project where the temperature and humidity values from a DHT11 sensor is sent to a PHP server using HTTP post. When I run the Arduino, the Serial Monitor says "Bad request". The sensor values are not appearing on the webpage. Please, help me figure out the problem. I am using an Arduino Uno with and an ESP-01.

```
// Code to use SoftwareSerial
//The final sketch
#include "SoftwareSerial.h"
#include <dht.h>

#define dht_dpin 8

String data;
String ssid = "TRAK family";

String password = "rukman12345";

SoftwareSerial espSerial(6, 7); // RX, TX

dht DHT;

float t;
float h;

String server = "svce-ece-b.000webhostapp.com";

String uri = "esp.php";

boolean DEBUG = true;

void showResponse(int waitTime)
{
    long t = millis();
    char c;
    while (t + waitTime > millis()) {
        if (espSerial.available()) {
            c = espSerial.read();
            if (DEBUG)
                Serial.print(c);
        }
    }
}

void setup()
{
    DEBUG = true;

    Serial.begin(115200);
    delay(500);

    espSerial.begin(115200);

    espSerial.println("AT+RST");
    showResponse(1000);

    // espSerial.println("CIOBAUD=9600");
    // showResponse(1000);

    espSerial.println("AT+CWMODE=1");
    showResponse(1000);

    espSerial.println("AT+CWJAP=\"" + ssid + "\",\"" + password + "\"");
    showResponse(5000);

    if (DEBUG)
        Serial.println("Setup completed");
}

void httppost()
{
    espSerial.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");

    if (espSerial.find("OK")) {
        Serial.println("TCP connection ready");
    }
    delay(1000);

    String postRequest =
        "POST " + uri + " HTTP/1.0\r\n" +
        "Host: " + server + "\r\n" +
        "Accept: *" + "/" + "*\r\n" +
        "Content-Length: " + data.length() + "\r\n" +
        "Content-Type: application/x-www-form-urlencoded\r\n" +
        "\r\n" + data;

    String sendCmd = "AT+CIPSEND=";
    espSerial.print(sendCmd);
    espSerial.println(postRequest.length());

    delay(500);

    if (espSerial.find(">")) {
        Serial.println("Sending..");
        espSerial.print(postRequest);

        if (espSerial.find("SEND OK")) {
            Serial.println("Packet sent");
            while (espSerial.available()) {
                String tmpResp = espSerial.readString();
                Serial.println(tmpResp);
            }

            // close the connection
            espSerial.println("AT+CIPCLOSE");
        }
    }
}

void loop()
{
    // Read sensor values
    DHT.read11(dht_dpin);
    float t = DHT.temperature;
    float h = DHT.humidity;
    if (isnan(t) || isnan(h)) {
        if (DEBUG)
            Serial.println("Failed to read from DHT");
    }
    else {
        if (DEBUG)
            Serial.println("Temp=" + String(t) + " *C");
        if (DEBUG)
            Serial.println("Humidity=" + String(h) + " %");

        data = "temperature=" + String(t) + "&humidity=" + String(h);

        httppost();
    }

    delay(1000);
}

```

This is my PHP code:

```
<?php
    global $Temp;
    global $Humidity;
    if(isset($_POST['temperature'])){
        $Temp=$_POST["temperature"];
    }
    if(isset($_POST['humidity'])){
        $Humidity=$_POST["humidity"];
    }

    $Write="<p>Temperature : " .$Temp . " Celcius </p>" . "<p>Humidity : " .       $Humidity . " % </p>";
    file_put_contents('sensor.html',$Write);
?>

```

# Answer
> 1 votes
The URI path in the HTTP request must start with a `/`.

It should be:

```
String uri = "/esp.php";

```

---
Tags: arduino-uno, programming, esp8266, http
---