# Question
Title: Arduino as ISP - program is being uploaded on Arduino, not breadboard
I am following this tutorial, and have wired Arduino using this diagram:

This is what it looks like:

These options are selected in Arduino IDE:

This is the program I'm uploading:

```
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(9, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(9, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

```

When I upload it, it's uploaded on the Atmega on arduino board, not the one on breadboard. Both chips are ATMEGA328P.

I also tried to put 10μF capacitor between GND and RESET pins of the arduino board, which led to following errors:

```
Sketch uses 936 bytes (3%) of program storage space. Maximum is 30720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:w:C:\Users\Jakub\AppData\Local\Temp\arduino_build_319338/BlinkTestAtmega.ino.hex:i

avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM4
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x12
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xe0
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xe0

avrdude done.  Thank you.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

```

Note that I have a homemade ATTINY programmer shield for this arduino board and it works without problems.

# Answer
> 2 votes
Use the "Upload using programmer" in Sketch menu to upload a sketch over ISP

warning, it deletes the bootloader

---
Tags: atmega328, arduinoisp
---


# Question
Title: Shield SIM808 EVB V3.2 charge a Lithium battery?
hello friends do you know if, can this shield (SIM808 EVB V3.2) charge a lithium battery directly or i need additional hardware?, I know that module has conection for battery but it can charge it?

# Answer
The module does not include a charging circuit for Lithium-ion cells.

---

**EDIT**

According to the SIM808 Hardware Design document, Page 28, the SIM808 module **does** integrate Lithium-ion cell charging.

It states that the battery should have it's own overcharge, over discharge, over current protection, and reverse-polarity protection.
> 1 votes

---
Tags: shields, gsm, gps
---


# Question
Title: HC-SR04 Echo Pin Fails To Go Low After Trigger Pulse
I have implemented an HC-SR04 distance sensor using an Arduino. After power up, the sensor operates well when objects are within range of the sensor. However, if the distance to be measured exceeds the maximum (about 15 feet) distance, the sensor times out (which is what I expect). However, after a time-out and with the distance between the object and the sensor in range, the Echo pin fails to be set low after a trigger pulse is generated. The only way to fix this condition is to power down the sensor and power it back up again. (I have verified the state of the Echo pin by using an oscilloscope.)

# Answer
After many hours of research, I discovered that the problem is related to the fact that there is (apparently) a well-known bug in the HC-SR04 which is a Chinese clone of a Devantech SRF04. I replaced the HC-SR04 with an SRF04 and the problem was solved. Now, the ECHO pin always goes low after a trigger and after a time-out (i.e. the object is beyond the maximum measurement distance).
> 1 votes

---
Tags: hc-sr04
---


# Question
Title: Arduino Nano 3.0 CH340G clone cannot upload sketch from Arduino IDE
I connected my brand new Arduino Nano 3.0 clone with CH340G and installed the drivers. It detects in Device Manager as USB-SERIAL CH340 (COM6). Under the Tools menu, i selected the correct board, the processor set to ATmega328P and the COM port. I couldn't upload my sketch so i tried uploading an example Blink sketch from Arduino IDE. The uploading is stuck. I keep waiting and nothing happens. I have read somewhere else that i should enable verbose output for compilation and upload, which i did and here is the output for trying to upload the basic Blink sketch.

```
Arduino: 1.8.9 (Windows 7), Board: "Arduino Nano, ATmega328P"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\admin\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\admin\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\admin\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328 -vid-pid=1A86_7523 -ide-version=10809 -build-path C:\Users\admin\AppData\Local\Temp\arduino_build_747566 -warnings=none -build-cache C:\Users\admin\AppData\Local\Temp\arduino_cache_890158 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avr-gcc-5.4.0-atmel3.6.1-arduino2.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avrdude.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.avrdude-6.3.0-arduino14.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.arduinoOTA.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -prefs=runtime.tools.arduinoOTA-1.2.1.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -verbose C:\Program Files (x86)\Arduino\examples\01.Basics\Blink\Blink.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\admin\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\admin\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\admin\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328 -vid-pid=1A86_7523 -ide-version=10809 -build-path C:\Users\admin\AppData\Local\Temp\arduino_build_747566 -warnings=none -build-cache C:\Users\admin\AppData\Local\Temp\arduino_cache_890158 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avr-gcc-5.4.0-atmel3.6.1-arduino2.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avrdude.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.avrdude-6.3.0-arduino14.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.arduinoOTA.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -prefs=runtime.tools.arduinoOTA-1.2.1.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -verbose C:\Program Files (x86)\Arduino\examples\01.Basics\Blink\Blink.ino
Using board 'nano' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Detecting libraries used...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp" -o nul
Generating function prototypes...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp" -o "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\preproc\\ctags_target_for_gcc_minus_e.cpp"
"C:\\Program Files (x86)\\Arduino\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\preproc\\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp" -o "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp.o"
Compiling libraries...
Compiling core...
Using precompiled core: C:\Users\admin\AppData\Local\Temp\arduino_cache_890158\core\core_arduino_avr_nano_cpu_atmega328_0c812875ac70eb4a9b385d8fb077f54c.a
Linking everything together...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp.o" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/..\\arduino_cache_890158\\core\\core_arduino_avr_nano_cpu_atmega328_0c812875ac70eb4a9b385d8fb077f54c.a" "-LC:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566" -lm
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.eep"
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-objcopy" -O ihex -R .eeprom "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.hex"
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-size" -A "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf"
Sketch uses 930 bytes (3%) of program storage space. Maximum is 30720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/bin/avrdude -CC:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -carduino -PCOM6 -b115200 -D -Uflash:w:C:\Users\admin\AppData\Local\Temp\arduino_build_747566/Blink.ino.hex:i
An error occurred while uploading the sketch

avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf"

         Using Port                    : COM6
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xd8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xd8

avrdude done.  Thank you.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

```

# Answer
You normally just have to press 'reset' on the board button 1 sec before clicking 'Upload'.

I had to do this with cheap Nano clone.
> 1 votes

---
Tags: arduino-nano, sketch, ide
---


# Question
Title: PWM Control, How to stop LED from Flickering?
What is required is controlling the brightness of an LED using both Buttons and a Potentiometer, Button A: Increase

Button B: Decrease /Dim

Potentiometer: Increase and Decrease,

This however must happen on 1 single circuit and must display the results on an LCD.

If I do this separately, meaning buttons without potentiometer and visa versa, I win, the moment I combine the two. I get flickering when working the buttons, due to the potentiometer.

Alternative Research:https://www.instructables.com/id/Smooth-Potentiometer-Input/

Code Below

```
#include <LiquidCrystal.h>
#include <Wire.h>
// ------------------------------------------------------------

int LED1          = 9;
int ButtonLeft    = 8;
int ButtonRight   = 7;
int brightness    = 0;

// ------------------------------------------------------------
byte buttonState1     = 0;
byte lastButtonState1 = 0;

byte buttonState2     = 0;
byte lastButtonState2 = 0;

unsigned long switchMillis;

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

int potValue1 = 0;
int potValue2 = 0;
int potPin= A0;
int readValue;
int writeValue;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// ------------------------------------------------------------
void setup() {

  lcd.begin(16, 2);
  pinMode (potPin, INPUT);
  pinMode(LED1,OUTPUT);
  pinMode(ButtonLeft,INPUT);
  pinMode(ButtonRight,  INPUT);
  lcd.clear ();
}

// ------------------------------------------------------------
void loop(){

    if (millis() - switchMillis >= 5)
  {
    switchMillis = millis();
    checkSwitches();
  }

   readValue = analogRead(potPin);
   writeValue = (255./1023.) * readValue;
   analogWrite(LED1, writeValue);

    potValue1 = analogRead(potPin) / 10;
    potValue2 = potValue1 / 1.02;

    lcd.setCursor(0,0);
    lcd.print("Potent=");
    lcd.print(potValue1);
    lcd.print("%");
    delay(100);
    lcd.print(" ");
    delay(1);
}

void checkSwitches() {

    analogWrite(LED1, brightness);
    delay(10);

  buttonState1 = digitalRead(ButtonLeft);

  if(buttonState1 == HIGH){
    brightness--;
    if(brightness < 0){
      brightness = 0;
    }
  }

  buttonState2 = digitalRead(ButtonRight);

  if(buttonState2 == HIGH){
    brightness++;
    if(brightness > 255){
      brightness = 255;
    }
  }

 lcd.setCursor (0,1);
 lcd.print ("Brightness=");
 lcd.print (brightness);
 lcd.print ("   ");
}

```

# Answer
> 3 votes
Your code doesn't make much sense.

You set the LED to 2 different brightness values that don't have anything to do with each other: The pot brightness and the button-based brightness. You only adjust the LED based on switches once every 5 mS. Thus the LED is going to flicker between 2 different brightness values.

What do you want it to do? How do you want to control the brightness based on input from both the pot and your switches? (What is the relationship between the buttons and the pot? Should the button input alter max/min value of the pot up and down? Should holding the button down change the brightness by 1 value per a specific time unit? Say 2 increments/decrements per second?)

Describe the user interface you want to achieve, and then think through how you would do that in code.

---
Tags: arduino-uno, led, pwm, button, potentiometer
---


title: Why is my relay not triggering?

text:
# Question
Title: Why is my relay not triggering?
I have a 4 channel relay for my Arduino. Here's an image:

**From what I can tell, it's rated for 5V direct current because of the big `05VDC` at the bottom, but please tell me if I'm wrong? If I'm wrong, then that's the problem here.**

I've tested out an LED on 5V DC to work and connected it to output side of the relay.

