# Question
Title: Why does the following code not cause the led's to flash but rather stay on continuously
```
int timer = 1000;
int thispin = 5;

void setup() {
  for (int thispin = 5; thispin < 8; thispin++)
    pinMode(thispin, OUTPUT);
}

void loop() {
  for (int thispin = 5; thispin < 8; thispin++)
    digitalWrite(thispin, HIGH);

  delay(timer);
  digitalWrite(thispin, LOW);

  for (int thispin = 7; thispin = 5; thispin--)
    digitalWrite(thispin, HIGH);

  delay(timer);
  digitalWrite(thispin, LOW);
}

```

I have the above code. I thought that how it was written would cause the led's to flash but they all stay on continuously. Could anybody help to explain what it is i have done wrong? I am very new to this and I'm just fiddling basically trying to learn. Thank you!

# Answer
The objective of the code is not clear. It seems the idea is to repeatedly blink 3 LEDs, connected on pins 5,6 and 7. To do so, the code needs slight modification-

```
int timer = 1000;
int thispin = 5;

void setup() {

  for (int thispin = 5; thispin < 8; thispin++)
    pinMode(thispin, OUTPUT);
}

void loop() {

  for (int thispin = 5; thispin < 8; thispin++)
    digitalWrite(thispin, HIGH);

    delay(timer);

  for (int thispin = 5; thispin < 8; thispin++)
    digitalWrite(thispin, LOW);

    delay(timer);

}

```

Also, since you wanted to know why the LEDs stay ON continuously with your code- This is because there is no delay statement after any of the digitalWrite-LOW statements. If there's no delay, the LEDs may turn off for a fraction of a millisecond, which won't be noticeable.
> 3 votes

# Answer
From the given code it is not entirely clear what you are trying to achieve. If I understood correctly, you want the pins to light up for one second and then go out. First from 5 to 7, and then from 7 to 5. Try the given code.

```
int timer = 1000;

void setup()
{
  for (int thispin = 5; thispin < 8; thispin++)
    pinMode(thispin, OUTPUT);
}

void loop()
{
  for (int thispin = 5; thispin < 8; thispin++)
  {
    digitalWrite(thispin, HIGH);
    delay(timer);
    digitalWrite(thispin, LOW);
  }

  delay(timer);

  for (int thispin = 7; thispin >= 5; thispin--)
  {
    digitalWrite(thispin, HIGH);
    delay(timer);
    digitalWrite(thispin, LOW);
  }
}

```

Also, using the same name for globals variable and loop iterators is bad style.
> 1 votes

# Answer
Exchange the last lines:

```
delay(timer);
digitalWrite(thispin, LOW);

```

It is 2 seconds on and maybe a few hundred nanoseconds on.
> 0 votes

# Answer
In the last for() loop, the limit expression, `thispin =5;` was probably meant to say `thispin <=5;`. As it is written, the expression is an assignment, not a test, and it will always be `true`, because 1) an assignment statement is also an expression having a value equal to the value assigned; and 2) the assigned value, '5', being non-zero, is equivalent to 'true'), so this loop will never end. thispin will get decremented forever and repeatedly set pin 5 to HIGH. It leaves the other pins alone, but they were already high, and the LEDs stay lit, which is what you observed.

(There are a couple of other errors, as noted earlier by previous responders, which will also prevent your code from operating as you expected.)
> 0 votes

---
Tags: led, code-review
---


title: L293D motor shield

text:
# Question
Title: L293D motor shield
I have the L293D motor shield on top of my Arduino UNO.

The L293D has a servo attached of 5 volt and a motor of 12 volt there is an external power supply.

If I remove the jumper of the board and power my motor with the 12 volt? Will my servo of 5 volt still have the 5 volt of the Arduino or is this connected to the external 12 volt?

# Answer
No , your motor will actually get power from outside but the Servo Motor will be powered by arduino even if the jumper removed because the ln298 shield is mounted on the arduino.
> 1 votes

---
Tags: arduino-uno, c++, power, motor, l293d
---


title: Arduino Coding Issue

text:
# Question
Title: Arduino Coding Issue
I'm running a water pump based on ultra sonic readings. Once the Ultra Sonic Sensor reads \> 10 cm , I want the water pump to start until sensor reads \< 5 cm. Would you please help me adjust the following code to meet my requirements.

```
void loop(){
 digitalWrite(trigPin,LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin,HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin,LOW);
 duration=pulseIn(echoPin,HIGH);
 distance=(duration*0.034/2);
 if(distance>5){
   digitalWrite(motor,HIGH);
   delay(30000);
   digitalWrite(motor,LOW);
 } else {
   digitalWrite(motor,LOW);
 }
}

```

# Answer
> 2 votes
So what you're asking is:

* If distance is greater than 10:
    + Turn on
* If distance is less than 5:
    + Turn off

That's not hard to code, since you already have an "if" there that compares the distance.

```
 if(distance>5){
   digitalWrite(motor,HIGH);
   delay(30000);
   digitalWrite(motor,LOW);
 } else {
   digitalWrite(motor,LOW);
 }

```

becomes:

```
if (distance > 10) {
    digitalWrite(motor, HIGH);
}

if (distance < 5) {
    digitalWrite(motor, LOW);
}

```

See how there's a direct 1:1 correlation between the English I wrote at the top and the code below it? That's often a good way to understand code: write it out in plain English step by step what you want and what decisions you need to make - then there's usually a simple conversion from English to code.

The hardest part of learning to program is understanding the logic. Do that in English first and the writing of the code itself becomes so much easier.

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


# Question
Title: ESP8266 with RTC DS1307 shield - WS2818B shield won't blink - I2C issue?
Dear Ladies and Gentlemen,

I'd like to let a LED blink base on the time of the day. So I took Wemos D1 mini and a WS2818B shield and a RTC DS107 Shield for the before mentioned ESP8266 model.

Based on my observation, I can let the LED blink on its own without starting the initialization of the RTC. As soon as I initialize the communication with the DS1307 shield, the LED shield won't translate any commands toward the desired behavior (e.g. the LED won't blink anymore).

What am I doing wrong?

I'm using the Ardunio IDE to program the D1 mini.

I stacked the shields and kept an eye on the pins to be sure I did wire everything the right way.

Libraries in use:
RTC: https://github.com/Makuna/Rtc
LED: Adafruit NeoPixel

Code:

```
// WIFI
#include <ESP8266WiFi.h>

// RTC
#include <RtcDateTime.h>
#include <RtcUtility.h>
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS1307.h>
RtcDS1307<TwoWire> Rtc(Wire);

// LED
#include <Adafruit_NeoPixel.h>
#define PIN        D2
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ400);

int DELAYVAL = 1000; // Time (in milliseconds) to pause between pixels

void setup() {

  Serial.begin(57600);
  Serial.println();
  Serial.flush();

  setupLed();

  setupWifiConnection();

  setupRtc();

}

void loop() {

  pixels.clear(); // Set all pixel colors to 'off'
  pixels.show();   // Send the updated pixel colors to the hardware.
  delay(DELAYVAL); // Pause before next pass through loop

  pixels.setPixelColor(0, pixels.Color(0, 150, 0));
  pixels.show();   // Send the updated pixel colors to the hardware.
  delay(DELAYVAL); // Pause before next pass

}

void setupRtc () {

  Rtc.Begin();

  RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
  Serial.println();

  if (!Rtc.IsDateTimeValid())
  {
      if (Rtc.LastError() != 0)
      {
          // we have a communications error
          // see https://www.arduino.cc/en/Reference/WireEndTransmission for
          // what the number means
          Serial.print("RTC communications error = ");
          Serial.println(Rtc.LastError());
      }
      else
      {
          // Common Causes:
          //    1) first time you ran and the device wasn't running yet
          //    2) the battery on the device is low or even missing

          Serial.println("RTC lost confidence in the DateTime!");
          // following line sets the RTC to the date & time this sketch was compiled
          // it will also reset the valid flag internally unless the Rtc device is
          // having an issue

          Rtc.SetDateTime(compiled);
      }
  }

  if (!Rtc.GetIsRunning())
  {
      Serial.println("RTC was not actively running, starting now");
      Rtc.SetIsRunning(true);
  }

  RtcDateTime now = Rtc.GetDateTime();
  if (now < compiled)
  {
      Serial.println("RTC is older than compile time!  (Updating DateTime)");
      Rtc.SetDateTime(compiled);
  }
  else if (now > compiled)
  {
      Serial.println("RTC is newer than compile time. (this is expected)");
  }
  else if (now == compiled)
  {
      Serial.println("RTC is the same as compile time! (not expected but all is fine)");
  }

  // never assume the Rtc was last configured by you, so
  // just clear them to your needed state
  Rtc.SetSquareWavePin(DS1307SquareWaveOut_Low);
}

void setupLed () {

  pixels.begin();

  pixels.clear();
  pixels.show();
}

void setupWifiConnection () {

  WiFi.begin("some ap", "some password");

  Serial.print("Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

```

# Answer
According to your code, you’ve connected the Neopixel to D2. The RTC is an I2C device, so it’s also connected to D2. How is that supposed to work? The Neopixel isn’t an I2C device.

Move the Neopixel to a different pin that’s not used by anything else - so not D1. Try D3. Update your code to use D3. There may be other issues but at least you won’t be trying to use the same pin to talk to two very different devices.
> 2 votes

---
Tags: esp8266, i2c, spi, shields, rtc
---


# Question
Title: Beginners code, loop doesn't detect unplugged pin
I'm learning on an Arduno UNO board, and im trying to turn a LED on three times when I connect pin 10 to ground and then turn it off. Then when I unplug the pin number 10 it should NOT blink again... yet it does and I can't find the issue.

this is the entire code:

```
bool ledBlinked = false;

void setup() {
  // put your setup code here, to run once:
  pinMode(7, OUTPUT);
  pinMode(10, INPUT_PULLUP);
}

//Turns on and off a digital pin, a number of times, with a certain delay
void blinkLed(int pin, int times, int del){
  // activates a pin a number of times
  for (int i=0; i<=times; i++){
    digitalWrite(pin, HIGH);
    delay(del);
    digitalWrite(pin, LOW);
    delay(del);
  }
}

//Checks if passed pin number is connected to ground
bool pinIsGround(int pin){
  return (digitalRead(10) == LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(pinIsGround(10) && !ledBlinked){ //if pin is connected to ground and the LED hasn't blinked
    blinkLed(7,3, 100); //blink pin 7, 3 times, with a delay of 100ms
    ledBlinked = true; //LED has blinked already
  }
  if (!pinIsGround(10) && ledBlinked){ //if pin is not connected to ground and the LED hasn blinked
    digitalWrite(7, LOW); //turn LED off (unnecesary?)
    ledBlinked = false; //LED hasn't blinked yet
  }

}

```