I've connected my Arduino to the input, programmed with the following code:

```
const int RELAY_PIN = 3;

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  Serial.begin(96000);

}

void loop() {
  Serial.println("Relay ON");
  digitalWrite(RELAY_PIN, LOW);
  delay(1000);

  Serial.println("Relay OFF");
  digitalWrite(RELAY_PIN, HIGH);
  delay(1000);
}

```

I can confirm that the corresponding LED on the relay for channel 4 does blink for 1 second and stay off for 1 second, which I'm expecting it's meant to do. I've never worked with an Arduino or a relay before.

However, the 5V DC LED on the other end never lights up. Why is my relay not switching on?

Edit: About the LED circuit. It is on and fully powered. If I bypass the relay and join the two wires, the LED lights up. If I plug the two wires into the relay, the LED never lights up.

Edit2: About the jumper: I have a secondary 5V power supply connected to the VCC for what I'm told is isolation. I've read a little on the matter, but am not fully aware of how it works.

Edit 3:

**Connections**

I have the following connections:

* Output 3 (Arduino) to Input 4 (Relay)
* 5V (Arduino) to Input VCC (Relay) \[The one next to the input pins\]
* Power supply positive/ground to GND (Relay)
* Power supply negative/live to VCC (the one next to the JD-VCC)

This did not work. What did work was the following configuration:

* Output 3 (Arduino) to Input 4 (Relay)
* 5V (Arduino) to Input VCC (Relay) \[The one next to the input pins\]
* Jumper across VCC and JD-VCC on the Relay

# Answer
* From the image in the question, the jumper across pins J5 (in the below schematic) or JD as on the silk screen on the PBC is missing.
* Using the above schematic, a choice to power the Ardino and the relays off of one 5V power supply can be made. This appears to be done by connecting the 5V to the VCC pin, Ground to the GND pin & placing a jumper across J5. However, it appears that the relays can be isolated from the Arduino if desired. This appears to be done by connecting the Arduino's 5V to pin 2 of J5. That should be enough to light up the LED indicator and therefor the optical isolator when the Arduino's output to IN1, 2, 3 or 4 is low. Then, connect the 2nd power source 5V to pin 1 of J5 and the ground from the 2nd power source to pin GND. This last step should provide the power to close the relays when the Arduino takes IN1, 2, 3 or 4 low.
* Lastly, make sure the polarity of the 2nd power supply (if one is used) is correct. The output side of the optical coupler and the transistor driving the relay only work when the current is passing in the proper direction. Not to mention, the reverse bias flyback diode (D1, 2, 3 & 4) would short out the power supply if connected in the reverse direction. However, this catastrophe is avoided here as the transistors (Q1, 2, 3 & 4) would not pass current in the reversed direction.
> 2 votes

# Answer
A relay is an electromagnet-driven switch. It opens and closes that switch, but doesn't provide power.

Assuming it's like my relays, that relay can either power the relay coils AND the logic inputs, or (if you remove the jumper) use separate power for the relay coils and the logic signals.

Since you've removed the jumper, you need to provide 2 different 5V power sources to drive the relay - one high-current supply to the VCC, which runs the logic circuits and the relay coil. Another to the logic power in. Then you ground the input pin to activate one of the relay channels.

Finally, you need to wire the screw terminals on the left side into a circuit with separate power that controls something. For an LED, you'd need power, the LED, and a current-limiting resistor wired in series with the screw terminals on LED channel 1.

For an LED this is serious overkill. You could drive the LED directly (with a current limiting resistor) from the Arduino logic signal.
> 1 votes

---
Tags: relay
---


title: There is no PWM output

text:
# Question
Title: There is no PWM output
I recently made a project where output is coming from the differential between data reading and reference value. It works on my Proteus simulation but there is no PWM output on my real world device.

Here is my code listing

```
for (z = 0; z <= output2; z++)
  if (output2 >= 30) {
   toggle == HIGH;
   en = !en;
  }
if (en == true) {
  OCR1A = map(z, 0, 255, 0, ICR1); ;
  OCR1B = 0;
} else {
  OCR1A=0;
  OCR1B = map(z, 0, 255, 0, ICR1);
}
if (output2 < 30) {
  en = !en;
  analogWrite(9, 0);
  analogWrite(10, 0);
}

```

# Answer
> 1 votes
I’m not sure what you’re trying to accomplish, but you’re writing a constant `0` to the analog output.

> ```
> if (output2 < 30) {
>   en = !en;
>   analogWrite(9, 0);
>   analogWrite(10, 0);
> }
>
> ```

To quote the analogWrite() doc

> Syntax
>
> analogWrite(pin, value)
>
> Parameters
>
> pin: the pin to write to. Allowed data types: int.
>
> value: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types: int

If you want to see an output, you have to write a value between 0 and 255.

---
Tags: pwm
---


# Question
Title: Why does current flow along a wire instead of a resistor right next to it?
I am having trouble understanding exactly what is going on in a circuit where when a button is pressed an LED goes on. Also, I have the Arduino UNO.

The schematic can be seen at:

2:36 of this video: Arduino Tutorials: Control a LED with a Button.

So, the part that I don’t understand is, how come when the button is clicked and the current can pass through, the current doesn’t go through the pull down resistor and instead goes along the input wire?

I’m a beginner but do understand concepts like voltage, amps, resistors, Ohm’s law, etc. So answers don’t have to be super simple, but simple enough that I can understand them. Thanks!

# Answer
> 3 votes
> So, the part that I don’t understand is, how come when the button is clicked and the current can pass through, the current doesn’t go through the pull down resistor and instead goes along the input wire?

Simple: It *does* go through the pull down resistor. But it *also* goes down the "input" wire.

For simplicity you can imagine that the input is simply a very large resistor. Say, 1MΩ.

The circuit can then be simplified as:

simulate this circuit – Schematic created using CircuitLab

Contrary to popular belief, current does *not* take the path of least resistance. It takes *all possible* paths. The quantity of current through each path is proportional to the resistance of the paths.

In this example we have two paths - one with 10kΩ and one with 1MΩ. That's a ratio of 1:100, and the current will be split accordingly.

You can calculate the current that flows through each resistor simple using Ohm's Law because the wires and switch are (in an ideal world) just not there. The 5V is directly connected across each of the resistors.

So for the 10kΩ resistor the current through is is:

```
     V      5
I = --- = ----- = 0.0005 = 500µA
     R    10000

```

And for the 1MΩ it is of course 100x smaller (I'll let you do the maths for that if you want to check), so 5µA.

The full current that the circuit takes is 505µA, with it split between the two resistors.

With the Arduino instead of the 1MΩ resistor it's exactly the same (though the current values may vary somewhat). 500µA flows through the 10kΩ resistor, and "some tiny current" flows through the Arduino.

However, with all that said, the Arduino really doesn't care about the current. All it cares about is the voltage. With the button pressed both the input and the 10kΩ resistor are connected directly to the 5V supply - so the Arduino reads that as "HIGH". When you release the button the input is now connected to ground through the 10kΩ resistor, but there's no current to flow, so there's no voltage across the resistor (the voltage across a resistor is proportional to the current flowing through the resistor - Ohm's Law), so it's as if the input is connected directly to ground - and the Arduino reads that as "LOW".

To be more technically accurate the input of the Arduino is actually more akin to a tiny capacitor. When you apply 5V to the input it charges that capacitor up. Once it reaches 60% of 5V the Arduino recognises it as a "HIGH" signal.

When you release the button that capacitor is then connected to ground through the resistor, and it discharges through that resistor. Once it drops to 30% of 5V the Arduino sees it as being "LOW".

If you don't have the pull-down resistor, when you remove the 5V from the input that capacitor is still charged. So the Arduino still sees it as a HIGH. The charge in the capacitor will slowly bleed away until it's low enough to be seen as low.