# Answer
> 0 votes
SInce I can coment I have to write this as answer. there are two ways of understanding your question:
If you dont want it to ever blink again then simply remove `ledBlinked = false;`
If you are trying to prevent the blinking until the button is depressed and pressed again then first think I see is the error in **blinkLed** function as
`for (int i=0; i<=times; i++)` would run times+one time. because it runs first with value of ***i*** being 0
(Eg times=4 would run for i equal 0,1,2,3,4 -\> Five times )
So correction to `for (int i=0; i<times; i++)` would run correct number of times (Eg times=4 would run for i equal 0,1,2,3 -\> four times )
Although as you are not checking status during the running of blinkLed function for the status of the button, if you release it while blink is running the script would not notice unless its still unpressed when script gets back to Loop.
Although since hardware operation take more work then logical operation I would recommend **if...else** statement rather then multiple hardware operations. Although they make code simpler to read

```
if(digitalRead(10) == LOW){
         if(ledBlinked != true)...
   } else { ...}

```

---
Tags: arduino-uno
---


title: None of the pins work as inputs

text:
# Question
Title: None of the pins work as inputs
I’m using an Arduino-uno

I'm trying to read an PWM signal being output by pin 6. I'm attempting to read it with pin A0.

5 volts are being supplied from pin 6 to a 300 ohm resister in series with one led. This circuit returns to the analog input pin A0.

It'll admit it's a strange set up and I was told to use a pass through filter to read the signal.

At this point I'm not concerned with whether the program reads the right values, so despite the code involving the serial monitor I'm just trying to figure out why the led won't turn on anymore.

As I stated in the sketch, this exact set up was working fine yesterday. The led was on and (accurate or not) there were consistent values being printed to the serial monitor.

I'm trying to figure out now what changed after I unplugged it last to create a now open circuit.

---

```

void setup() {

  Serial.begin(9600);
  pinMode(6, OUTPUT);
  // I  also tried setting the A0 pin as an input even though I thought you didn't have to and it didn't change anything.

}

void loop() {

  analogWrite(6, 255); // This pin is working as an output, I tested it to ground and led lights.

  int value = analogRead(A0); // I realize inputs are typically used for things like potentiometers
                              // But just as an example the LED should still turn on when connected here, correct?
                              //And it did the first few times I did it... maybe that was the problem?

  Serial.println(value);  // This was  all working previously. It just randomly stopped.
                          // Now this just prints random numbers and the circuit remains incomplete.
                          // Even if the input pins are not supposed to be used with 5 volts, Why was it working before then...
                          // ALSO it does not matter which pins you use for what...
                          // No current is running through the digital inputs with digital output set to HIGH.
                          // And No current runs through the analogInput pins when analogWrite is set to 255.
                          // Once again, I apologize if my terminology is off.

}
```

---

This is what I did to trouble shoot:

With the same sketch running on the board...

I connected a jumper from pin A0 to ground and the serial monitor switched from a bunch of random values to a solid 0. So it recognizes input still... in a sense.

**Then** I modified the sketch...

```
void setup() {

Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(8, INPUT);

}

void loop() {

// now I'm attempting to read a digital signal with the same circuit...
// Pin 6 is connected to a 300 ohm resistor in series with an led which returns to pin 8.

digitalWrite(6, HIGH);

int value = digitalRead(8);

Serial.println(value);

}

```

This gave the same result. The led wont turn on anymore unless the circuit ends are connected from a voltage source to ground.

Previously, any pins configured as INPUT would not only read consistent values but also complete the circuit, turning the led on.

Now the pins only recognize zero volts and do not complete any circuits. You can't even use a simple potentiometer if you wanted.

Each pin that can be configured as an INPUT acts the same way.

The only thing I did between the times when it was working and wasn't was unplug and plug in the board...

# Answer
Sounds like there's a basic misunderstanding here.

Setting a pin as "output" mean it'll either supply +5V ("HIGH") or 0V ("LOW"). Both those states are considered "outputs", and the pin can source or sink current in those states. When driven "LOW", the circuit does "input" current to the chip, but that's not what "input" usually means.

"Input" means you can use the pin to read the voltage applied to the pin. When connected to a PWM source, this might manifest as the pin quickly switching between "1" / "HIGH" / "+5V" and "0" / "LOW" / "0V". Normally, you would use the "input" mode to read things like switches, or potentiometers on the analog input pins.

Your desired use of "current input" pins will require you to configure the pin as "output", and then set it to "LOW", which will make it able to sink current.
> 7 votes

# Answer
The LED would glow only when the pin is configured as an OUTPUT or it would be very dim in INPUT mode. This is because INPUT mode sets the pin to a high impedance state, suitable for reading voltages and not for driving circuits requiring current.

Setting a digital pin to INPUT mode, allows you to only read voltages as 0 or 1 which correspond to 0V and 5V respectively. For example, upload the code below to your Arduino and open the serial monitor. Now, by connecting Pin 11 to GND the serial monitor should display 0, and by connecting it to 5V, it should display 1. If this doesn't work something may be wrong with the Arduino.

```
const int TESTPIN=11; //connect pin 11 to 5V and GND for testing

void setup() {

  pinMode(TESTPIN, INPUT);
  Serial.begin(9600);
}

void loop() {
  Serial.println(digitalRead(TESTPIN));
  delay(500);
}

```

However, I would recommend that you share your code and diagram before concluding a fault in the Arduino.
> 1 votes

# Answer
In your second update you described the following circuit:

simulate this circuit – Schematic created using CircuitLab

Then in code you are doing `digitalWrite(6, HIGH);`, which sets pin 6 to HIGH/1/true/5V. Pin 6 is configured as output, pin 8 as input. In this situation the LED will not light up. A pin, that is configured as input, will not draw or source current (except a very very small amount). The input pin behaves somewhat like a little capacitor to ground (so in principle nearly no current can flow). Thus no current is flowing through the circuit. No current also means, that the LED does not light up (it needs current for lighting up) and no voltage drop will happen on the circuit. The circuit will not be "completed", as you phrased it. Thus your input pin will also get HIGH/1/true/5V, which is what you then read on in the code.

When you instead change pin 8 to output (`pinMode(8, OUTPUT);`) and set it to LOW (`digitalWrite(8, LOW);`), the LED will light up, as now the voltage difference is the full 5V (from HIGH at pin 6 to LOW/ground at pin 8). If you now read the pin with `digitalRead(8)` you will just read, what you have written to it, meaning LOW/0/false/ground.

You might also have tried to use `digitalWrite()` with a pin, which is configured as `INPUT`. That does not really output anything. Instead it activates or deactivates the internal pullup resistor of the pin. As I remember, this pullup resistor is between 20 and 50 kΩ, so again you cannot get enough current to light an LED through that pin. The internal pullup resistor is then like an additional 20 to 50 kΩ resistor from the corresponding input pin to Vcc (5V in your case). If nothing else pulls on the pins value, the pullup resistor will pull the value of the input pin to HIGH/1/true/5V, so that you don't have a floating pin (see below for an explanation of that term).

---

**The next scenario: Using `analogRead()`**

Here you first tried to read an analog pin (A0), which was not connected to anything. That is called a **floating pin**. There is nothing, that gives this pin a definite value, thus it catches whatever electrical noise comes around, from the microcontroller, from other pins, from the circuit or from outside. A floating pin can change it's value rapidly and randomly, depending on the noise, which comes around. Thus you will get very different and varying values here.

Then you connected A0 to ground. That gives the pin a definite value (LOW/0/false/ground). Thus you now only read zero as value.

If you are doing the `analogRead()` with a circuit similar to the first case (with the LED between two pins) you will get a similar result as with `digitalRead()`. An analog input will also not source or draw any current (besides a very very small current). Thus you cannot "complete" a circuit to light an LED on the path.

---

> I'm trying to read an PWM signal being output by pin 6. I'm attempting to read it with pin A0.

A PWM signal is nothing else than changing rapidly between Vcc (5V in your case) and ground. The value, that you give the PWM signal via `analogWrite()`, defines the duty cycle of the signal, meaning the ratio between the HIGH and LOW portions in the signal. The function name `analogWrite()` is unfortunately very misleading, as you don't really output an analog voltage. Most Arduinos don't have the hardware to do that, so `analogWrite()` uses PWM to output a pseudo analog voltage. Devices like motors are not fast enough to react to the fast voltage change, so you can change the speed with PWM. LEDs are fast enough, but the human eye cannot see the individual on-off cycles, so you see the LED being dimmed with lower values.

But the `analogRead()` function (which uses the ADC hardware internally) is fast enough, thus you would only read a series of changes between 5V and ground, when reading a PWM signal. You could build a low pass filter, which will filter out the PWM frequency and give you a real analog voltage, which you can then read via `analogRead()`. Though keep in mind, that this makes it slower, so you cannot read fast changes with that. A low pass filter looks like this:

simulate this circuit

The values come from the come from the comment of Edgar Bonet (thanks):

> The PWM frequencies of the Uno are 977 and 490 Hz, below the cut-off of the filter you drew. Per the ADC's specification, you can safely increase R1 up to 10 kΩ, which should put the cutoff low enough to attenuate the PWM frequencies by at least 30 dB.

Though you might also want to read up the formula for the cut-off frequency. You can google terms like "RC low pass filter".

If you don't want to use extra hardware, but still want to read the PWM signal, you need to read the pulse length. For this there are multiple ways, depending on the requirements. You can use `pulseIn()`, you can use interrupts and take timestamps, you can use the capture mode of a hardware Timer.

---

> As I stated in the sketch, this exact set up was working fine yesterday. The led was on and (accurate or not) there were consistent values being printed to the serial monitor.

Unfortunately this is not possible. The pins must behave like I described above. As electronics not break and then just magically unbreak, you must have done something different. An input pin (digital or analog) will not source or draw enough current to light an LED.

---

> Now the pins only recognize zero volts and do not complete any circuits. You can't even use a simple potentiometer if you wanted.

You may have damaged something, though I cannot really say, if that is really the case or if you are just doing something wrong there. A potentiometer has to be connected like the following: The outer pins to ground and 5V respectively, the middle pin directly to the analog input. Nothing else. You might check, if that is, what you did.

---

Besides all that, you didn't really state, what you are trying to achieve. As you already acknowledged in your question, the described circuit is not typical and a strange setup. To light an LED, you would just connect it to the output pin (via the resistor) and on the other side to ground.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Using rotary encoders with pin change interrupts
I'm using an Arduino Uno and two (3-pin) rotary encoders for a project. Since the loop takes a bit long and accuracy is important, I'd like to use interrupts to read the values from the rotary encoders. Also, pins 2 and 3 are occupied so I can't use hardware interrupts.

I'm using the Rotary library (github link) for the rotary encoders and the EnableInterrupt library (github link) for external interrupts. The Rotary library includes an interrupt example, but I couldn't manage to modify it to work with pin change interrupts. This is my current state (test code):

```
#include <EnableInterrupt.h>
#include <Rotary.h>

Rotary r = Rotary(2, 3);

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

  /* Original interrupt setup:
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();
  */

  enableInterrupt(2, interruptFunction, CHANGE);
  enableInterrupt(3, interruptFunction, CHANGE);
}

void loop() {

}

void interruptFunction() {

  Serial.println("Int. called");

  unsigned char result = r.process();
  if (result == DIR_NONE) {
    // do nothing
  }
  else if (result == DIR_CW) {
    Serial.println("ClockWise");
  }
  else if (result == DIR_CCW) {
    Serial.println("CounterClockWise");
  }
}

```

Everytime I turn the encoder for one step, the interruptFunction gets called a bunch of times (about 2~4) but the r.process() call never returns a value.

My current guess is that this has something to do with the rotary encoder outputting gray code, but I'm not quite sure how my approach differs from the Rotary interrupt example using hardware interrupts.

Hope you can help!

# Answer
I too had this problem. I chased my tail in SW for hours. I was making the ISRs non-reentrant (assumed they accidentally were), I was doing SW debouncing etc. I even looked at the signal on a scope but did not see any significant bounces. I eventually added 0.1uF capacitors to the inputs and that solved all my problems with the ISR. So don't trust the encoder manufacturers, there WILL be signal bounce and your Arduino WILL detect it and throw multiple interrupts. Good luck with your project! LDP
> 1 votes

# Answer
> Everytime I turn the encoder for one step, the interruptFunction gets called a bunch of times (about 2~4)

This is due to contact bounces. You should either implement a hardware debouncing circuit (a simple R-C filter could be enough. Do not connect instead large capacitors directly in parallel to your contacts, as when the contact closes, the energy stored on the capacitor will damage over time the contacts. Using large capacitances on an input can also lead to problems when power is removed), or better a good software debouncing strategy.

For instance, when the interrupt is called the first time, disable the pin-change interrupts. Then set up a timer, which will trigger an interrupt when it expires (the time should be larger than the bounce time, usually several ms or more). Then in the timer interrupt, first put your code:

```
  unsigned char result = r.process();
  if (result == DIR_NONE) {
    // do nothing
  }
  else if (result == DIR_CW) {
    Serial.println("ClockWise");
  }
  else if (result == DIR_CCW) {
    Serial.println("CounterClockWise");
  }

```

end re-enable the pin-change interrupts.

```
  enableInterrupt(2, interruptFunction, CHANGE);
  enableInterrupt(3, interruptFunction, CHANGE);

```

> but the r.process() call never returns a value.

r.process() will ALWAYS returns a value. Maybe you did mean that it returns DIR\_NONE ?
> 1 votes

# Answer
check the library to see if it debounces the input.

if not, write your own code. usually state machine-based approaches are very resistant to switch bounces.
> 1 votes

# Answer
Code Correction 7th October - Tidy code as per comments Code Correction 7th October - proper reading of rotary encoder

Uses the Pin Change interrupts to allow increment and decrement of the 2 rotary encoders within an interrupt service routine using arduino (in my case nano) with ATMEGA328P chip. Need to add 2 x 104 (0.1uF caps) at the rotary encoder between each pin and the centre ground pin to stop the debounce, doesnt work without the capacitors added. Does not need any library. Watched the Tutorial: Pin Change Interrupts on the Arduino by makecourse which helped understand the Pin change interrupts, will help to watch this if have a different version of arduino so know what digital pins relate to what interrupts.

```
          //*******************************************  rotary encoder ************************************************************
          #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))    //shortcut way to clear a bit in a register
          #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))     //shortcut way to set a bit in a register

          #define Encoder1pin 3 //corresponds to PCINT19
          #define Encoder2pin 4 //corresponds to PCINT20
          #define Encoder3pin 5 //corresponds to PCINT21
          #define Encoder4pin 6 //corresponds to PCINT22
          #define Encoder5pin 7 //corresponds to PCINT23

          unsigned long encoderPos1 = 100;
          unsigned long oldEncPos1 = 0;
          unsigned long encoderPos2 = 100; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255
          unsigned long oldEncPos2 = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)

          volatile byte portDstatus;

          volatile bool readingEncoder1pin = 0;
          volatile bool readingEncoder2pin = 0;
          volatile bool readingEncoder3pin = 0;
          volatile bool readingEncoder4pin = 0;
          volatile bool lastreadingEncoder1pin = 0;
          volatile bool lastreadingEncoder2pin = 0;
          volatile bool lastreadingEncoder3pin = 0;
          volatile bool lastreadingEncoder4pin = 0;

          void setup() {

            Serial.begin(9600);

          //*************************************************** rotary encoder ******************************************************************************
            pinMode(Encoder1pin, INPUT);//define pin as INPUT
            digitalWrite(Encoder1pin, HIGH);//connect the internal pull-up resistor - this will yield a HIGH readout if the switch is open.
            pinMode(Encoder2pin, INPUT);
            digitalWrite(Encoder2pin, HIGH);
            pinMode(Encoder3pin, INPUT);
            digitalWrite(Encoder3pin, HIGH);
            pinMode(Encoder4pin, INPUT);
            digitalWrite(Encoder4pin, HIGH);
            pinMode(Encoder5pin, INPUT);
            digitalWrite(Encoder5pin, HIGH);

            //setting up the interrupt pins:   //I needed to set all of these otherwise the serial monitor does not read the byte correctly -
                                               // and it doesnt work.

            sbi (PCICR, PCIE2); // enable interrupt PCI2);
            sbi (PCMSK2,PCINT23); // set the interrupt control bits for pins 7-3. These bits control whether the pins can trigger the interrupt or not.
            sbi (PCMSK2, PCINT22);
            sbi (PCMSK2, PCINT21);
            sbi (PCMSK2, PCINT20);
            sbi (PCMSK2, PCINT19); // we do not want to set interrupt control for pins 0 or 1 since this is serial reading .

          //******************************************************************* LED *********************************************************************
          }

          void loop()

              {
               }

          ISR(PCINT2_vect) // Interrupt Service Routine. This code is executed when a state change occurs on a pin
          {

                portDstatus=PIND;
               readingEncoder1pin = bitRead(portDstatus,3);
               readingEncoder2pin = bitRead(portDstatus,4);
             if(lastreadingEncoder1pin == 1 && lastreadingEncoder2pin == 0 && readingEncoder1pin == 1 && readingEncoder2pin == 1)
              {
                  encoderPos1 ++;
                   lastreadingEncoder1pin = readingEncoder1pin;
                   lastreadingEncoder2pin = readingEncoder2pin;
              }

              else if(lastreadingEncoder1pin == 0 && lastreadingEncoder2pin == 1 && readingEncoder1pin == 1 && readingEncoder2pin == 1)
              {
                encoderPos1 --;
                  lastreadingEncoder1pin = readingEncoder1pin;
                  lastreadingEncoder2pin = readingEncoder2pin;;
              }
              else
                {
                   lastreadingEncoder1pin = readingEncoder1pin;
                   lastreadingEncoder2pin = readingEncoder2pin;
                }

    //  reading the second encoder:

               readingEncoder3pin = bitRead(portDstatus,5);
               readingEncoder4pin = bitRead(portDstatus,6);

             if(lastreadingEncoder3pin == 1 && lastreadingEncoder4pin == 0 && readingEncoder3pin == 1 && readingEncoder4pin == 1)
              {

                  encoderPos2 ++;
                   lastreadingEncoder3pin = readingEncoder3pin;
                   lastreadingEncoder4pin = readingEncoder4pin;
              }

              else if(lastreadingEncoder3pin == 0 && lastreadingEncoder4pin == 1  && readingEncoder3pin == 1 && readingEncoder4pin == 1)
              {
                encoderPos2 --;
                  lastreadingEncoder3pin = readingEncoder3pin;
                  lastreadingEncoder4pin = readingEncoder4pin;;
              }
              else
                {

                   lastreadingEncoder3pin = readingEncoder3pin;
                   lastreadingEncoder4pin = readingEncoder4pin;
                }
             // serial print for testing only then remove from ISR
          Serial.print(encoderPos1);
          Serial.println(encoderPos2);

             }

```
> 1 votes

# Answer
The correct solution is to use a debouncing circuit. The MC14490 is a hex debouncing circuit and is perfect for this type of application. No need to block interrupts or set timers. It's available as either SMD or thru hole.
> -1 votes

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


# Question
Title: Can BUS Shield on Arduino Leonardo - Can't init CAN
I'm hoping to get some help with this as I am unable to get the CAN to Initialize.

I have the sparkfun Can-Bus shield: https://www.sparkfun.com/products/13262

and an Arduino Leonardo board.

I'm using the following code to try to connect my 2008 Audi S6 to the Arduino board:

```
#include <Canbus.h>
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>
#include <Canbus.h>
char UserInput;
int data;
char buffer[456];  //Data will be temporarily stored to this buffer before being written to the file

//********************************Setup Loop*********************************//

void setup(){
Serial.begin(9600);
while(!Serial);
Serial.println("CAN-Bus Demo");

if(Canbus.init(CANSPEED_500))  /* Initialise MCP2515 CAN controller at the  specified speed */
  {
Serial.println("CAN Init ok");
  } else
  {
    Serial.println("Can't init CAN");
  }

  delay(1000);

Serial.println("Please choose a menu option.");
Serial.println("1.Speed");
Serial.println("2.RPM");
Serial.println("3.Throttle");
Serial.println("4.Coolant Temperature");
Serial.println("5.O2 Voltage");
Serial.println("6.MAF Sensor");

}

//********************************Main Loop*********************************//

void loop(){

while(Serial.available()){
   UserInput = Serial.read();

if (UserInput=='1'){
 data=Canbus.ecu_req(VEHICLE_SPEED, buffer);
 Serial.print("Vehicle Speed: ");
 Serial.print(data);
 Serial.println(" km/hr ");
 delay(1000);
}
else if (UserInput=='2'){
 data= Canbus.ecu_req(ENGINE_RPM, buffer);
 Serial.print("Engine RPM: ");
 Serial.print(data);
 Serial.println(" rpm ");
 delay(1000);

}
else if (UserInput=='3'){
 data= Canbus.ecu_req(THROTTLE, buffer);
 Serial.print("Throttle: ");
  Serial.print(data);
 Serial.println(" %% ");
 delay(1000);

}
else if (UserInput=='4'){
 data =Canbus.ecu_req(ENGINE_COOLANT_TEMP, buffer);
 Serial.print("Engine Coolant Temp: ");
 Serial.print(data);
 Serial.println(" degC");
 delay(1000);

}
else if (UserInput=='5'){
 data=Canbus.ecu_req(O2_VOLTAGE, buffer);
 Serial.print("O2 Voltage: ");
 Serial.print(data);
 Serial.println(" V");
 delay(1000);

}
else if (UserInput=='6'){
 data=Canbus.ecu_req(MAF_SENSOR, buffer);
 Serial.print("MAF Sensor: ");
 Serial.print(data);
 Serial.println(" g/s");
 delay(1000);

}
else
{
  Serial.println(UserInput);
  Serial.println("Not a valid input.");
  Serial.println("Please enter a valid option.");
}

}
}

```