But, (and it's a *big* but), the capacitor is very sensitive and can be charged up again by ambient energy around the place (radio waves, static electricity, etc). It can harvest enough energy from the environment to get back up to the 60% of 5V and be seen as "HIGH" again. This is known as "Floating", and is something you do *not* want in your circuit. The input "flaps around" between HIGH and LOW with no control. Which is why the pull-down resistor is absolutely essential.

# Answer
> -1 votes
the answer is within the question, Electrons will quite happily travel along a wire until they hit resistence as in a resistor. where there is less resistence too flow that is the path they will take. The path of least resistence you might say.

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


# Question
Title: Help with coding Arduino Nano to run fan through slide switch at specific intervals
I’m trying to use Arduino Nano to run my 5 V PC fan, which, I know it sounds crazy, it’ll be mounted on a piece of Tupperware that’ll control the airflow through it via the fan. However I have no idea how to code the Arduino, but I do know how to code other things when I’ve done it in class. The setup is a 5 V rechargeable lithium ion portable battery connected to the switch which would be connected to the Arduino, and when the switch is triggered/flipped it would allow power to the Arduino, boot it up, and trigger the code that would tell the fan to run at specific intervals. The idea for intervals is a result of the battery only having 23 hrs and 10 minutes of continuous battery life while powering the fan. The pseudocode would look something like:

> Press bump switch, it turns on the Nano with the ensuing program. Twice an hour, the Nano starts the fan. The fan runs for 20 seconds to 30 seconds each time the fan is started. After a set of 48 on/off cycles have completed (24 hours), the Nano is set to sleep mode in order to save power. In order to restart cycles, user must press bump switch again.

I’m pretty sure I have the hardware side of things down but if I don’t please do inform me.

I’ve attached a picture of what it’ll approximately look like, with the battery at the left, switch in the middle, then the Arduino (not seen in picture), then the fan.

I know this is asking a lot when I don’t even know where to get started with the coding, but I’d be sincerely eternally grateful.

# Answer
> 2 votes
You can't run the fan directly from an Arduino pin. The fan will require to much current for that to work. Instead connect the fan, via a transistor/mosfet to the Arduino.

Also add a (flyback-)diode to the fan, as turning of the fan can create huge (but short) voltage spikes, which can damage the transistor/mosfet.

Pseudo code would be something like:

```
for( byte i=0; i<48; i++ )
{
  digitalWrite(fanPin, HIGH);
  delay(20000);
  digitalWrite(fanPin, LOW);
  delay(1780000);
}

```

You could also put the Arduino in sleep mode, during those half hours, as well. You could use the LowPowerSleep library. Then replace the `delay(ms)` with `LowPower.sleep(ms)`.

Lastly, some powerbank will automatically shut down, if the detect nothing is using power. The Arduino, without the fan on, will use so little current (compared to charging a phone) that such a powerbank would shut of.

---
Tags: programming, arduino-nano, sketch, battery, electricity
---


# Question
Title: How can I compare two serial port readings on Arduino Mega?
I'm writing some code that compares information from two Arduino Unos by an Arduino Mega 2560. The problem that I'm having is that when I read the information coming in through `Serial1` and `Serial2` on my `if` statements, I get both inputs out on my serial monitor for the Mega, but if I try to compare them after I have read them it comes out not working the way it is intended. I don't know if I might be missing some syntax on my code or if I'm doing this wrong but I would appreciate any help I can get.

```
byte inData;

byte inDataTwo;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);

  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop()
{
  if (Serial1.available()>0 )
  {
      inData = Serial1.read();
      Serial.print(char(inData));
  }
  if (Serial2.available()>0)
  {
    inDataTwo = Serial2.read();
    Serial.print(char(inDataTwo));
  }
  if(inData == inDataTwo)
  {
    Serial.print("true");
  }
  else
  {
    Serial.print("False");
  }
}`

```

# Answer
> 2 votes
I think your code is implemented wrong in general. Even if it worked "like intended" it would not behave like you might want it to.

The first problem is, that you are polling for bytes that are received **asynchronuously**. That means that two byte sequences must not only be equal, they must also be sent "at the same time" if they should pass your comparison test. As the atmega will `loop()` very fast, there is only very little tolerance in timing.

Secondly, the variables you write received values to are not reset, meaning that once they have the same value they will pass the if statement until another byte has been received. Actually they aren't initialized and therefore will be `0` at the very beginning. So I wonder why you don't get your `Serial` interface flushed with `true`. Is this actually the entire code?

As a solution I suggest accumulating received bytes into a buffer and waiting for a soecific termination byte (often `/n`). If a termination character has been received, perform the comparison on that buffer.

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


# Question
Title: Can I use WTV020 sound module as SD card reader?
I want to try this example, A Simple Function for Reading CSV Text Files, in order to read a .csv file from an SD card, but I don't have the SD card reader module and can't find it in my country.

What I have found everywhere is this sound module, WTV020-SD, and I wonder if I can use that to read a single .csv file from it, using the SD Arduino library. I checked the module's documentation and there's nothing about it in there.

# Answer
It seems unlikely, for if you compare the schematic of the WTV020-SD (card reader part only) from the data sheet that you provided:

to the schematic of a bog standard SD card reader:

they are not the same. Instead of interfacing directly to the Arduino, as the standard SD card reader does, the WTV020-SD has additional logic, in the form of a WTV020SD-20S IC.

Therefore the code on the Arduino forums is highly unlikely to work.
> 1 votes

---
Tags: sd-card
---


# Question
Title: Adafruit Feather 32u4 BLE compatible with Software SPI?
Let me preface by saying that I am not super experienced with electronics. I have an Adafruit Feather 32u4 that is using Hardware SPI to communicate over Bluetooth. Unfortunately, I'm also hoping to use the SD library, which also uses Hardware SPI. I am hoping to change the board to use Software SPI instead, so that the two may work together.

The Bluefruit code by default has the following commented out:

```
/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

```

Which leads me to believe I could use SW SPI but simply uncommenting this and commenting out the HW SPI doesn't seem to work.

I am just not sure if it's not compatible with the board, or I need to do more than this...?

# Answer
Read SparkFun's guide, Serial Peripheral Interface (SPI), especially the multiple slaves section:

---

> ### Multiple slaves
>
> There are two ways of connecting multiple slaves to an SPI bus:
>
> 1. In general, each slave will need a separate SS line. To talk to a particular slave, you'll make that slave's SS line low and keep the rest of them high (you don't want two slaves activated at the same time, or they may both try to talk on the same MISO line resulting in garbled data). Lots of slaves will require lots of SS lines; if you're running low on outputs, there are binary decoder chips that can multiply your SS outputs.
>
> 2. On the other hand, some parts prefer to be daisy-chained together, with the MISO (output) of one going to the MOSI (input) of the next. In this case, a single SS line goes to all the slaves. Once all the data is sent, the SS line is raised, which causes all the chips to be activated simultaneously. This is often used for daisy-chained shift registers and addressable LED drivers.
>
> Note that, for this layout, data overflows from one slave to the next, so to send data to any one slave, you'll need to transmit enough data to reach all of them. Also, keep in mind that the first piece of data you transmit will end up in the last slave.
>
> This type of layout is typically used in output-only situations, such as driving LEDs where you don't need to receive any data back. In these cases you can leave the master's MISO line disconnected. However, if data does need to be returned to the master, you can do this by closing the daisy-chain loop (blue wire in the above diagram). Note that if you do this, the return data from slave 1 will need to pass through all the slaves before getting back to the master, so be sure to send enough receive commands to get the data you need.
> 2 votes

---
Tags: bluetooth, spi, adafruit, software
---


# Question
Title: How do I know if GY-521 MPU6050 has been calibrated properly?
I am planning to use the accelerometer of MPU6050 for a project.

I know that before using module (I am using GY-521 MPU6050), one needs to calibrate it.

I am using code by Luis Rodenas for calibration: https://sites.google.com/view/autoaero/code/auto-calibration-mpu6050

This code returns following offsets for my module:

```
-1123 -4100 1562 111 8 -1

```

Offsets are in Ax,Ay,Az,Gx,Gy,Gz format. I am using these offsets in MPU6050\_raw.ino example of i2cdevlib after making necessary adjustments. Here is the sketch

```
    // I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class
// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//

// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "MPU6050.h"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high

int16_t ax, ay, az;
int16_t gx, gy, gz;

// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO

#define LED_PIN 13
bool blinkState = false;

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
    // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
    // it's really up to you depending on your project)
    Serial.begin(115200);

    // initialize device
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();
    accelgyro.setFullScaleAccelRange(3);
    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

    // use the code below to change accel/gyro offset values

    Serial.println("Updating internal sensor offsets...");
    // -76 -2359 1688 0 0 0
    Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
    Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
    Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
    Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
    Serial.print("\n");
    accelgyro.setXGyroOffset(111);
    accelgyro.setYGyroOffset(8);
    accelgyro.setZGyroOffset(-1);
    accelgyro.setZAccelOffset(1562);
    accelgyro.setXAccelOffset(-1123);
    accelgyro.setYAccelOffset(-4100);
    Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
    Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
    Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
    Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
    Serial.print("\n");

    // configure Arduino LED pin for output
    pinMode(LED_PIN, OUTPUT);
}

void loop() {
    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

    // these methods (and a few others) are also available
    //accelgyro.getAcceleration(&ax, &ay, &az);
    //accelgyro.getRotation(&gx, &gy, &gz);

    #ifdef OUTPUT_READABLE_ACCELGYRO
        // display tab-separated accel/gyro x/y/z values
        Serial.print("a/g:\t");
        Serial.print(ax); Serial.print("\t");
        Serial.print(ay); Serial.print("\t");
        Serial.print(az); Serial.print("\t");
        Serial.print(gx); Serial.print("\t");
        Serial.print(gy); Serial.print("\t");
        Serial.println(gz);
    #endif

    #ifdef OUTPUT_BINARY_ACCELGYRO
        Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
        Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
        Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
        Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
        Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
        Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
    #endif

    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
}

```

This is the output at serial monitor when module is horizontal with package letters facing up. So have I calibrated the accelerometer properly? Please help if you can see any anomaly. Thanks.

# Answer
> -1 votes
consider looking at your acceleration and gyroscope data. if you have the device perfectly flat on the table you will find the gravitational force in some axis. tilt the whole setup and check if the g force now shows up in a different axis (hopefully the one you expect) then rotate the setup by 90 degrees around any axis. (always one at a time please!) if your gyro tells you that your rotational velocity per some measure of time roughly equals pi you know that everything works as expected. this actually works for every accelerometer and gyro so also these that you find on say the sparkfun 9dof board if you should ever come across those.

your cal can be tested by comparing a non cal-ed measurement with a cal-ed one. the differences between the expected value and the measured one should get smaller then.

---
Tags: arduino-uno, mpu6050
---


# Question
Title: My Code turns on my LED even when my switch is not pressed
I am trying to create a circuit that will turn my motor when I clap. When the first limit switch is low, and there is only one clap, a solenoid pin is supposed to be engaged (currently an LED), but when I clap once without pressing the limit switch, my LED turns on.

Also, I can't seem to get my code to work properly with the limit switches, to control my motor.

I am not sure what is wrong, can someone help?

I have an Arduino Uno with the following code:

```
#define sound_Sensor 2
#define EN1 9
#define IN1 8
#define IN2 7
#define solenoid_pin 6
#define LimSwitch1 4
#define LimSwitch2 3