Overall, I just can't get the CAN to initialize. I've looked online and just can't seem to find a solid solution. I've tried other libraries as well to no avail.

Please assist!

# Answer
> 1 votes
Had this problem myself. Found this fixed it

Change the following line...

```
_delay_us(10);

```

To...

```
_delay_us(50);

```

In the `MCP2515.c` file in the library

# Answer
> 1 votes
Increasing that delay in the MCP2515.c file also fixed this issue for me. I am running the sparkfun Can-Bus shield on an Arduino pro-mini, and here is my serial monitor output before the change, and after:

12:56:38.580 -\> CAN Read - Testing receival of CAN Bus message 12:56:39.556 -\> Can't init CAN 13:01:40.992 -\> CAN Read - Testing receival of CAN Bus message 13:01:42.016 -\> CAN Init ok

---
Tags: arduino-leonardo, can-bus
---


# Question
Title: cant read json data esp 32 “parseObject() failed”
> **hello I am just trying to make Youtube Subscribe Counter with led matrix 32\*8 and esp 32 and I had this problem when I trying to get subscribers to count so what is the problem and how I can fix it? \`**

  ```    //########################  YouTube Subscriber Count Display on LED MATRIX  #############################
        // Receives and displays YouTube channel statistics
        //################# LIBRARIES ################
        String version = "v1.0";       // Version of this program

    #include <WiFi.h>
    #include <WiFiClientSecure.h>
    #include <ArduinoJson.h>     // https://github.com/bblanchon/ArduinoJson
    #include <SPI.h>
    #include <Adafruit_GFX.h>
    #include <Max72xxPanel.h>    // https://github.com/markruys/arduino-Max72xxPanel
    #include <time.h>
    //################ VARIABLES ################
    // Use your own API key by signing up for a free Youtube developer account at http://www.youtube.com
    // LED Matrix Pin -> ESP32 Pin
    // Vcc            -> 3v
    // Gnd            -> Gnd
    // DIN            -> MOSI pin use results of print statement 23 maybe
    // CS             -> SS pin   use results of print statement 5 maybe
    // CLK            -> SCK pin  use results of print statement 18 maybe

    const char* channelId = "UCqTSLaEj9c4hiZkU0FfbaJA"; // See your Channel details click on your channel icon at top-right, then Settings, then Advanced
    const char* apiKey    = "A--------------Aw"; // See https://developers.google.com/youtube/v3/getting-started for an API key, you must enable it to make it work!
    const char* host      = "https://www.googleapis.com";
    unsigned long lastConnectionTime = 0;                 // Last time you connected to the server, in milliseconds
    const unsigned long  postingInterval = 10L*60L*1000L; // Delay between updates, in milliseconds, you should limit your YouTube requests per-day maximum

    //################ PROGRAM VARIABLES and OBJECTS ################
    int pinCS = 5; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
    int numberOfHorizontalDisplays = 4;
    int numberOfVerticalDisplays   = 1;
    int wait   = 35; // In milliseconds
    int spacer = 1;
    int width  = 5 + spacer; // The font width is 5 pixels
    int port   = 443;
    String time_str;

    Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

    struct channelStatistics{
      long viewCount;
      long commentCount;
      long subscriberCount;
      bool hiddenSubscriberCount;
      long videoCount;
    };

    // Change to your WiFi credentials
    const char* ssid     = "SSid";
    const char* password = "PASS";

    channelStatistics channelStats;

    void setup() {
      Serial.begin(115200); // initialize serial communications
      Serial.println("Mosi="+String(MOSI));
      Serial.println("SS="+String(SS));
      Serial.println("SCK="+String(SCK));
      StartWiFi(ssid,password);
      StartTime();

      //----------------------------------------------------------------------
      configTime(0 * 3600, 0, "pool.ntp.org", "time.nist.gov");
      matrix.setIntensity(0); // Use a value between 0 and 15 for brightness
    // Adjust the LED matrix to your own needs
    //  matrix.setPosition(0, 0, 0); // The first display is at <0, 0>
    //  matrix.setPosition(1, 1, 0); // The second display is at <1, 0>
    //  matrix.setPosition(2, 2, 0); // The third display is at <2, 0>
    //  matrix.setPosition(3, 3, 0); // And the last display is at <3, 0>
    //  ...
      matrix.setRotation(0, 1);    // The first display is position is rotated
      matrix.setRotation(1, 1);    // The first display is position is rotated
      matrix.setRotation(2, 1);    // The first display is position is rotated
      matrix.setRotation(3, 1);    // The first display is position is rotated
      lastConnectionTime = millis();
      obtain_subscriber_stats();
    }

    void loop() {
      display_message("Subs: " + String(channelStats.subscriberCount));
      time_t now = time(nullptr);
      String time = String(ctime(&now));
      time.trim();
      display_message(" on " + time);
      if (millis() - lastConnectionTime > postingInterval) { // 15-minutes
        obtain_subscriber_stats();
        lastConnectionTime = millis();
      }
    }

    //################ PROGRAM FUNCTIONS ################

    void display_message(String message){ // Scroll the image left
      matrix.fillScreen(LOW);
      for ( int i = 0 ; i < width * message.length() + matrix.width() - 1 - spacer; i++ ) {
        int letter = i / width;
        int x = (matrix.width() - 1) - i % width;
        int y = (matrix.height() - 8) / 2; // center the text vertically
        while ( x + width - spacer >= 0 && letter >= 0 ) {
          if (letter < message.length()) matrix.drawChar(x, y, message[letter], HIGH, LOW, 1); // HIGH means foreground on, LOW means background off, LOW< HIGH inverts the display
          letter--;
          x -= width;
        }
        matrix.write(); // Send bitmap to display
        delay(wait);
      }
    }

    void obtain_subscriber_stats() {
      String command = "https://www.googleapis.com/youtube/v3/channels?part=statistics&id=" + String(channelId);
      String response = GetRequestFromYoutube(command);
      StaticJsonBuffer <200> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject(response); // Parse JSON
      if (!root.success()) {
        Serial.println(F("jsonBuffer.parseObject() failed"));
      }
      else
      {

        JsonObject& current                = root["items"][0]["statistics"];
        long subscriberCount               = current["subscriberCount"];
        long viewCount                     = current["viewCount"];
        long commentCount                  = current["commentCount"];
        long hiddenSubscriberCount         = current["hiddenSubscriberCount"];
        long videoCount                    = current["videoCount"];
        channelStats.viewCount             = viewCount;
        channelStats.subscriberCount       = subscriberCount;
        channelStats.commentCount          = commentCount;
        channelStats.hiddenSubscriberCount = hiddenSubscriberCount;
        channelStats.videoCount            = videoCount;

      }
      Serial.println("      View Count = " + String(channelStats.viewCount));
      Serial.println("Subscriber Count = " + String(channelStats.subscriberCount));
        Serial.println(GetRequestFromYoutube(command));
        Serial.println(response);
      //  Serial.println(jsonBuffer.parseObject(response));

    }

    String GetRequestFromYoutube(String request) {
      String headers, body = "";
      bool Headers    = false;
      bool currentLineIsBlank = true;
      int  MessageLength = 1000;
      // Connect with youtube api over ssl
      WiFiClientSecure client;
      if (client.connect(host, port)) {
        Serial.println(".... connected to server");
        char c;
        int ch_count=0;
        request += "&key=" + String(apiKey);
        request = "GET " + request;
        Serial.println(request);
        client.println(request);
        int now   = millis();
        while (millis()-now < 1500) {
          while (client.available()) {
            char c = client.read();
            if(!Headers){
              if (currentLineIsBlank && c == '\n') {
                Headers = true;
              }
              else{
                headers = headers + c;
              }
            } else {
              if (ch_count < MessageLength)  {
                body = body+c;
                ch_count++;
              }
            }
            if (c == '\n') {
              currentLineIsBlank = true;
            } else if (c != '\r') {
              currentLineIsBlank = false;
            }
          }
        }
      }
      return body;
    }

    ////////////// WiFi, Time and Date Functions /////////////////
    int StartWiFi(const char* ssid, const char* password) {
      int connAttempts = 0;
      Serial.print(F("\r\nConnecting to: ")); Serial.println(String(ssid));
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED ) {
        delay(500); Serial.print(".");
        if (connAttempts > 20) {
          Serial.println("\nFailed to connect to a Wi-Fi network");
          return -5;
        }
        connAttempts++;
      }
      Serial.print(F("WiFi connected at: "));
      Serial.println(WiFi.localIP());
      return 1;
    }

    void StartTime(){
      configTime(0, 0, "0.uk.pool.ntp.org", "time.nist.gov");
      setenv("TZ", "GMT0BST,M3.5.0/01,M10.5.0/02",1); // Change for your location
      UpdateLocalTime();
    }

    void UpdateLocalTime(){
      struct tm timeinfo;
      while (!getLocalTime(&timeinfo)){
        Serial.println("Failed to obtain time");
      }
      //See http://www.cplusplus.com/reference/ctime/strftime/
      Serial.println(&timeinfo, "%a %b %d %Y   %H:%M:%S"); // Displays: Saturday, June 24 2017 14:05:49
      char output[50];
      strftime(output, 50, "%a %d-%b-%y  (%H:%M:%S)", &timeinfo);
      time_str = output;
    }
    ```

# Answer
> 0 votes
The documentation for ArduinoJson 5 lists the reasons why `parseObject()` may return `false`:

1. The input is not a valid JSON
2. The `StaticJsonBuffer` is too small
3. The `StaticJsonBuffer` is too big (stack overflow)
4. The `DynamicJsonBuffer` fails to allocate memory
5. You called `parseObject()` instead of `parseArray()`
6. The nesting limit is too low

A glance at your code suggests that the problem is number 2: the `StaticJsonBuffer` is too small. Indeed, I don't know what the input looks like, but 200 bytes is probably too small to store the result.

You can use the ArduinoJson Assistant to compute the required capacity for the `JsonBuffer`. Don't forget to switch to a `DynamicJsonBuffer` if it becomes bigger than 4 KB.

Lastly, I really recommend that you switch to ArduinoJson 6 because it offers more features, better performance, better memory usage, and better error reporting, all with the same code size and portability.

---
Tags: c++, esp32, json, java
---


# Question
Title: How to send messages to multiple numbers using Arduino uno & SIM800 module?
I am using following code to send message using Arduino Uno & SIM800 module. But I need to send same message on multiple numbers then what changes should I make in my code.

```
const int buttonPin = 8;   // Main gate sensor 1
const int buttonPin1 = 7;  // Main gate sensor 2
const int buttonPin2 = 9;  // Store room sensor 1
const int buttonPin3 = 10; // Store room sensor 2

bool i = false;
bool j = false;
bool k = false;
bool l = false;

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

  pinMode(buttonPin, INPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);

  digitalWrite(buttonPin, LOW);
  digitalWrite(buttonPin1, LOW);
  digitalWrite(buttonPin2, LOW);
  digitalWrite(buttonPin3, LOW);

  delay(1000);
}
void loop()

{
  sensor1();
  sensor2();
}
  void sensor1()
  {
  if (digitalRead(buttonPin1)== LOW && digitalRead(buttonPin) == HIGH  && i == false)

  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91...................");
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Main Gate is Closed");
    Serial.write(0x1A);
    delay(1000);
    i = true;
    j = false;

  }

  if (digitalRead(buttonPin)== LOW && digitalRead(buttonPin1) == HIGH &&  j == false)
  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91........................");
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Main Gate is open");
    Serial.write(0x1A);
    delay(1000);
    j = true;
    i = false;
  }
  }
  void sensor2()
  {
  if (digitalRead(buttonPin2) == HIGH && digitalRead(buttonPin3)==LOW && k == false)
  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91....................");
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Store room is Closed");
    Serial.write(0x1A);
    delay(1000);
    k = true;
    l = false;
  }
  if (digitalRead(buttonPin3) == HIGH &&digitalRead(buttonPin2)== LOW && l == false)
  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91....................");
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Store room is Open");
    Serial.write(0x1A);
    delay(1000);
    l = true;
    k = false;
  }
}

```

# Answer
> 1 votes
@nilesh just add some delay between two massege

I modified your code check it

```
const int Main1 = 8;
const int Main2 = 9;
const int Store1 = 7;
const int Store2 = 10;
bool i = false;
bool j = false;
bool k = false;
bool l = false;

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

  pinMode(Main1, INPUT);
  pinMode(Main2, INPUT);
  pinMode(Store1, INPUT);
  pinMode(Store2, INPUT);

  digitalWrite(Main1, LOW);
  digitalWrite(Main2, LOW);
  digitalWrite(Store1, LOW);
  digitalWrite(Store2, LOW);

  delay(1000);
}
void loop()

{
  sensor1();
  sensor2();
}
void sensor1()
{
  if (digitalRead(Main1) == HIGH && digitalRead(Main2) == LOW && i == false)

  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91-----------");// first number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Main gate closed");
    Serial.write(0x1A);
    delay(5000);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91-----------");// Second number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Main gate closed");
    Serial.write(0x1A);
    delay(1000);
    i = true;
    j = false;

  }
  if (digitalRead(Main2) == HIGH && digitalRead(Main1) == LOW && j == false)
  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91---------------");//first number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Main gate Open");
    Serial.write(0x1A);
    delay(5000);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91--------------"); second number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Main gate Open");
    Serial.write(0x1A);
    delay(1000);
    j = true;
    i = false;
  }
}
void sensor2()
{
  if (digitalRead(Store1) == HIGH && digitalRead(Store2) == LOW && k == false)
  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
   Serial.print("+91-----------");// first number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Store room is closed");
    Serial.write(0x1A);
    delay(10000);
    Serial.print("AT+CMGS=\"");
    Serial.print("+91-----------");// second number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Store room is Closed");
    Serial.write(0x1A);
    delay(1000);
    k = true;
    l = false;
  }
  if (digitalRead(Store2) == HIGH && digitalRead(Store1) == LOW && l == false)
  {
    Serial.println("OK");
    delay(1000);
    Serial.print("AT+CMGF=1\r\n");
    delay(500);
    Serial.print("AT+CMGS=\"");
   Serial.print("+91-----------");// first number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Store room is Open");
    Serial.write(0x1A);
    delay(5000);
    Serial.print("AT+CMGS=\"");
   Serial.print("+91-----------");// Second number
    Serial.print("\"\r\n");
    delay(2000);
    Serial.print("Store room is Open");
    Serial.write(0x1A);
    delay(1000);
    l = true;
    k = false;
  }
}

```

thanks

bhupendra.sinkar727@gmail.com

# Answer
> 1 votes
I have same question but minor different.

sim.println("AT+CMGS="+91xxxxxxxxxx"\r");

i dont want to write this. i want to write mobile number on serial monitor in arduino and on that number, i want to send message. how can i do?

# Answer
> -1 votes
Try out this one. Here, I made the code for two number. Just simply add a new function for every new number. I hope it will help you.

```
const int buttonPin = 8;   // Main gate sensor 1
const int buttonPin1 = 7;  // Main gate sensor 2
const int buttonPin2 = 9;  // Store room sensor 1
const int buttonPin3 = 10; // Store room sensor 2

bool i = false;
bool j = false;
bool k = false;
bool l = false;

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

  pinMode(buttonPin, INPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);

  digitalWrite(buttonPin, LOW);
  digitalWrite(buttonPin1, LOW);
  digitalWrite(buttonPin2, LOW);
  digitalWrite(buttonPin3, LOW);

  delay(1000);
}
void loop()

{
  sensor1();
  sensor2();
}

void sensor1()
{
  if (digitalRead(buttonPin1)== LOW && digitalRead(buttonPin) == HIGH  && i == false)
  {
    numOneGateClose();
    numTwoGateClose();
    i = true;
    j = false;
  }

  if (digitalRead(buttonPin)== LOW && digitalRead(buttonPin1) == HIGH &&  j == false)
  {
   numOneGateOpen();
   numTwoGateOpen();
    j = true;
    i = false;
  }
}

void sensor2()
{
  if (digitalRead(buttonPin2) == HIGH && digitalRead(buttonPin3)==LOW && k == false)
  {
    numOneRoomClose();
    numTwoRoomClose();
    k = true;
    l = false;
  }

  if (digitalRead(buttonPin3) == HIGH &&digitalRead(buttonPin2)== LOW && l == false)
  {
    numOneRoomOpen();
    numTwoRoomOpen();
    l = true;
    k = false;
  }
}

void numOneGateClose()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91...................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is Closed");
  Serial.write(0x1A);
  delay(1000);
}

void numTwoGateClose()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91...................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is Closed");
  Serial.write(0x1A);
  delay(1000);
}

void numOneGateOpen()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91........................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is open");
  Serial.write(0x1A);
  delay(1000);
}

void numTwoGateOpen()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91........................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is open");
  Serial.write(0x1A);
  delay(1000);
}

void numOneRoomClose()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91...................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is Closed");
  Serial.write(0x1A);
  delay(1000);
}

void numTwoRoomClose()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91...................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is Closed");
  Serial.write(0x1A);
  delay(1000);
}

void numOneRoomOpen()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91........................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is open");
  Serial.write(0x1A);
  delay(1000);
}

void numTwoRoomOpen()
{
  Serial.println("OK");
  delay(1000);
  Serial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.print("AT+CMGS=\"");
  Serial.print("+91........................");
  Serial.print("\"\r\n");
  delay(2000);
  Serial.print("Main Gate is open");
  Serial.write(0x1A);
  delay(1000);
}

```

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


# Question
Title: OLED 'SH1106_WHITE' was not declared in this scope
I was following FREE Functions to draw graphs on OLED displays on YouTube but mine OLED display doesn't support Adafruit\_SSD1306 library,but it works on Adafruit\_SH1106.h driver.

The code that is shared with YouTube video

```
/*

  This program provides functions to draw:
  1. horizontal bar graph
  2. vertical bar graph
  3. dial
  4. cartesian graph

  It requires an microcrontrioller Arduino, teensy and a 0.96 dispaly (1306 driver chip)

  display. sources
  https://www.amazon.com/Diymall-Yellow-Arduino-display.-Raspberry/dp/B00O2LLT30/ref=pd_lpo_vtph_147_bs_t_1?_encoding=UTF8&psc=1&refRID=BQAPE07SVJQNDKEVMTQZ
  https://www.amazon.com/dp/B06XRCQZRX/ref=sspa_dk_detail_0?psc=1&pd_rd_i=B06XRCQZRX&pd_rd_wg=aGuhK&pd_rd_r=1WJPXAG68XFSADGDPNZR&pd_rd_w=DAAsB

  Adafruit libraries
  https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip
  https://github.com/adafruit/Adafruit_SSD1306

  Revisions
  rev     date        author      description
  1       12-5-2017   kasprzak    initial creation

  Pin settings

  Arduino   device
  5V        Vin
  GND       GND
  A0        read an input voltage from a pot across Vcc and Gnd (just for demo purposes)
  A1
  A2
  A3
  A4        SDA on the display. or use dedicated pin on board if provided
  A5        SCL on the display. use dedicated pin on board if provided
  1
  2
  3
  4
  5
  6
  7
  8
  9
  10
  11
  12
  13

*/

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define READ_PIN            A0
#define OLED_RESET          A4
#define LOGO16_GLCD_HEIGHT  16
#define LOGO16_GLCD_WIDTH   16

// create what ever variables you need
double volts;
double bvolts;
double x, y;

// these are a required variables for the graphing functions
bool Redraw1 = true;
bool Redraw2 = true;
bool Redraw3 = true;
bool Redraw4 = true;
double ox , oy ;

// create the display object
Adafruit_SSD1306 display(OLED_RESET);

void setup() {

  Serial.begin(9600);

  // initialize the display
  // note you may have to change the address
  // the most common are 0X3C and 0X3D

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  // if you distribute your code, the adafruit license requires you show their splash screen
  // otherwise clear the video buffer memory then display
  display.display();
  //delay(2000);
  display.clearDisplay();
  display.display();

  // establish whatever pin reads you need
  pinMode(A0, INPUT);

}

unsigned long OldTime;
unsigned long counter;

  void loop(void) {

  // read some values and convert to volts
  bvolts = analogRead(A0);
  volts = (bvolts  / 204.6 ) ;

  // draw any of the following, sorry for the crazy long arguement lists
  // note 0.96 isn't very big, so you can't show many graphs at the same time
  // also colors are hard coded
  // the display i use draws text at the top in yellow--we'll use that for drawing the title

  // call one of these functions
  DrawBarChartV(display, bvolts, 25,  60, 40, 40, 0, 1024 , 256, 0, "A0 (bits)", Redraw1);
  //  DrawBarChartH(display, volts, 10, 45, 100, 20, 0, 5, 1, 0, "A0 (volts)", Redraw2);
  //  DrawDial(display, volts, 65, 50, 25, 0, 5 , 1, 0, 200, "A0 (volts)", Redraw3);

  // for multiple graphs uncomment the next 2 lines
  //  DrawBarChartV(display, bvolts, 5,  60, 10, 40, 0, 1024 , 256, 0, "A0 (bits/volts)", Redraw1);
  //  DrawDial(display, volts, 90, 50, 25, 0, 5 , 1, 0, 200, "A0 (bits/volts)", Redraw3);

  // or show a cartesian style graph to plot values over time (or whatever)

    DrawCGraph(display, x++, bvolts, 30, 50, 75, 30, 0, 100, 25, 0, 1024, 512, 0, "Bits vs Seconds", Redraw4);
    if (x > 100) {
    while (1) {}
    }

  delay(1000);

  }

  /*
  This method will draw a vertical bar graph for single input
  it has a rather large arguement list and is as follows

  &d to pass the display object, mainly used if multiple displays are connected to the MCU
  curval = date to graph (must be between loval and hival)
  x = position of bar graph (lower left of bar)
  y = position of bar (lower left of bar
  w = width of bar graph
  h =  height of bar graph (does not need to be the same as the max scale)
  loval = lower value of the scale (can be negative)
  hival = upper value of the scale
  inc = scale division between loval and hival
  dig = format control to set number of digits to display. (not includeing the decimal)
  label = bottom lable text for the graph
  redraw = flag to redraw display. only on first pass (to reduce flickering)

*/