int lastSoundValue;
int soundValue;
long lastNoiseTime = 0;
long currentNoiseTime = 0;
int solenoidPinStatus = LOW;
int status_motor = LOW;
int clap_interval = 200;
int claps = 0;
int pos1 = 1;
int pos2 = 1;

void setup() {
  pinMode(sound_Sensor, INPUT);
  pinMode(EN1, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(solenoid_pin, OUTPUT);
  pinMode(LimSwitch1, INPUT);
  pinMode(LimSwitch2, INPUT);
}

void loop() {

  soundValue = digitalRead(sound_Sensor);
  currentNoiseTime = millis();
  if (soundValue == 1 && lastSoundValue == 0 && (currentNoiseTime > lastNoiseTime + 200))
  {
      if (claps == 0) // allow first to register without much condition
      {
          claps = 1;
          lastNoiseTime = currentNoiseTime;
      }
      else
      {
          if (currentNoiseTime > lastNoiseTime + clap_interval)
          {
              claps++;
              lastNoiseTime = currentNoiseTime;
          }
      }
      Serial.print(claps);
  }
  else
  {
      if (currentNoiseTime > (lastNoiseTime + 3 * clap_interval)) // no claps for a longer duration time to print and/or reset clap
      {
          if (claps > 0)
          {
              while(status_motor == LOW){
                  if (digitalRead(LimSwitch1) == LOW && claps == 1)
                  {
                    solenoidPinStatus = HIGH;
                    digitalWrite(solenoid_pin, HIGH);
                  }

                 if (digitalRead(LimSwitch1) == LOW)
                 {
                    pos1 = 2;
                    status_motor = HIGH;
                    digitalWrite(IN1, HIGH); //Turns on Motor
                    digitalWrite(IN2, LOW);
                    analogWrite(EN1, 200); //Set Speed of Motor
                  }
                 else if (digitalRead(LimSwitch2) == LOW)
                 {
                    pos2 = 2;
                    status_motor = HIGH;
                    digitalWrite(IN1, HIGH); //Turns on Motor99++
                    digitalWrite(IN2, LOW);
                    analogWrite(EN1, 200); //Set Speed of Motor
                 }
              }

              while(status_motor == HIGH){
                if (pos1 == 2 && digitalRead(LimSwitch2) == LOW)
                {
                    status_motor = LOW;
                    digitalWrite(IN1, LOW); //Turns on Motor
                    digitalWrite(IN2, LOW);
                    pos1 = 1;
                }

                else if (pos2 == 2 && digitalRead(LimSwitch1) == LOW)
                {
                    status_motor = LOW;
                    digitalWrite(IN1, LOW); //Turns on Motor
                    digitalWrite(IN2, LOW);
                    pos2 = 1;
                }
              }
          }
             claps = 0; ///reset
      }
  }

// if (solenoidPinStatus == HIGH && status_motor == LOW && digitalRead(LimSwitch1) == LOW)
// {
//   solenoidPinStatus = LOW;
//   digitalWrite(solenoid_pin, LOW);
// }
  lastSoundValue = soundValue;
}

```

Sorry my wire diagram may not be the easiest to look at...

# Answer
> 2 votes
I think your problem might be connected to wiring.

This is one of the ways you can correctly connect a switch to Pin 8.

In this case you need to configure Pin 8 as INPUT\_PULLUP to use internal "pullup" resistor. When switch is not pressed Pin8 is connected to 5V through that resistor and value on the pin is HIGH. When you press the switch it connects Pin 8 to ground (the resistor prevents a short) and that way value on Pin 8 is LOW.

This is code that works correctly with the design above

```
void setup()
{
  pinMode(8, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop()
{
  if (digitalRead(8) == HIGH)
  {
    Serial.println("It's HIGH");
  }
  else
  {
    Serial.println("It's LOW");
  }

  delay(1000);
}

```

If you do not configure Pin 8 as INPUT\_PULLUP but just normal INPUT (as you did in your code) when the button is not pressed Pin 8 is "floating" (it's not connected to anything) and on a "floating" pin values are random.

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


title: WiFi Connection With a Enterprise WLAN

text:
# Question
Title: WiFi Connection With a Enterprise WLAN
I have an ESP32 and want to connect it to the WLAN at my office. Based on my current knowledge of the Arduino, we use the `WiFiClass` to connect to a WLAN and then use a `WiFiClient` to use the WiFi for data transfer.

In order to connect to the WLAN at my office, a certificate is needed. I have asked the network guys to issue a x.509 certificate and plan to use the `WiFiSecureClient` class.

The problem is that my `WiFi.begin(ssid)` method never leaves the following `while` loop:

```
Wifi.begin(ssid); // my office needs a certificate to connect to the wifi at the first place
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}

```

Note that to connect to my office network, no password is needed. The x.509 certificate is enough for the connection to establish.

Only after a WiFi connection is established, I can set the `WiFiSecureClient` parameters of the CA. But to connect to the WiFi, I need the certificate.

This is very confusing. Could someone please clarify a way our for me in this situation.

# Answer
> 2 votes
The Arduino API for ESP32 does not support your desired configuration.

The ESP32 is capable, but there is no easy "Arduino" interface to configure it.

Instead you will have to directly interface with the ESP32 SDK and configure things manually. That won't be easy.

This example code shows you how it can be done - however that code is not designed to run in the Arduino environment, so you will first need to understand exactly what it is doing and then adapt it to suit.

---
Tags: arduino-uno, wifi, esp32
---


# Question
Title: Analog reading with noise - Arduino Uno VS ESP12e
I was testing analog output from a microphone (Max9814) with an Arduino Uno, which came with nice results. The output provided by the microphone is converted into sound and is loud and clear.

Setup: (Max to Uno)

* Pin Vdd to 3,3V
* Pin GND to GND
* Pin Out to A0

---

However when I tried to set it up with an ESP12e instead of an Uno, I got a lot of 'noise' and no clear sound at all.

Here I used the following setup: (Max to ESP)

* Pin Vdd to VCC (VCC is measured at 3.3v with a multimeter)
* Pin GND to GND
* Pin Out to AD0

**A little 'side step'**

The problem arised that the analog output from the microphone delivered a voltage of around 1.24, while the ESP12e analog has 1v as max input. This made the analogRead max out all the time. For this reason I put a 10k OHM resistor between the OUT and AD0 combined with a 20k OHM resistor between gnd and AD0. This resulted into nice analog readings (instead of 1024, around 400-500 all the time).

However, like mentioned before, a lot of noise is in between and the sound is not clear. (I also tried to work with 'sample windows', here is the 'filtering mechanism' which can be found on many sites/questions and works perfectly fine):

```
//(global logic is set to take n samples and than print the line)
//Tried n of 5 to 20
//Also instead of just samples tried the micros variant instead of just samples which is also found on many sites to create a time window to record.
unsigned int sample = analogRead(A0);
if (sample < 1024) {  // toss out spurious readings
  if (sample > signalMax) {
    signalMax = sample;  // save just the max levels
  } else if(sample < signalMin) {
    signalMin = sample;  // save just the min levels
  }
}

unsigned int peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
Serial.println(peakToPeak);

```

Does somebody have a clue why the Arduino gives such clear and good sound, while the ESP12e does not. (The analog values do not 'seem' to differ much in the levels)

# Answer
The ESP8266 is an incredibly (electrically) noisy environment.

Because you can't use anything except the internal voltage reference, which is in turn driven from the internal noisy power, you can't get anything even vaguely approaching stable readings.

It is recommended to disable the WiFI completely ("Modem Sleep") when doing ADC readings to reduce noise.

However, the ADC was never intended for this kind of work. Its primary role is for monitoring the battery voltage of your hardware - and as such it really doesn't care that much about noise, since you can average a number of samples for greater accuracy (something you can't really do with audio).
> 3 votes

---
Tags: arduino-uno, esp8266, analogread
---


# Question
Title: Problem with String& argument of a function
I am trying to send SMSs using a GSM module with Arduino Mega. I have followed a tutorial and downloaded the SIM908IDE100 library. I am using the function

`SendSMS(String&, const char [27]);`.

It works fine when I type:

`sms.SendSMS("1234567890","Text message");`

where "1234567890" is the telephone number I want to send the SMS to and "Text message" is the text of the SMS.

If I instead try to pass to the function a String containing the telephone number

`String number = "1234567890";
sms.SendSMS(number,"Text message");`

I get the following error:

`exit status 1
no matching function for call to 'SMSGSM::SendSMS(String&, const char [27]);'`

I don't understand what String followed by an ampersand means. What am I supposed to pass the function as its first argument?

# Answer
The function prototype in sms.h is

```
char SendSMS(char *number_str, char *message_str);

```

if `number` is `String`, you should have

```
sms.SendSMS((char*) number.c_str(),"Text message");

```

`c_str()` is a function of the Strinng class. It returns a pointer to internal char array of the String object.

The cast to `char*` is necessary because the author of the library didn't make the parameter constant with `const char*`. (It is a good practice, to declare pointers and references as constants.)

The error message `no matching function for call to 'SMSGSM::SendSMS(String&, const char [27]);` shows the arguments you try to use. `String&` is reference to some instance of the `String` type
> 0 votes

---
Tags: arduino-mega, gsm, string, functions
---


title: Problem with LCD

text:
# Question
Title: Problem with LCD
I'm working on this piano project. When I push a button one of the led light is suppose to turn on and a tone comes out of the piezo. The LCD screen is suppose to print out a sentence but I can't get it to work.

Here is a picture of the board ( everything works except the LCD) I think the problems lies in the power supply but I'm not sure. This is the first time I use a big breadboard.

Here is my code:

```
#include <LiquidCrystal.h>

LiquidCrystal lcd(13,12,11,10,9,8);

int p1 = 1;
int p2 = 2;
int p3 = 3;
int p4 = 4;

int C,D,E,F;
int buzz = 5;

void setup()
{
   lcd.begin(16, 2);

  lcd.print("hello, world!");

  Serial.begin(9600);
  pinMode(p1,INPUT);
  pinMode(p2,INPUT);
  pinMode(p3,INPUT);
  pinMode(p4,INPUT);

}

void loop()
{

  lcd.setCursor(0, 1);

  lcd.print(millis() / 1000);

  C = digitalRead(p1);
  D = digitalRead(p2);
  E = digitalRead(p3);
  F = digitalRead(p4);

  if(C == 1){

    tone(buzz,523);
  }else if(D == 1){
    tone(buzz,587);
  }else if(E == 1){
    tone(buzz,659);
  }else if(F == 1){
    tone(buzz,698);

  }else{
    noTone(buzz);
  }
  delay(50);
}

```

# Answer
The LCD is not powered, there are 2 separated power rails... use a wire to connect both rails.
> 1 votes

# Answer
the power rails are separated in the middle of the breadboard. bridge them with jumper wires
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Is it possible to send a float Array over I2c
I have tried it several times myself but i never could send or receive it properly. I am asking myself if it is possible and if so could someone explain how?

Cheers.

# Answer
Below is a simple rewrite of the Master Writer/Slave Receiver Wire Tutorial, https://www.arduino.cc/en/Tutorial/MasterWriter, for a vector of floating-point numbers.

**Master Writer Sketch**

```
#include <Wire.h>

const int DEVICE = 8;

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

void loop() {
  const int VEC_MAX = 6;
  float vec[VEC_MAX];
  uint8_t* vp = (uint8_t*) vec;

  Wire.requestFrom(DEVICE, sizeof(vec));
  while (Wire.available()) {
    *vp++ = Wire.read();
  }

  for (int i = 0; i < VEC_MAX; i++) {
    Serial.println(vec[i]);
  }

  delay(500);
}

```

**Slave Receiver Sketch**

```
#include <Wire.h>

const int DEVICE = 8;
const int VEC_MAX = 6;
float vec[VEC_MAX] = { ... };

void setup() {
  Wire.begin(DEVICE);
  Wire.onRequest(requestEvent);
}

void loop() {
  delay(100);
}

void requestEvent() {
  Wire.write((uint8_t*) vec, sizeof(vec));
}

```

> Is it possible to send a float Array over I2c

So I would answer - Yes.
> 1 votes

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


title: ESP32 bluetooth discovery parse names

text:
# Question
Title: ESP32 bluetooth discovery parse names
I'm running a sample code from ESP32 examples and I'm scanning available BLE devices. I can see device MAC address etc. But for few devices I can't see their names.
I am using ESP-WROOM-32 with hardware support checked out directly from their github (some bugs were fixed earlier on github than via lib manager)
When I use LightBlue app for discovery of BLE Devices I can see names for more devices that ESP. What can I change to see the names correctly? OR Can how can I parse device name from the data I'm receiving?

This callback code

```
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
      Serial.print(" RSSI: ");
      Serial.println(advertisedDevice.getRSSI());
    }
};

```

produces this output:

```
Advertised Device: Name: , Address: 1d:0c:c7:3a:fb:c6, manufacturer data: 4c0009060378c0a81f12, payload: 1073609632
 RSSI: -75

```

# Answer
> 2 votes
Bluetooth has two ways of dealing with device names. A device can optionally choose to advertise its device name. It also has to respond to a "get device name" request. The former is passive, and is what you normally see when scanning. The latter is active and requires you to connect to the device and make a request. If the device doesn't advertise the device name then the only way you can get the name is to make a GATT "Name Characteristic" request to the device. The ESP32 doesn't (AFAIK) do that automatically because these things are designed to be "light weight". Your heavier-weight "reference" software can go off and do more things because it's a full-blown application.

You can sometimes see the difference in the devices because your reference application might populate the list of devices with a combination of MAC addresses and names, and then replace the MAC addresses with names in a later step. Also it probably caches names that it has queried in the past.

---
Tags: bluetooth, esp32, espressif
---


# Question
Title: Stacking adc's when making an midi controller ( lots of potmeters)
I'm making a midi controller with the Arduino uno. It contains approximately 50 analog inputs with potentiometers. I have enough MCP3008 adc's here but I have no idea how I connect 2 or more adc's to the Arduino so that I can read 50. How do you stack adc's?

# Answer
> 1 votes
These ADC's use the SPI protocol. Luckily the Arduino has one onboard.

With each ADC you get 8 channels (thus inputs). Since you need more than one SPI device (ADC in your case).

With SPI you can chain multiple SPI devices to your SPI port of the Arduino. To select which is active you use the Chip/Slave select signal. This is a separate GPIO you can define yourself. Read more about SPI to read details.

For 50 inputs you need 50 / 8, rounded up is 7 ADCs. This means also 7 CS pins. Thus in total you need 3 (for SPI) + 7 = 10 pins. I hope you have that many left.

About 'stacking', just put the ADC's on a breadboard and wire them according to the SPI protocol.

See also Arduino Reference SPI

# Answer
> 0 votes
With SPI the SCK, MISO, MOSI are connected in parallel to all devices. The device with the active low Chip Select pin is the one that receives a command and then sends data, the others ignore what is happening. You can also load data into a shift register to create the chip selects, thus only 4 pins are needed: SCK (13), MISO (12), MOSI (11), to all the devices, and use D10, the SS pin, as the latch pin (SRCK) into a 74HC595 for the 7 chip selects out to the MCP3008s.

The code to loop can be pretty simple.

```
for (pin = 0; pin <7; pin = pin +1){
  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address] = SPI.transfer(addressByte [address]); // send out address, read in D9, D8
  lowerBits[pin + address] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+1] = SPI.transfer(addressByte [address+1]); // send out address, read in D9, D8
  lowerBits[pin + address+1] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+2] = SPI.transfer(addressByte [address+2]); // send out address, read in D9, D8
  lowerBits[pin + address+2] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+3] = SPI.transfer(addressByte [address+3]); // send out address, read in D9, D8
  lowerBits[pin + address+3] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+4] = SPI.transfer(addressByte [address+4]); // send out address, read in D9, D8
  lowerBits[pin + address+4] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+5] = SPI.transfer(addressByte [address+5]); // send out address, read in D9, D8
  lowerBits[pin + address+5] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+6] = SPI.transfer(addressByte [address+6]); // send out address, read in D9, D8
  lowerBits[pin + address+6] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+7] = SPI.transfer(addressByte [address+7]); // send out address, read in D9, D8
  lowerBits[pin + address+7] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

}

```

The end result are two 56 byte arrays, upperBits\[\] and lowerBits\[\], combine a byte from each for a reading per channel.

I do have a lot of duplicate code there that could likely be reduced to a loop within a loop to remove the redundancy.

'address' could come from an array also, as the data needs to be 0b10000000, 0b10010000, 0b10100000, 0b10110000, 0b11000000, 0b11010000, 0b11100000, 0b11110000

or start with address = 0x80 and add 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70

That code has to integrate to drive the shift register, which I forgot about, so instead of

```
digitalWrite (csPin[pin], LOW);
and
digitalWrite (csPin[pin], HIGH);

```

you'd have

```
digitalWrite (shiftRegisterLatch, LOW); // first MCP3008 CS low
SPI.transfer(0b11111110);
digitalWrite (shiftRegisterLatch, HIGH); //first MCP3008 CS low
// read from ADC0 on first MCP3008 using SPI.transfers above
digitalWrite (shiftRegisterLatch, LOW); // first MCP3008 CS high
SPI.transfer(0b11111111);
digitalWrite (shiftRegisterLatch, HIGH); //first MCP3008 CS high

```

Repeat for channels ADC1 to ADC7

Then go to the next device:

```
digitalWrite (shiftRegisterLatch, LOW); // 2nd MCP3008 CS low
SPI.transfer(0b11111101);
digitalWrite (shiftRegisterLatch, HIGH); //2nd MCP3008 CS low
// read from ADC0 on second MCP3008 using SPI.transfers above
digitalWrite (shiftRegisterLatch, LOW); // 2nd MCP3008 CS high
SPI.transfer(0b11111111);
digitalWrite (shiftRegisterLatch, HIGH); //2nd MCP3008 CS high

```

So the data could be in an array as well: 0b11111110, 0b11111101, 0b11111011, 0b11110111, 0b11101111, 0b11011111, 0b10111111, with 0b11111111 to turn off CS

I'd be using direct port manipulation as well instead of digitalWrite() to speed up latching data into the shift register.

---
Tags: arduino-uno, adc, potentiometer, input, digital-analog-conversion
---


# Question
Title: Sporadically corrupted data returned from ESP8266
I have an Arduino Uno connected to an ESp8266 via an ESP-01 adapter. The Adapter is powered from the Arduino 5v and Gnd pins and the Tx/Rx to the Adapter use Arduino pins 2/3. I have basic code which sets the ESP8266 as an access point and I am able to connect to the AP from my phone, send a message and receive a reply from the ESP8266. This works fine for 75% of the time. other times, the message received by ESP8266 ( and printed on the serial monitor for debug ) is truncated, and/or corrupted. I have tried a different ESp8266 and a different adapter; I don't get corruption errors with other programs run on the Uno; I have dropped the communications speed between the Uno and ESp8266 to 9600 baud. What could be the cause of the corruption I am seeing in the data ? Thanks

I have updated my app an no longer get corrupted data, but there are characters data missing from the returned data stream.

Here is my sketch :

```
#include <SoftwareSerial.h>

//
// ESP8266 interface
////////////////////

SoftwareSerial wifiSerial(2, 3);            // RX, TX for ESP8266

#define TICK  100

bool DEBUG = true;
int responseTime = 1000;

#define ESP8266CMD_SET_UART_9600            "AT+UART_CUR=9600,8,1,0,3"
#define ESP8266CMD_SET_UART_38400           "AT+UART_CUR=38400,8,1,0,0"

#define ESP8266CMD_ECHO_OFF                 "ATE0"
#define ESP8266CMD_ECHO_ON                  "ATE1"
#define ESP8266CMD_SET_WIFI_STATION_MODE    "AT+CWMODE=1"
#define ESP8266CMD_SET_WIFI_SOFTAP_MODE     "AT+CWMODE=2"
#define ESP8266CMD_GET_IP_ADDRESS           "AT+CIFSR"
#define ESP8266CMD_CONFIG_AP_LIST_ALL       "AT+CWLAPOPT=1,2047" // Sort and display all netwroks
#define ESP8266CMD_CONFIG_AP_LIST           "AT+CWLAPOPT=1,3"    // Sort and display ECN / ESSID only
#define ESP8266CMD_LIST_AVAILABLE_APS       "AT+CWLAP"

#define ESP8266CMD_SEND_DATA                "AT+CIPSEND=0,"     // required data length to be appended
#define ESP8266CMD_CLOSE_ALL_CONNECTIONS    "AT+CIPCLOSE=5"

//
// LCD interface
////////////////

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR                            0x27
#define BACKLIGHT_PIN                       3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

//
// S E T U P
////////////

void setup()
{
  Serial.begin(115200);
  Serial.println("Initialising...");

  lcd.begin( 16, 2 );                                 //  LCD is 16x2

  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);        // Switch on the backlight
  lcd.setBacklight(HIGH);

  lcd.home();
  lcd.print("Initialising...");

  wifiSerial.begin(9600);

  sendToWifi( ESP8266CMD_ECHO_OFF, responseTime, DEBUG );
  sendToWifi( ESP8266CMD_SET_WIFI_STATION_MODE, responseTime, DEBUG );

  sendToWifi( ESP8266CMD_CONFIG_AP_LIST, responseTime, DEBUG );

  Serial.println("Wifi connection is running!");

  lcd.clear();
  lcd.print("Ready");

  pinMode(13,OUTPUT);  //set build in led as output
}

//
// L O O P
//////////

void loop()
{
String APList = sendToWifi(ESP8266CMD_LIST_AVAILABLE_APS, responseTime, DEBUG);

  Serial.println(APList);

  delay(100 * TICK);
}

/*
* Name:         sendToWifi
* Description:  Send data to ESP8266.
* Params:       command - the data/command to send
*               timeout - the time to wait for a response
*               debug - print to Serial window?(true = yes, false = no)
* Returns:      Response from the esp8266 (if there is a reponse)
*/
String sendToWifi(String command, const int timeout, boolean debug){
 String response = "";

 if(debug)
    Serial.println( "Command[" + command + "]" );

 wifiSerial.println(command);       // send string esp8266

 long int time = millis();
 while( (time+timeout) > millis())
 {
   while(wifiSerial.available())
   {
   char c = wifiSerial.read();      // read resonse

    response += c;
    time = millis();                // data received - reset timeout
   }
 }
 if(debug)
    Serial.println( "Response[" + response + "]" );

 return response;
}

```

..and here is output debug data from a sample run.

```
Initialising...
Command[ATE0]
Response[
OK
]
Command[AT+CWMODE=1]
Response[
OK
]
Command[AT+CWLAPOPT=1,3]
Response[
OK
]
Wifi connection is running!
Command[AT+CWLAP]
Response[]

Command[AT+CWLAP]
Response[+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(3,"NVR9ca3a92708f2")
+CWLA]
+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(3,"NVR9ca3a92708f2")
+CWLA
Command[AT+CWLAP]
Response[+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(4,"VM2293456")
+CWLAP:(5,"]
+CWLAP:(4,"VM2293456_EXT")
+CWLAP:(4,"VM2293456")
+CWLAP:(5,"

```

As well as the two networks VM2293456 and VM2993456\_EXT there are a number of other netwroks available, and on some runs I see those networks shown. In any case, there are missing characters from the response text.

# Answer
> 0 votes
AT firmware writes the data to Serial without any control. If the data are not read fast the Serial buffer overflows. If you count the bytes read by your sketch (including 2 not visible line ending characters per line) you count 64 bytes. That is the size of the RX buffer of SoftwareSerial. SoftwareSerial can tell you if the buffer overflowed. Call `wifiSerial.overflow()`.

The CWLAP takes time to execute on esp8266 side and then the AT firmware puts out the complete listing to Serial. Reading it byte by byte and storing millis() in-between is then too slow. You need to read it faster with a buffer.

I use `readBytesUntil` to read a line into buffer. This function waits for the next byte if there is a gap between bytes and stops reading if terminator is received or it times out. Default timeout is 1000 millis. It can by set with `setTimeout(t)`.

In your sketch you use String. I do not recommend it for a project, but in a test you could use:

```
result += wifiSerial.readStringUntil('\n');

```

to read and append a whole line.

# Answer
> 1 votes
Taking the information that people have kindly offered to me, I have re-written my code to use the AltSoftSerial library and I now have my small app working fine. Thanks. AltSoftSerial uses pins 8/9 in an interrupt driven manner, leaving the 'standard' pin 1/2 serial comms for a debug channel. I have it running at 19200 baud. I have remove String variable from the code and my final improvement will be to use malloc() to allocation data buffer in place of the current statically declared buffer. The purpose of my test app is to connect to my home wifi network a to print out the IP address allocated. All output goes to an LCD display, but the serial monitor could be used instead.

Here's my code :

```
#include <AltSoftSerial.h>
#include "ESP8266_cmd.h"

//
// Connect to home WiFi network using AltSoftSerial via pins 8/9 to ESP8266
///////////////////////////////////////////////////////////////////////////

//
// ESP8266 interface
////////////////////

AltSoftSerial wifiSerial;                   // RX, TX for ESP8266

#define TICK  100

#define DEBUG                               false
#define ResponseTime                        1000

#define NW_CREDENTIALS                      "\"VM2293456\",\"----------\""

//
// LCD defines
//////////////

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR          0x27
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

int n = 1;

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

//
// Buffer for ESP8266 data
//////////////////////////

#define BUFFER_LEN    512
char Buffer[BUFFER_LEN];

//
// State Machine
////////////////

enum {
 STATE_INIT_WIFI = 0,
 STATE_WIFI_CONNECT,
 STATE_WAIT_FOR_CONNECTED,
 STATE_GET_IP_ADDRESS,
 STATE_WAIT,

 STATE_ERROR,
} State;

int MachineState = STATE_ERROR;
int ErrorCode = 0;

void setup()
{
String response;

  Serial.begin(115200);
  Serial.println("Initialising...");

  lcd.begin( 16, 2 );                                 //  LCD is 16x2.  Cmd is Column, Row

  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);        // Switch on the backlight
  lcd.setBacklight(HIGH);

  lcd.clear();
  lcd.home();
  lcd.print( "Network Connect " );

  wifiSerial.begin(19200);

  MachineState = STATE_INIT_WIFI;
}

void loop()
{
String response;
char cmd[64];

  switch( MachineState )
  {
  case STATE_INIT_WIFI:
    lcd.setCursor( 0, 1);
    lcd.print("Initialising    ");

    sendToWifi( ESP8266CMD_ECHO_OFF, ResponseTime, DEBUG );
    if( strcmp( Buffer, "OK" ) != 0 )
    {
      ErrorCode = 1;
      MachineState = STATE_ERROR;
      break;
    }

    sendToWifi( ESP8266CMD_SET_WIFI_STATION_MODE, ResponseTime, DEBUG );
    if( strcmp( Buffer, "OK" ) != 0 )
    {
      ErrorCode = 2;
      MachineState = STATE_ERROR;
      break;
    }
    MachineState = STATE_WIFI_CONNECT;
    break;

  case STATE_WIFI_CONNECT:
    lcd.setCursor( 0, 1);
    lcd.print("Connecting           ");

    strcpy( cmd, ESP8266CMD_CONNECT_TO_AP );
    strcat( cmd, NW_CREDENTIALS );
    sendToWifi( cmd, ResponseTime, DEBUG );
    MachineState = STATE_WAIT_FOR_CONNECTED;
    break;

  case STATE_WAIT_FOR_CONNECTED:
    lcd.setCursor( 0, 1);
    lcd.print("Wait for connect");
    readFromWiFi( ResponseTime );
    if( strstr(Buffer, "WIFI GOT IP") != NULL )
       MachineState = STATE_GET_IP_ADDRESS;
    else
       delay( 1000 );
    break;

  case STATE_GET_IP_ADDRESS:
    lcd.setCursor( 0, 1);
    lcd.print("Getting IP Addr ");

    sendToWifi(ESP8266CMD_GET_IP_ADDRESS,ResponseTime,DEBUG);

    MachineState = STATE_ERROR;   // prime for error case
    ErrorCode = 3;

    if( strstr( Buffer, "OK" ) != NULL )
    {
      if( strncmp( Buffer, "+CIFSR:STAIP", 12 ) == 0 )
      {
        lcd.setCursor( 0, 1 );
        lcd.print( "                " );
        lcd.setCursor( 0, 1 );
        for( int i = 15; i < strlen(Buffer ); i++ )
        {
          if( Buffer[i] == '"' )
            Buffer[i] = '\0';
        }
        lcd.print( &Buffer[14] );   // Display extracted IP address
        MachineState = STATE_WAIT;
      }
    }
    break;

  case STATE_WAIT:
    delay(10000);
    MachineState = STATE_GET_IP_ADDRESS;
    break;

  case STATE_ERROR:
  default:
    lcd.setCursor( 0, 1 );
    lcd.print( "                " );
    lcd.setCursor( 0, 1 );
    strcpy( cmd, "Err " );
    itoa( ErrorCode, &cmd[strlen(cmd)], 10 );
    lcd.print( cmd );
    delay(10000);
    break;
  }
}

/*
* Name:         readFromWiFi
* Description:  Read data from ESP8266.
* Params:       timeout - the time to wait for a response
*               debug - print to Serial window?(true = yes, false = no)
* Returns:      Response from the esp8266 (if there is a reponse) in Global Buffer
*/
void readFromWiFi(int timeout)
{
int l = 0;
long int t = millis();

    while( ( t + timeout ) > millis() ){
      while( wifiSerial.available() > 0 ) {
        Buffer[l++] = wifiSerial.read();
        t = millis();
       }
    }

    Buffer[l] = '\0';

    trimRight( Buffer );
    trimLeft( Buffer );
}

/*
* Name: sendToWifi
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
void sendToWifi( const char *command, const int timeout, boolean debug){

 if(debug)
 {
    Serial.print( "Command[" );
    Serial.print( command );
    Serial.println( "]" );
 }

 wifiSerial.println( command );       // send string esp8266

 readFromWiFi( timeout);

 if(debug)
  {
    Serial.print( "Response[" );
    Serial.print( Buffer );
    Serial.println( "]" );
  }
}

void trimRight( char *src )
{
  int i = strlen(src)-1;

  for( ; i >= 0; i-- )
  {
    if( (src[i] != ' ' ) && ( src[i] != '\t' ) && ( src[i] != '\n' ) )
      break;
  }
  src[i] = '\0';
}

void trimLeft( char *src )
{
  int i, l = strlen(src);

  for( i = 0; i < l; i++ )
  {
    if( (src[i] != ' ' ) && ( src[i] != '\t' ) && ( src[i] != '\n' ) && ( src[i] != '\r' ) )
      break;
  }
  memmove( src, &src[i], l);
}

```

and here is the ESP822\_cmd.h header file that I created :

// ESP82266_cmd.h
//
// #defines for ESP8266 interface
//

#define ESP8266CMD_SET_UART_9600            "AT+UART_DEF=9600,8,1,0,0"
#define ESP8266CMD_SET_UART_19200           "AT+UART_DEF=19200,8,1,0,0"
#define ESP8266CMD_SET_UART_38400           "AT+UART_CUR=38400,8,1,0,0"

#define ESP8266CMD_ECHO_OFF                 "ATE0"
#define ESP8266CMD_ECHO_ON                  "ATE1"
#define ESP8266CMD_SET_WIFI_STATION_MODE    "AT+CWMODE=1"
#define ESP8266CMD_SET_WIFI_SOFTAP_MODE     "AT+CWMODE=2"
#define ESP8266CMD_GET_IP_ADDRESS           "AT+CIFSR"
#define ESP8266CMD_CONFIG_AP_LIST_ALL       "AT+CWLAPOPT=1,2047" // Sort and display all netwroks
#define ESP8266CMD_CONFIG_AP_LIST           "AT+CWLAPOPT=1,3"    // Sort and display ECN / ESSID only
#define ESP8266CMD_LIST_AVAILABLE_APS       "AT+CWLAP"

#define ESP8266CMD_SEND_DATA                "AT+CIPSEND=0,"      // required data length to be appended
#define ESP8266CMD_CLOSE_ALL_CONNECTIONS    "AT+CIPCLOSE=5"

#define ESP8266CMD_CONNECT_TO_AP            "AT+CWJAP_CUR="      // required essid and password to be appended
```

---
Tags: arduino-uno, esp8266
---


title: Modifying a code

text:
# Question
Title: Modifying a code
I use this code to turn on/off a small 5v dc motor. How can I modify it so that the arduino writes the potentiometer value to the motor when it is in ON state ?

```
int speed = analogRead(pot) / 4;
ButtonState = !digitalRead(Switch);

if (ButtonState != lastButtonState)
{
     if (ButtonState == 1)
     {
         if (motorstate == 1)
         {
             motorstate = 0;
         }
         else
         {
             motorstate = 1;
         }
     }
     lastButtonState = ButtonState;
}

digitalWrite(enable, motorstate);
delay(20);

```

# Answer
(this is not an answer, but just a comment, used to use code alignment).

This sketch (which I aligned in your code) can be rewritten to

```
int speed = analogRead(pot) / 4;
ButtonState = !digitalRead(Switch);

if (ButtonState != lastButtonState)
{
     if (ButtonState == 1)
     {
         motorstate = (motorstate == 1 ? 0 : 1);
     }

     lastButtonState = ButtonState;
}

digitalWrite(enable, motorstate);
delay(20);

```

I suggest the best way to proceed is to add print statements and use the serial monitor to check what values you get and see what you expect (which is not fully clear).
> 1 votes

---
Tags: arduino-uno
---


title: D1 mini / esp8266 WifiManager

text:
# Question
Title: D1 mini / esp8266 WifiManager
So i have a D1 mini that I want to connect to the wifi. I found the following code on the internet that is supposed to start a web server, that you can visit and then connect to the chosen wifi through the website. It will then remember the settings and try to connect to that wifi next time before it starts a web server - which is just what I need! The problem is that when I connect to the wifi the d1 mini thinks it did just than - but when I visit my router and check it is not connected.

I cannot figure out why it thinks it's connected but is not, can anyone help me?

```
#include <FS.h>                   //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager

void setup() {

  Serial.begin(115200);
  Serial.println();

  //WiFiManager

  WiFiManager wifiManager;

  //reset settings - for testing
  wifiManager.resetSettings();

  IPAddress _ip = IPAddress(192, 168, 0, 35);
  IPAddress _gw = IPAddress(192, 168, 0, 1);
  IPAddress _sn = IPAddress(255, 255, 255, 0);

  wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);
  if (!wifiManager.autoConnect("WemosAP", "ConfigureMe")) {
    Serial.println("failed to connect, we should reset as see if it connects");
    delay(3000);
    ESP.reset();
    delay(5000);
  }
  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");
  Serial.println("local ip");
  Serial.println(WiFi.localIP());
}
void loop() {
}

```

btw: the ip 192.168.0.35 is free, and I have checked both the gateway and the subnet mask from my laptop by running ipconfig in cmd.

# Answer
So it seems like the code is just broken. I found an example from the WifiManager library that is called "autoconnect". This just seems to do the exact same thing, just by also working:

```
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "WiFiManager.h"          //https://github.com/tzapu/WiFiManager

void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset settings - for testing
  //wifiManager.resetSettings();

  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
  wifiManager.setAPCallback(configModeCallback);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if(!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(1000);
  }

  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");

}

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

}