void DrawBarChartV(Adafruit_SSD1306 &d, double curval, double x , double y , double w, double h , double loval , double hival , double inc , double dig, String label, bool &Redraw)
{
  double stepval, my, level, i, data;

  if (Redraw) {
    Redraw = false;
    d.fillRect(0, 0,  127 , 14, SSD1306_WHITE);
    d.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
    d.setTextSize(1);
    d.setCursor(2, 4);
    d.println(label);
    // step val basically scales the hival and low val to the height
    // deducting a small value to eliminate round off errors
    // this val may need to be adjusted
    stepval = ( inc) * (double (h) / (double (hival - loval))) - .001;
    for (i = 0; i <= h; i += stepval) {
      my =  y - h + i;
      d.drawFastHLine(x + w + 1, my,  5, SSD1306_WHITE);
      // draw lables
      d.setTextSize(1);
      d.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
      d.setCursor(x + w + 12, my - 3 );
      data = hival - ( i * (inc / stepval));
      d.print(data, dig);
    }
  }
  // compute level of bar graph that is scaled to the  height and the hi and low vals
  // this is needed to accompdate for +/- range
  level = (h * (((curval - loval) / (hival - loval))));
  // draw the bar graph
  // write a upper and lower bar to minimize flicker cause by blanking out bar and redraw on update
  d.drawRect(x, y - h, w, h, SSD1306_WHITE);
  d.fillRect(x, y - h, w, h - level,  SSD1306_BLACK);
  d.drawRect(x, y - h, w, h, SSD1306_WHITE);
  d.fillRect(x, y - level, w,  level, SSD1306_WHITE);
  // up until now print sends data to a video buffer NOT the screen
  // this call sends the data to the screen
  d.display();

}

/*
  This method will draw a horizontal bar graph for single input
  it has a rather large arguement list and is as follows

  &display to pass the display object, mainly used if multiple displays are connected to the MCU
  x = position of bar graph (upper left of bar)
  curval = date to graph (must be between loval and hival)
  y = position of bar (upper left of bar (add some vale to leave room for label)
  w = width of bar graph (does not need to be the same as the max scale)
  h =  height of bar graph
  loval = lower value of the scale (can be negative)
  hival = upper value of the scale
  inc = scale division between loval and hival
  dig = format control to set number of digits to display. (not includeing the decimal)
  label = bottom lable text for the graph
  redraw = flag to redraw display. only on first pass (to reduce flickering)
*/

void DrawBarChartH(Adafruit_SSD1306 &d, double curval, double x , double y , double w, double h , double loval , double hival , double inc , double dig, String label, bool &Redraw)
{
  double stepval, mx, level, i, data;

  if (Redraw) {
    Redraw = false;
    d.fillRect(0, 0,  127 , 16, SSD1306_WHITE);
    d.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
    d.setTextSize(1);
    d.setCursor(2, 4);
    d.println(label);
    // step val basically scales the hival and low val to the width
    stepval =  inc * (double (w) / (double (hival - loval))) - .00001;
    // draw the text
    for (i = 0; i <= w; i += stepval) {
      d.drawFastVLine(i + x , y ,  5, SSD1306_WHITE);
      // draw lables
      d.setTextSize(1);
      d.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
      d.setCursor(i + x , y + 10);
      // addling a small value to eliminate round off errors
      // this val may need to be adjusted
      data =  ( i * (inc / stepval)) + loval + 0.00001;
      d.print(data, dig);
    }
  }
  // compute level of bar graph that is scaled to the width and the hi and low vals
  // this is needed to accompdate for +/- range capability
  // draw the bar graph
  // write a upper and lower bar to minimize flicker cause by blanking out bar and redraw on update
  level = (w * (((curval - loval) / (hival - loval))));
  d.fillRect(x + level, y - h, w - level, h,  SSD1306_BLACK);
  d.drawRect(x, y - h, w,  h, SSD1306_WHITE);
  d.fillRect(x, y - h, level,  h, SSD1306_WHITE);
  // up until now print sends data to a video buffer NOT the screen
  // this call sends the data to the screen
  d.display();

}

/*
  This method will draw a dial-type graph for single input
  it has a rather large arguement list and is as follows

  &display to pass the display object, mainly used if multiple displays are connected to the MCU
  curval = date to graph (must be between loval and hival)
  cx = center position of dial
  cy = center position of dial
  r = radius of the dial
  loval = lower value of the scale (can be negative)
  hival = upper value of the scale
  inc = scale division between loval and hival
  sa = sweep angle for the dials scale
  dig = format control to set number of digits to display. (not includeing the decimal)
  label = bottom lable text for the graph
  redraw = flag to redraw display. only on first pass (to reduce flickering)
*/

void DrawDial(Adafruit_SSD1306 &d, double curval, int cx, int cy, int r, double loval , double hival , double inc, double dig, double sa, String label, bool &Redraw) {

  double ix, iy, ox, oy, tx, ty, lx, rx, ly, ry, i, Offset, stepval, data, angle;
  double degtorad = .0174532778;
  static double px = cx, py = cy, pix = cx, piy = cy, plx = cx, ply = cy, prx = cx, pry = cy;

  if (Redraw) {
    Redraw = false;
    // draw the dial only one time--this will minimize flicker
    d.fillRect(0, 0,  127 , 16, SSD1306_WHITE);
    d.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
    d.setTextSize(1);
    d.setCursor(2, 4);
    d.println(label);
    // center the scale about the vertical axis--and use this to offset the needle, and scale text
    Offset = (270 +  sa / 2) * degtorad;
    // find hte scale step value based on the hival low val and the scale sweep angle
    // deducting a small value to eliminate round off errors
    // this val may need to be adjusted
    stepval = ( inc) * (double (sa) / (double (hival - loval))) + .00;
    // draw the scale and numbers
    // note draw this each time to repaint where the needle was
    for (i = 0; i <= sa; i += stepval) {
      angle = ( i  * degtorad);
      angle = Offset - angle ;
      ox =  (r - 2) * cos(angle) + cx;
      oy =  (r - 2) * sin(angle) + cy;
      ix =  (r - 10) * cos(angle) + cx;
      iy =  (r - 10) * sin(angle) + cy;
      tx =  (r + 10) * cos(angle) + cx + 8;
      ty =  (r + 10) * sin(angle) + cy;
      d.drawLine(ox, oy, ix, iy, SSD1306_WHITE);
      d.setTextSize(1);
      d.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
      d.setCursor(tx - 10, ty );
      data = hival - ( i * (inc / stepval)) ;
      d.println(data, dig);
    }
    for (i = 0; i <= sa; i ++) {
      angle = ( i  * degtorad);
      angle = Offset - angle ;
      ox =  (r - 2) * cos(angle) + cx;
      oy =  (r - 2) * sin(angle) + cy;
      d.drawPixel(ox, oy, SSD1306_WHITE);
    }
  }
  // compute and draw the needle
  angle = (sa * (1 - (((curval - loval) / (hival - loval)))));
  angle = angle * degtorad;
  angle = Offset - angle  ;
  ix =  (r - 10) * cos(angle) + cx;
  iy =  (r - 10) * sin(angle) + cy;
  // draw a triangle for the needle (compute and store 3 vertiticies)
  lx =  2 * cos(angle - 90 * degtorad) + cx;
  ly =  2 * sin(angle - 90 * degtorad) + cy;
  rx =  2 * cos(angle + 90 * degtorad) + cx;
  ry =  2 * sin(angle + 90 * degtorad) + cy;

  // blank out the old needle
  d.fillTriangle (pix, piy, plx, ply, prx, pry, SSD1306_BLACK);

  // then draw the new needle
  d.fillTriangle (ix, iy, lx, ly, rx, ry, SSD1306_WHITE);

  // draw a cute little dial center
  d.fillCircle(cx, cy, 3, SSD1306_WHITE);

  //save all current to old so the previous dial can be hidden
  pix = ix;
  piy = iy;
  plx = lx;
  ply = ly;
  prx = rx;
  pry = ry;
  // up until now print sends data to a video buffer NOT the screen
  // this call sends the data to the screen
  d.display();

}

/*

  function to draw a cartesian coordinate system and plot whatever data you want
  just pass x and y and the graph will be drawn huge arguement list

  &display to pass the display object, mainly used if multiple displays are connected to the MCU
  x = x data point
  y = y datapont
  gx = x graph location (lower left)
  gy = y graph location (lower left)
  w = width of graph
  h = height of graph
  xlo = lower bound of x axis
  xhi = upper bound of x asis
  xinc = division of x axis (distance not count)
  ylo = lower bound of y axis
  yhi = upper bound of y asis
  yinc = division of y axis (distance not count)
  title = title of graph
  &redraw = flag to redraw graph on fist call only

*/

void DrawCGraph(Adafruit_SSD1306 &d, double x, double y, double gx, double gy, double w, double h, double xlo, double xhi, double xinc, double ylo, double yhi, double yinc, double dig, String title, boolean &Redraw) {

  double i;
  double temp;
  int rot, newrot;

  if (Redraw == true) {
    Redraw = false;
    d.fillRect(0, 0,  127 , 16, SSD1306_WHITE);
    d.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
    d.setTextSize(1);
    d.setCursor(2, 4);
    d.println(title);
    ox = (x - xlo) * ( w) / (xhi - xlo) + gx;
    oy = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
    // draw y scale
    d.setTextSize(1);
    d.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
    for ( i = ylo; i <= yhi; i += yinc) {
      // compute the transform
      // note my transform funcition is the same as the map function, except the map uses long and we need doubles
      temp =  (i - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
      if (i == 0) {
        d.drawFastHLine(gx - 3, temp, w + 3, SSD1306_WHITE);
      }
      else {
        d.drawFastHLine(gx - 3, temp, 3, SSD1306_WHITE);
      }
      d.setCursor(gx - 27, temp - 3);
      d.println(i, dig);
    }
    // draw x scale
    for (i = xlo; i <= xhi; i += xinc) {
      // compute the transform
      d.setTextSize(1);
      d.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
      temp =  (i - xlo) * ( w) / (xhi - xlo) + gx;
      if (i == 0) {
        d.drawFastVLine(temp, gy - h, h + 3, SSD1306_WHITE);
      }
      else {
        d.drawFastVLine(temp, gy, 3, SSD1306_WHITE);
      }
      d.setCursor(temp, gy + 6);
      d.println(i, dig);
    }
  }

  // graph drawn now plot the data
  // the entire plotting code are these few lines...

  x =  (x - xlo) * ( w) / (xhi - xlo) + gx;
  y =  (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
  d.drawLine(ox, oy, x, y, SSD1306_WHITE);
  d.drawLine(ox, oy - 1, x, y - 1, SSD1306_WHITE);
  ox = x;
  oy = y;

  // up until now print sends data to a video buffer NOT the screen
  // this call sends the data to the screen
  d.display();

}

/////////////////////////////////////////////////////////

```

For my purpose of running this project in my OLED I replaced all SSD1306 keyword with SH1106. Except this project every other projects works on this OLED by replacing SSD1306 keyword with SH1106.

Getting this error in Ardunio IDE 'SH1106\_WHITE' was not declared in this scope

```
Arduino: 1.8.13 Hourly Build 2020/04/21 12:25 (Linux), Board: "Arduino Uno"

/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino: In function 'void DrawBarChartV(Adafruit_SH1106&, double, double, double, double, double, double, double, double, double, String, bool&)':
sketch_oct07a:162:33: error: 'SH1106_WHITE' was not declared in this scope
     d.fillRect(0, 0,  127 , 14, SH1106_WHITE);
                                 ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:162:33: note: suggested alternative: 'SH1106_LCDWIDTH'
     d.fillRect(0, 0,  127 , 14, SH1106_WHITE);
                                 ^~~~~~~~~~~~
                                 SH1106_LCDWIDTH
sketch_oct07a:163:20: error: 'SH1106_BLACK' was not declared in this scope
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:163:20: note: suggested alternative: 'SH1106_128_64'
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
                    SH1106_128_64
sketch_oct07a:187:30: error: 'SH1106_WHITE' was not declared in this scope
   d.drawRect(x, y - h, w, h, SH1106_WHITE);
                              ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:187:30: note: suggested alternative: 'SH1106_LCDWIDTH'
   d.drawRect(x, y - h, w, h, SH1106_WHITE);
                              ^~~~~~~~~~~~
                              SH1106_LCDWIDTH
sketch_oct07a:188:39: error: 'SH1106_BLACK' was not declared in this scope
   d.fillRect(x, y - h, w, h - level,  SH1106_BLACK);
                                       ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:188:39: note: suggested alternative: 'SH1106_128_64'
   d.fillRect(x, y - h, w, h - level,  SH1106_BLACK);
                                       ^~~~~~~~~~~~
                                       SH1106_128_64
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino: In function 'void DrawBarChartH(Adafruit_SH1106&, double, double, double, double, double, double, double, double, double, String, bool&)':
sketch_oct07a:221:33: error: 'SH1106_WHITE' was not declared in this scope
     d.fillRect(0, 0,  127 , 16, SH1106_WHITE);
                                 ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:221:33: note: suggested alternative: 'SH1106_LCDWIDTH'
     d.fillRect(0, 0,  127 , 16, SH1106_WHITE);
                                 ^~~~~~~~~~~~
                                 SH1106_LCDWIDTH
sketch_oct07a:222:20: error: 'SH1106_BLACK' was not declared in this scope
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:222:20: note: suggested alternative: 'SH1106_128_64'
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
                    SH1106_128_64
sketch_oct07a:246:47: error: 'SH1106_BLACK' was not declared in this scope
   d.fillRect(x + level, y - h, w - level, h,  SH1106_BLACK);
                                               ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:246:47: note: suggested alternative: 'SH1106_128_64'
   d.fillRect(x + level, y - h, w - level, h,  SH1106_BLACK);
                                               ^~~~~~~~~~~~
                                               SH1106_128_64
sketch_oct07a:247:31: error: 'SH1106_WHITE' was not declared in this scope
   d.drawRect(x, y - h, w,  h, SH1106_WHITE);
                               ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:247:31: note: suggested alternative: 'SH1106_LCDWIDTH'
   d.drawRect(x, y - h, w,  h, SH1106_WHITE);
                               ^~~~~~~~~~~~
                               SH1106_LCDWIDTH
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino: In function 'void DrawDial(Adafruit_SH1106&, double, int, int, int, double, double, double, double, double, String, bool&)':
sketch_oct07a:283:33: error: 'SH1106_WHITE' was not declared in this scope
     d.fillRect(0, 0,  127 , 16, SH1106_WHITE);
                                 ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:283:33: note: suggested alternative: 'SH1106_LCDWIDTH'
     d.fillRect(0, 0,  127 , 16, SH1106_WHITE);
                                 ^~~~~~~~~~~~
                                 SH1106_LCDWIDTH
sketch_oct07a:284:20: error: 'SH1106_BLACK' was not declared in this scope
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:284:20: note: suggested alternative: 'SH1106_128_64'
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
                    SH1106_128_64
sketch_oct07a:333:49: error: 'SH1106_BLACK' was not declared in this scope
   d.fillTriangle (pix, piy, plx, ply, prx, pry, SH1106_BLACK);
                                                 ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:333:49: note: suggested alternative: 'SH1106_128_64'
   d.fillTriangle (pix, piy, plx, ply, prx, pry, SH1106_BLACK);
                                                 ^~~~~~~~~~~~
                                                 SH1106_128_64
sketch_oct07a:336:43: error: 'SH1106_WHITE' was not declared in this scope
   d.fillTriangle (ix, iy, lx, ly, rx, ry, SH1106_WHITE);
                                           ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:336:43: note: suggested alternative: 'SH1106_LCDWIDTH'
   d.fillTriangle (ix, iy, lx, ly, rx, ry, SH1106_WHITE);
                                           ^~~~~~~~~~~~
                                           SH1106_LCDWIDTH
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino: In function 'void DrawCGraph(Adafruit_SH1106&, double, double, double, double, double, double, double, double, double, double, double, double, double, String, boolean&)':
sketch_oct07a:388:33: error: 'SH1106_WHITE' was not declared in this scope
     d.fillRect(0, 0,  127 , 16, SH1106_WHITE);
                                 ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:388:33: note: suggested alternative: 'SH1106_LCDWIDTH'
     d.fillRect(0, 0,  127 , 16, SH1106_WHITE);
                                 ^~~~~~~~~~~~
                                 SH1106_LCDWIDTH
sketch_oct07a:389:20: error: 'SH1106_BLACK' was not declared in this scope
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:389:20: note: suggested alternative: 'SH1106_128_64'
     d.setTextColor(SH1106_BLACK, SH1106_WHITE);
                    ^~~~~~~~~~~~
                    SH1106_128_64
sketch_oct07a:433:28: error: 'SH1106_WHITE' was not declared in this scope
   d.drawLine(ox, oy, x, y, SH1106_WHITE);
                            ^~~~~~~~~~~~
/tmp/arduino_modified_sketch_953644/sketch_oct07a.ino:433:28: note: suggested alternative: 'SH1106_LCDWIDTH'
   d.drawLine(ox, oy, x, y, SH1106_WHITE);
                            ^~~~~~~~~~~~
                            SH1106_LCDWIDTH
exit status 1
'SH1106_WHITE' was not declared in this scope

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

I am new to this field. Any help will be appreciated.

# Answer
> 2 votes
In the Adafruit\_SH1106.h header file, `SH1106_WHITE` and `SH1106_BLACK` are defined simply as `WHITE` and `BLACK` respectively. So instead of writing `SH1106_WHITE` try replacing it `WHITE` and `SH1106_BLACK` as `BLACK` respectively.

Eg:- `fillRect(0, 0, 127 , 14, WHITE);`

---
Tags: arduino-uno, display, oled
---


title: Is this LED Strip Schematic correct?

text:
# Question
Title: Is this LED Strip Schematic correct?
I am trying to simulate a 12V LED strip as per this tutorial. However the schematic I tried to make on EasyEDA looks quite different from the images on the website. I wanted to know if what I did is correct.

# Answer
> 1 votes
Schematic and wiring diagram are not the same. They seem to use different RGB LEDs. The wiring diagram has **common anode** RGB LEDs, while your schematic uses a **common cathode** RGB LED. The difference is, which side of the LED gets switched.

In the common anode configuration, all anodes (positive lead) of the individual color LEDs are connected together, while the cathodes (negative leads) are brought out, so that you can switch them via the MOSFETs. That means, that the MOSTFETs are connected between the strips color component pins and ground.

In the common cathode configuration, all cathodes (negative lead) of the individual color LEDs are connected together, while the anodes (positive leads) are brought out for you to switch them. In this case, the MOSFETs are connected between the strips color component pins and Vcc.

---

Besides that, you should be careful with providing 12V at Vin of an Arduino Uno. While it is possible, you can very fast get the linear voltage regulator to overheat, when providing 12V. It dissipates the excess voltage (so 7V, to get it to 5V down) as heat. The voltage regulator is not cooled, so you might run into this issue, with the wiring diagram. It depends on your much current you draw from the regulator.

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


title: DIY Arduino with USB port

text:
# Question
Title: DIY Arduino with USB port
I am planing on making Arduino from scratch. I found many examples on internet, but they all need another Arduino for programming. How can I make Arduino with USB interface for programming and serial data transfer? Would I need something called FTDI? Basically I want same Arduino you can buy, just build it from separate parts.

# Answer
There are two critical things that make an "Arduino". There is the hardware, and there is the bootloader.

The hardware is nothing special. It's just an MCU and the required minimal support hardware. What really makes it an Arduino is the bootloader which allows it to be programmed over the serial connection (via USB usually).

Without that bootloader the only way to program the MCU is over the hardware programming interface (typically ICSP for an AVR MCU), and for that you need some form of hardware programmer.

And of course that means the only way to put the bootloader onto the chip is to use a hardware programmer.

So you have two options:

1. Program the bootloader into the chip using a hardware programmer (which you can make with an Arduino), or
2. Buy an ATMega328P chip with the bootloader pre-programmed.

Once you have the bootloader installed then yes, you can program the chip over UART (through USB with a USB to UART adaptor such as an FT232).
> 1 votes

---
Tags: atmega328, ftdi
---


# Question
Title: Az Delivery ESP32 DevKitC V2 PIN names/number
i wonder where to find out the PIN names for the Az Delivery ESP32 DevKitC V2. There is a pin out graphic, but it does not say how the Pin addresses are: https://cdn.shopify.com/s/files/1/1509/1638/files/ESP\_-\_32\_NodeMCU\_Developmentboard\_Pinout\_Diagram.jpg?4479111012146266271

I thought maybe it's just the number of the GPIOs but that's wrong. In the first example script only PIN 1 was named as the address for the board intern LED.

# Answer
> 1 votes
ESP32 boards don't use "names" for their IO pins. There is a direct 1:1 mapping between the internal "GPIO" number and the pin number.

To do something with pin G21 on the board you use pin number 21. To do something with pin G14 you use pin number 14.

By all accounts that board differs from other ESP32 devkits in that the LED is on GPIO1 rather than the normal GPIO0 that all the other boards use. I suspect that this is the source of your confusion.

---
Tags: pins, esp32
---


title: board stops working when writing serial

text:
# Question
Title: board stops working when writing serial
i just started using Arduino IDE for my XMC1100XMC2Go. Information about the microcontroller can be found here: https://github.com/Infineon/XMC-for-Arduino/wiki/XMC-2Go

I now started with my first codes and want to print things on the serial monitor with this code:

```
*/
/* For on board LEDs */
#include <LED.h>

/* Create an LED object */
LED Led;

//#define SERIAL_DEBUG 1

int p_LED = 5;
int p_Button = 4;
int i_stateButton = 0;

void setup()
{
  Led.Add(LED1);            // Configure the LEDs
  Led.Add(LED2);
  pinMode(p_LED, OUTPUT);
  pinMode(p_Button, INPUT);

  // Set default state of LEDs
  Led.On(LED2);
  Led.Off(LED1);

  digitalWrite(p_LED, LOW);
  Serial.print("Hello World!");

  Serial.begin(9600);
}

void loop()
{
  Serial.write("Hello World!");
  Serial.println(i_stateButton);
  delay(200);
  Led.Toggle (LED2);
  Led.Toggle(LED1);

  i_stateButton = digitalRead(p_Button);
  //digitalToggle(p_LED);
  digitalWrite(p_LED, i_stateButton);
}

```

I checked under tools that SerialOutput is set to PC (https://github.com/Infineon/XMC-for-Arduino/blob/master/variants/XMC1100/config/XMC1100\_XMC2GO/pins\_arduino.h#L54)

There are two Ports, COM1 and COM3. I can send new sketches to the microcontroller using COM3. I checked my Serial Monitor and it is set to COM3, too.

Baudrate is for both the same (code and monitor)

Now that i send the above sketch to the microcontroller it stops working. one LED is on and the other is off. But they do no longer change the state. Nothing appears on the monitor. When i remove the both lines `Serial.write("Hello World!"); Serial.println(i_stateButton);` and send the sketch, the LEDs start flashing again.

I'm pretty sure it's a kind of configuration problem, but i cannot find out what it is. Does anyone have an idea?

# Answer
In the `setup()`, you have:

```
Serial.print("Hello World!");
Serial.begin(9600);

```

One should avoid printing to the serial port before enabling it with `Serial.begin()`.
> 1 votes

---
Tags: serial
---


title: Dim a led using a NPN transistor

text:
# Question
Title: Dim a led using a NPN transistor
I know there are a lot of questions about this topic, but I've tried everything and any possible guide online without success.

I want dim (increase and decrease the brightness) some leds (3.5 Watt each). To do that I'm using an Arduino Nano, a 10k potentiometer and an NPN transistor (TIP41).

I was able to drive the potentiometer as a switch: on/off. Now I want to control its brightness using the potentiometer. I don't get what I'm expecting because the led is always on except when the potentiometer is turned all the way on the right (where is connected Vcc).

This is the schematic:

This is my Arduino code:

```
int pinPotentiometer = 0;
int pinTransistor = 3;

void setup() {
  Serial.begin(9600);
  pinMode(pinTransistor, OUTPUT);
  pinMode(pinPotentiometer, INPUT);
}

void loop() {
  int potValue = analogRead(pinPotentiometer);
  int outValue = map(potValue, 0, 1023, 0 ,255);
  Serial.println(outValue);
  digitalWrite(pinTransistor, outValue);
  delay(100);
}

```

The potentiometer is working fine because I read from the serial values between 0 and 255.

Am I using the wrong transistor? Or maybe I'm using it in the wrong way?

**NOTE**: to test my circuit I'm using a small 5mm led and not the 3.5 Watt one so I don't have any external power source.

Many thanks!

# Answer
Try using analogWrite().

Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to analogWrite(), the pin will generate a steady square wave of the specified duty cycle until the next call to analogWrite() (or a call to digitalRead() or digitalWrite()) on the same pin. The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz.

Source: https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
> 1 votes

# Answer
your transistor base should be connected to the PWM side of the Arduino and not the collector. put a 1kOhm resistor between that base and arduino too. collector to load, load to positive of battery or power source. emitter to ground.
> 0 votes

---
Tags: arduino-nano, potentiometer, transistor, analogwrite
---


# Question
Title: Can I use LiFe PO4 batteries in a 18650 battery shield?
Is it safe to use LiFe PO4 batteries in a 18650 Battery Shield (sometimes called Lithium-Battery Shield)?

# Answer
> 4 votes
In my opinion it is NOT SAFE, if your 18650 Battery Shield also charges the battery.
Anyhow some pages state that it is possible to charge LiFePo4 batteries with 4.2V instead of the recommended 3.65V. https://www.powerstream.com/lithium-phosphate-charge-voltage.htm

LiFePo4 batteries have a smaller energy density and therefore capacity. Thus those are not as explosive as Li-Ion batteries. But you are risking damaging the battery and shorten its lifespan.

---
Tags: shields, battery
---


title: Using EEPROM to write a counter value

text:
# Question
Title: Using EEPROM to write a counter value
I have made a program that increments a counter everytime the up button is pressed. I am trying to write this value to EEPROM, so that when I turn my board off and on again, the value before power off is shown on screen.

I wrote this code but the value doesn't seem to be written to EEPROM. The counter incrementation works fine.

```
#include <EEPROM.h>
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

int addr = 0;
byte value;

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

int a;
void loop() {
  uint8_t buttons = lcd.readButtons();
  if (buttons) {

    lcd.clear();
    lcd.setCursor(0,0);

    if (buttons & BUTTON_UP) {
      a+= 1;
      EEPROM.write(addr, a);
      value = EEPROM.read(addr);
      lcd.print(value);
      delay(100);
    }
  }
}

```

Thanks for the help!

# Answer
> 1 votes
just add `a = EEPROM.read(addr);` in your setup also, you can remove `byte value` and use `a` you wrote to memory in the previous line

---
Tags: c++, c, eeprom
---


# Question
Title: Can Only Upload Arduino Sketch Once to Custom Mega2560 Board
I created a custom Arduino based off the Mega2560 R3. It uses the ATMega16U2 uC as the USB interface between ATMega2560 uC and the PC.

The bootloader on the 2560 is uploaded by using an Arduino Micro via ArduinoISP. I followed this tutorial from Instructables on uploading the bootloader/firmware for the 16U2 except I modified some parts for the 2560 instead of the UNO. Here is my added section in the /program Files (x86)/Arduino/hardware/arduino/avr/boards.txt

```
unorestore.name=MEGA2560 16U2 Restore Firmware
unorestore.bootloader.tool=arduino:avrdude
unorestore.bootloader.low_fuses=0xff
unorestore.bootloader.high_fuses=0xd9
unorestore.bootloader.extended_fuses=0xf4
unorestore.bootloader.file=Arduino-COMBINED-dfu-usbserial-atmega16u2-Mega2560-Rev3.hex
unorestore.bootloader.unlock_bits=0x3F
unorestore.bootloader.lock_bits=0x0F
unorestore.build.mcu=atmega16u2
unorestore.build.f_cpu=16000000L
unorestore.build.board=uno.build.board=AVR_MEGA2560
unorestore.build.core=arduino:arduino
unorestore.build.variant=standard

```

**The problem is** after I upload a sketch (with a size say over 10 kB), I can't upload any new sketch and get this timeout error message instead as shown below. Not even a simple blink sketch. The TX and RX LED connected to the 16U2 uC that flashes during an sketch upload doesn't even blink once.

The only way I can get it take another sketch is to "re-flash" the bootloader on the 2560 uC via ArduinoISP. The TX and RX led now flashes during the sketch upload. Of course, this is a huge hassle as I don't want to do "re-flash" the 2560 bootloader every time I want to upload a sketch.

I don't have this problem on my Elegoo Mega2560 R3 clone board so I'm thinking it might be something wrong with my 16U2 firmware/bootloader. Anyone have any idea what else might be causing this?

# Answer
Your RESET circuit is wrong.

* You have no pullup resistor on the RESET pin of the ATMega3560.
* You have an extraneous pulldown resistor on the D7 pin of the 16U2.

That means your 16U2 will not be able to trigger a reset of the ATMega2560 to run the bootloader.

Remove the pulldown on D7 of the 16U2 and add a 10kΩ pullup to the RESET pin of the ATMega2560. Without that pullup:

1. The chip may not run properly as RESET is floating (it may have an internal pullup, I can't recall)
2. The capacitor linking the 16U2 D7 and RESET of the ATMega2560 won't be able to generate a proper reset pulse. This will be exacerbated by the 1kΩ pulldown.

On the Mega2560 reference schematic RN1A is the pullup in question.
> 1 votes

---
Tags: arduino-mega, bootloader, atmega2560, firmware, atmega16u2
---


title: Can not upload to Arduino Nano BLE 33

text:
# Question
Title: Can not upload to Arduino Nano BLE 33
I am new so please be nice :)

I am trying to upload the Blinky example to my Arduino Nano BLE 33 but I get this error message from the Arduino IDE:

```
No device found on ttyACM0
Set binary mode
Send auto-baud
An error occurred while uploading the sketch
Set binary mode

```

Any idea what I could try?

I am running the Arduino IDE as superuser in Manjaro (latest versions of everything). If you need any more information please feel free to ask.

Full IDE output:

```
Sketch uses 77820 bytes (7%) of program storage space. Maximum is 983040 bytes.
Global variables use 42192 bytes (16%) of dynamic memory, leaving 219952 bytes for local variables. Maximum is 262144 bytes.
Forcing reset using 1200bps open/close on port /dev/ttyACM0
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } => {}
Uploading using selected port: /dev/ttyACM0
/root/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino1/bossac -d --port=ttyACM0 -U -i -e -w /tmp/arduino_build_408944/Blink.ino.bin -R
No device found on ttyACM0
Set binary mode
Send auto-baud
An error occurred while uploading the sketch
Set binary mode

```

# Answer
> -1 votes
It appears you are using Linux. In order to communicate you must establish yourself as being allowed to use it, that is the dial out function. "sudo usermod -a -G dialout " should work but you need to log out then back in before it takes effect. After that you are all set.

---
Tags: arduino-nano-ble
---


title: Can I use The mpu6050 with this?

text:
# Question
Title: Can I use The mpu6050 with this?
I am making a project with 3 arduinos (2 slave, 1 master) and I want to know can I use the mpu6050 since it uses the I2c communication.

# Answer
Yes, but only from the master. You have one I2C bus with three slave devices on it - two arduinos and one mpu6050.
> 0 votes

# Answer
You can but keep the I2C wires less then about 30cm. If they are going to be further apart consider something like RS485 or CAN. Are you sure you need three?
> 0 votes

---
Tags: communication, mpu6050
---