```
> 2 votes

---
Tags: esp8266
---


title: From Exploring Arduino Text

text:
# Question
Title: From Exploring Arduino Text
I am working thru the Exploring Arduino text mostly with success up until chapter 4. I have most of the parts required but for Figure 4-3 I used the following:

100nF Capacitor, (In place of 1uF Capacitor)

1N4007 Diode Rectifier, (In place of 1N4004 Diode)

S8050 NPN Transistor, (In place of PN2222 NPN)

DC Motor rated for 3V with a Reference Current of 0.35 to .4 Amps (Text lists "DC Motor")

Im aware that the Capacitor was undersized, Diode was a 4 series (so I assumed it was compatible), and the Transistor also the same but of a different manufacturer. Im also aware that the motor is underrated compared to the 9v input, but I didnt think this would cause a problem for a small time period.

My problem is that after about 10 seconds of running (both with the motor free spinning as intended, and sometimes just staying put but making a high pitched noise) the bread board started smoking. So, I disconnected everything and gave up for the day.

What was it that caused the breadboard to start smoking? Do you think I damaged my Arduino?

Link to companion site with diagrams: http://www.exploringarduino.com/content/ch4/

# Answer
> 1 votes
If you used the 9 V battery as described in the diagram, but with a 3 V rated motor, then the motor starts smoking and you might damage it. Use e.g. 2 AA batteries with 1.5 V instead of the 9 V battery, then it should work without smoke and your motor will survive much longer.

---
Tags: power, voltage-level, debugging
---


# Question
Title: How can I hook up multiple MMA8451 accelerometers, (I2C protocol) using one Arduino Mega?
How can I hook up four (adafruit) MMA8451 accelerometers (using I2C protocol) using one Arduino Mega? What I'm confused about is I only have one SDA and SCL on the Arduino Mega obviously. So how can I connect these all? Multiplexer? I need four because I have one on each leg of a robot. Or is perhaps this impractical to put an accelerometer on each leg of robot? I'm a little new to electronics so please explain in depth if you could. Thanks.

Note to moderators: I just would really love an answer to this even if this doesn't meet the super strict question guidelines. It seems every time I post here there's always that one person who takes it down for any number of trivial reasons. Please let me get an answer at least. Thank you!

# Answer
Brief explanation: When you talk to the slave device through I2C you start with (slave) device address. Then you send the message. It is like calling your colleague in an office with many other people. You say: "John", and when he is aware you continue with message, like "let's go for coffee".

This arrangement allows for adding up to 127 devices on one I2C bus. Each device must have different address (sorry, you cannot have two John's in the office, it will cause conflict). Generally two different type of devices will have different I2C addresses, but it may happen you need to use two (or more) of the same (like in your example). In this case, see below.

Many devices with I2C interface allows for address change. Using this facility you are able to communicate with many of the same devices through the same pair of cables.
You can check if your chosen accelerometer has possibility for address change: On picture below there is one with Address tab. When jumper is not fitted, you will get one address, when is fitted, the address of this device will be different, allowing of two of this accelerometers on one I2C bus. Unfortunately in this example there will be possibility of maximum of two of the same devices.

Of course there are devices with more than two possible addresses, you need to search for them.
And, yes, it is fine to use one Arduino to communicate with many I2C devices.

EDIT:
Looking after some of Adafruit accelerometers, I have found this page: https://learn.adafruit.com/i2c-addresses

And small off topic note: If you struggling on finding I2C with more than 2 addresses, check if it is easier to use SPI protocol. In this case you need (edited to correct bus lines names after user CrossRoads comment) MISO, MOSI, SCK and CS (chip select) wires. Chip select is individually connected to each slave device. This allows selecting particular device without addressing issue.
> 2 votes

# Answer
Talking about I2C protocol. The slave Address is of 7 Bits that means one I2c can handle 127 Slave I2C devices of different address. So you can connect 127 devices with Single I2C Port just make sure there slave address is different from each other.

Some I2C devices are provided with the option to select salve address by setting some pins high and low. If you are using some identical sensors you are set their slave address different.
> 2 votes

# Answer
The general technique for addressing multiple I2C devices is:

1. If the device(s) have only one address: use an I2C bus multiplexer.
2. If the device(s) have two addresses controlled by an addressing pin: use digital output pins from the Arduino to select which device to address, e.g., set the control pin for the selected device low and others high and use the corresponding address to address the device.

With MMA8451Q, factory default it has two distinct I2C addresses 0x1C and 0x1D, controlled by the SA0 pin, use digital output pins on the Arduino Mega to address the selected device (address 0x1C) by setting the corresponding output pin low for the selected device and the control pin for the others to high (address 0x1D). Use address 0x1C to interact with the selected device.

Cheers!
> 1 votes

# Answer
Simple just connect all SCK and SDL accelerometer lines together and then u just need to get a specific code address in your use to get a data from any of the accelerometers
> 0 votes

---
Tags: arduino-mega, i2c, adafruit, accelerometer, robotics
---


title: Triggering an ultrasonic sensor

text:
# Question
Title: Triggering an ultrasonic sensor
I made a smart blind stick for my class project. It uses an ultrasonic sensor to detect obstacles and I was asked this question in VIVA...

Why is it necessary for giving a digital high for 10 μS on the trigger (`Trig`) pin of an ultrasonic sensor ?

Why 10 μS only?

I changed it to 5 μS then to 20 μS and to 50 μS and it still works fine! Why so?

# Answer
The specification1 says (emphasis is mine):

> using IO trigger distance, the high signal to ***at least*** 10us.

So, longer than 10 μS is not a problem.

With respect to less than 10 μS, well 5 μS may also work, but it is out-of-spec and therefore not guaranteed to work and so may not always work correctly, or as expected.

From Source 1:

>

From Source 2:

>

---

As to why must it be 10 μS, well that is *probably* (at a guess) down to the design of the logic upon the silicon and the resultant propagation delay through the logic gates. Most, if not all, logic ICs specify a minimum amount of time required for a signal level, in order to allow the signal to propagate through the transistors that make up the logic, so that they switch correctly. PN junctions require a finite time for the electrons and holes to move, and when there are a number of them in sequential stages, that time is multiplied by the number of stages that the signal needs to propagate through. That is a very simplified way of looking at it.

To confirm this, you would need to speak to either the designers, or take a look at the mask used to fabricate the IC. Test simulations were probably run during the design phase, and they suggested a minimum trigger pulse of 10 μS. The figure could also be arrived at by simply looking at the design and counting the number of stages and multiplying that by the propagation delay per stage.

However, as Valbhav points out, the HC-SR04 is controlled by a STM8 (actually it is a STC11F), and after having looked at the STM8 programming manual, it is more related to instruction cycles. The `Trig` pin is, I assume, an interrupt, and from section **3.2 CPU registers**

> When an interrupt occurs, the CPU registers (CC, X, Y, A, PC) are pushed onto the stack. This operation takes 9 CPU cycles and uses 9 bytes in RAM

So, 9 CPU cycles just *begin to* to service the interrupt, and then however many needed to actually do the rest. I can't find any timing diagrams in the Programming Manual which would show the minimum interrupt signal length. This information, is however in the Reference Manual

The length of a CPU cycle will obviously depend upon the clock frequency., which according to this schematic, from An Ultrasonic Shortcut – Getting the HC-SR04 Transducer Up and Running Fast!, is 4 MHz:

So, 10 μS is 40 CPU cycles.

---

1 Sources for downloading HC-SR04 pdf datasheet:

> ### HC-SR04 Specifications
>
> * Working Voltage: DC 5V
> * Working Current: 15mA
> * Working Frequency: 40Hz
> * Max Range: 4m
> * Min Range: 2cm
> * Measuring Angle: 15 degree
> * Trigger Input Signal: 10µS TTL pulse
> * Echo Output Signal Input TTL lever signal and the range in proportion
> * Dimension 45 * 20 * 15mm
> 3 votes

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


# Question
Title: cannot convert 'bool' to 'PinStatus' for argument '2' to 'void digitalWrite(pin_size_t, PinStatus) on Arduino Uno Rev 2 Wifi not working
I am a newbie to micro controllers and struggling to figure out how to fix this issue. When using an older Arduino micro controller it works fine, but when I use a new board (Arduino Uno Rev 2 Wifi) it gives me this error:

```
cannot convert 'bool' to 'PinStatus' for argument '2' to 'void digitalWrite(pin_size_t, PinStatus)'

```

At this line :

```
digitalWrite(pin_enable_line, !digitalRead(pin_enable_line));

```

Library I am using is: `ReceiveOnlySoftwareSerial`.

# Answer
> 4 votes
The `digitalRead` method doesn't return a Boolean value. It returns an Integer.

From what I remember inside Arduino.h values of `LOW` and `HIGH` are defined as being simply Integer `0` and `1`.

```
#define HIGH 0x1
#define LOW 0x0

```

I think that was changed to an Enum called `PinStatus` but Enum can be treated as an Integer.

This means that you have to store results of `digitalRead` inside Integer variable.

```
int value = digitalRead(8);

```

It was designed that way to easily cast values between Integer and Boolean. By (very smart) design choice Integer value of `0` (`LOW`) will be cast to `false` and every other value (for example `1` or `HIGH`) will be cast to `true`.

The operator `!` (Boolean NOT) can be used only with Boolean variables so the compiler needs to perform several "implicit casts". When it's smart enough it will assume you are know what you are doing and it will add the cast by itself.

By reading the error I see that the issue is happening when compiler tries to convert Boolean value into Integer. So this is implicitly evaluated correctly as a Boolean value

```
!digitalRead(pin_enable_line)

```

But when you try to put it inside a place for PinStatus you get the exception

```
cannot convert 'bool' to 'PinStatus'

```

Try adding an "explicit cast" to PinStatus:

```
digitalWrite(pin_enable_line, (PinStatus)!digitalRead(pin_enable_line));

```

It should fix the issue. But I suggest splitting the code into several lines and adding a temporary variable. It makes debugging much easier. Trust the code optimizer that's built into the compiler. It will understand what you want to do and actual machine code will be the same.

---
Tags: arduino-uno
---


# Question
Title: Conditions with GSM module SIM900 doesn't execute
I'm executing this code to control a LED with GSM SIM900 message but there are two problems. First, it receives messages sometimes and some times doesn't. The second is that it doesn't execute the `if` conditions that are on the GSM message when received.

Is there a problem with my GSM module? Can any one help?

```
#include <SoftwareSerial.h>
SoftwareSerial gsm(9,10);
String msg;
const int LED = 13;

void setup() {
  gsm.begin(9600);
  Serial.begin(9600);
  Serial.println("PUMP CONTROL");
  Serial.println("t : to receive text");
  delay(1000);

  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop() {
  if (Serial.available()>0)
  switch(Serial.read())
  {
    case 't':
    showSMS();
    break;
  }

  while(gsm.available() > 0)
  {
    Serial.write(gsm.read());
  }
  if ( msg == "ON")
  {
    Serial.println("ON");
    digitalWrite(LED, HIGH);
     Serial.println("ON1");
    delay(1000);
  } else if (msg == "OFF")
  {
    digitalWrite(LED, LOW);
    delay(1000);
  }
  if(msg != "") msg = "";
}

void showSMS()
{
 gsm.print("AT+CMGF=1\r");
 gsm.print("AT+CNMI=2,2,0,0,0\r");
 delay(1000);
 msg = "";
 while(gsm.available() > 0)
 {
  msg += gsm.read();
 }
 Serial.println(msg);
}

```

# Answer
> 1 votes
I’ve solved the condition problems by making the condition with the ASCII code of ON and OFF.

I replaced:

```
if ( msg == “ON”)

```

with

```
if(msg.indexOf("ON")>=0)

```

and replaced:

```
else if (msg == "OFF")

```

with

```
if(msg.indexOf("OFF")>=0)

```

---
Tags: arduino-uno, gsm
---