# Question
Title: Arduino Code for Pulse Skip Modulation (PSM)
I have recently bought this light dimmer, and only when I received it I noticed it works with PSM (Pulse Skip Modulation) and not PWD (Pulse Width Modulation).

Does anyone know how to write Arduino code and do the wiring for this dimmer? I can't seems to find a working example.

Thanks

# Answer
I assume you use this module.

PSM is often used because of it's higher efficiency with light loads. It's also better for AC loads, since they should get a complete AC voltage and not a DC voltage (when you cut half of the wave).

The module you have, is build to support you with implementing PSM correctly. It has a zero-crossing detection, which gives you a signal on the Z-C pin, every time the AC sine wave crosses zero voltage (which is the best time to switch). You can sense the signal with an interrupt in your Arduino. The website does not explain exactly, what is outputted by the Z-C pin on a zero crossing, but you can check this easily yourself, by monitoring both AC and Z-C voltage in operation. Most likely you will have to use either a `FALLING` or a `CHANGE` interrupt.

PSM works with modulating the number of pulses (in this case full sine wave periods) are transmitted to the load. Imagine you want to dim the light in 10 distinct values.

* For full power you always set the pin marked with PWM to high, when a full sine wave is starting (this is at every second zero crossing). This means the PWM pin is always high.
* For half power you turn the PWM pin high for 5 full periods and then turning it off for further 5 periods.
* For 10% (a value of 1) you turn the PWM pin high for 1 full period and then off for 9 periods.

The downside of this method is, that you might see the light flickering when having low values.

When implementing this, you can use the `attachInterrupt()` function with the Z-C pin. In the callback function you toggle a global (volatile!) boolean variable, to indicate, if a new full period is starting, or if the zero crossing signal is only indicating the start of the negative part of the sine wave. Also use a global (volatile!) counter variable, that counts (increments every full period) to the value, you preset (Here something between 0 and 10). When the counter variable is 0 (and the desired value is greater than 0) you write HIGH to the PWM pin of your module. When the counter reaches the desired value, you write LOW to the PWM pin. When the counter reaches the maximum value, you have reset it to 0.

In code something like this:

```
volatile byte counter=0;
volatile boolean new_period = true;
volatile byte value=5;
#define MAX_VALUE 10

void setup(){
  // set pinModes for the correct pins

  // active interrupt. Note, that you may have to change FALLING to a value fitting the output of the module (see explanation above)
  attachInterrupt(digitalPinToInterrupt(Z_C_pin), zero_crossing, FALLING);
}

void zero_crossing(){
  if(new_period){
    if(counter==0 && value>0) digitalWrite(PWM_pin,HIGH);
    if(counter==value) digitalWrite(PWM_pin,LOW);
    counter++;
    if(counter > MAX_VALUE) counter=0;
  }
  new_period=!new_period;
}

```

Note: Especially when having a great range of possible values, some of the values can be exchanged by a better behavior, that would prevent a bit of the flickering. For example, when using 100 distinct dimming stages and wanting to dim to 50%, you can either (as depicted above) turn the light on for 50 periods and then turning it of for another 50 periods. Or you can turn on during every second period. Though this will not help you with really small values. So I left it out for simplicity.
> 1 votes

# Answer
Just adding to chrisl's answer since I bought this module, too.

There is a simple example on the manufacturers website of this module which does not seem to implement PSM the obvious way:

```
/*
Connect RobotDyn AC Light Dimmer as follows:
Dimmer pin  --  Arduino pin
    VCC     --    5V
    GND     --    GND
    Z-C     --    D2
    PWM     --    D3

Glow sketch for AC Voltage dimmer with Zero cross detection
Based on the sketch by Charith Fernanado
Adapted by RobotDyn: http://www.robotdyn.com
License: Creative Commons Attribution Share-Alike 3.0 License.
Attach the Zero cross pin of the module to Arduino External Interrupt pin
Select the correct Interrupt # from the below table (the Pin numbers are digital pins, NOT physical pins: digital pin 2 [INT0]=physical pin 4 and digital pin 3 [INT1]= physical pin 5)

Pin    |  Interrrupt # | Arduino Platform
---------------------------------------
2      |  0            |  All
3      |  1            |  All
18     |  5            |  Arduino Mega Only
19     |  4            |  Arduino Mega Only
20     |  3            |  Arduino Mega Only
21     |  2            |  Arduino Mega Only

In the program pin 2 is chosen
*/
int AC_LOAD = 3;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

void setup()
{
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
}

// the interrupt function must take no parameters and return nothing
void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation : 1 full 50Hz wave =1/50=20ms
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) For 60Hz => 8.33ms (10.000/120)
  // 10ms=10000us
  // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

  int dimtime = (75*dimming);    // For 60Hz =>65
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // triac Off
}

void loop()  {
  for (int i=5; i <= 120; i++){  // We use 120 as the lowest and 5 as the highest brightness setting. May be adjusted depending on the lamp used.
    dimming=i;
    delay(20);
   }
  for (int i=120; i >= 5; i--){  // Same as above
    dimming=i;
    delay(20);
   }
}

```

They are using an interrupt as suggested by chrisl. There is no flickering present with low dim values (using an incandescent bulb). See this video for a similar board with the original version of the above sketch.

**Note:** If you want to integrate your own code into this example, it will likely not work as intended because the Arduino is busy with `delayMicroseconds()` most of the time

---

EDIT: The manufacturer of this module just released a library. Check it out on their github
> 3 votes

# Answer
This module allows you to implement pulse skipping modulation but also phase angle control. The code that reins.ch posted is actually the latter.
> 1 votes

---
Tags: pwm
---


# Question
Title: How can I measure maximum range of my ohm meter?
Hello everyone I am working on a project that will measure ohm value of a resistor .

Schematic / article link https://create.arduino.cc/projecthub/iasonas-christoulakis/how-to-make-an-arduino-ohm-meter-90fda8

And

Here is the code below

```
int analogPin= 0;
int raw= 0;
int Vin= 5;
float Vout= 0;
float R1= 1000;
float R2= 0;
float buffer= 0;

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

 void loop()
{
raw= analogRead(analogPin);
if(raw)
{
buffer= raw * Vin;
Vout= (buffer)/1024.0;
buffer= (Vin/Vout) -1;
R2= R1 * buffer;
Serial.print("Vout: ");
Serial.println(Vout);
Serial.print("R2: ");
Serial.println(R2);
delay(1000);
}
}

```

There need to be a known and another unknown resistor.

The ohm value of known resistor is supposed to be 1k ohm

So my question is, what is the max ohm range will my arduino ohm meter be able to measure of the unknown resistor with 1k reference resistor and how to calculate it?

5 - 10% accuracy is enough for me

Thanks for giving me your attention :D

# Answer
> 2 votes
Your *resolution* of the ADC (the analogRead) will be 1/1024 * 5V (since you get a reading in the range 0 to 1023), that is, you can tell the difference in increments of 5/1024 which is 0.00488V, so say roughly 0.005V.

Now, I wrote a little bit of code to work out the voltages that you would get with various values for your varying resistor:

```
r1 =      0, v = 5.000
r1 =    100, v = 4.545
r1 =    200, v = 4.167
r1 =    300, v = 3.846
r1 =    400, v = 3.571
r1 =    500, v = 3.333
r1 =    600, v = 3.125
r1 =    700, v = 2.941
r1 =    800, v = 2.778
r1 =    900, v = 2.632
r1 =   1000, v = 2.500
r1 =   1100, v = 2.381
r1 =   1200, v = 2.273
r1 =   1300, v = 2.174
r1 =   1400, v = 2.083
r1 =   1500, v = 2.000
r1 =   1600, v = 1.923
r1 =   1700, v = 1.852
r1 =   1800, v = 1.786
r1 =   1900, v = 1.724
r1 =   2000, v = 1.667
r1 =   3000, v = 1.250
r1 =   4000, v = 1.000
r1 =   5000, v = 0.833
r1 =   6000, v = 0.714
r1 =   7000, v = 0.625
r1 =   8000, v = 0.556
r1 =   9000, v = 0.500
r1 =  10000, v = 0.455
r1 =  20000, v = 0.238
r1 =  30000, v = 0.161
r1 =  40000, v = 0.122
r1 =  50000, v = 0.098
r1 =  60000, v = 0.082
r1 =  70000, v = 0.070
r1 =  80000, v = 0.062
r1 =  90000, v = 0.055
r1 = 100000, v = 0.050
r1 = 110000, v = 0.045
r1 = 120000, v = 0.041
r1 = 130000, v = 0.038
r1 = 140000, v = 0.035
r1 = 150000, v = 0.033
r1 = 160000, v = 0.031
r1 = 170000, v = 0.029
r1 = 180000, v = 0.028
r1 = 190000, v = 0.026
r1 = 200000, v = 0.025
r1 = 210000, v = 0.024
r1 = 220000, v = 0.023
r1 = 230000, v = 0.022
r1 = 240000, v = 0.021
r1 = 250000, v = 0.020
r1 = 260000, v = 0.019
r1 = 270000, v = 0.018
r1 = 280000, v = 0.018
r1 = 290000, v = 0.017
r1 = 300000, v = 0.017

```

You can see that the difference in voltage is only 0.005V (the ADC resolution) between r1 of 90k and 100k. Further down, you can't tell the difference (within 0.005V) of 270k and 300k.

I'm not sure how to express that as an error percentage, perhaps someone better at maths than me can do that. :)

---
Tags: arduino-uno, resistor, voltage-divider
---


title: Switching from one color to another

text:
# Question
Title: Switching from one color to another
I'm using ws2812b 2x2 LEDs and have it switching between green and red, but only one of my LEDs on my 2x2 is lighting up.

I'm using the "blink" FastLED sketch with Data pin 3 on my Arduino Uno, define led 4.

```
void loop() {
 // Turn the LED on, then pause
 leds[0] = CRGB::Red;
 FastLED.show();
 delay(5000);
 // Now turn the LED off, then pause
 leds[0] = CRGB::Green;
 FastLED.show();
 delay(5000);
}

```

# Answer
For changing the led color or making any other led to glow you have to put the led number instead of `leds[led number]` in this case so your code will basically look like.

```
void loop() {
 // Turn the LED on, then pause
 leds[0] = CRGB::Red;
 leds[1] = CRGB::Red;
 leds[2] = CRGB::Red;
 leds[3] = CRGB::Red;
 FastLED.show();
 delay(5000);
 // Now turn the LED off, then pause
 leds[0] = CRGB::Green;
 leds[1] = CRGB::Green;
 leds[2] = CRGB::Green;
 leds[3] = CRGB::Green;
 FastLED.show();
 delay(5000);
}

```

Hope this helps
> 5 votes

# Answer
This is an addition to the answer of xbox gamer (which I upvoted), to prevent much duplicated code.

**`For` loop**

First we see, the 4 LEDs are made red or green (using green in the following case):

```
leds[0] = CRGB::Green;
leds[1] = CRGB::Green;
leds[2] = CRGB::Green;
leds[3] = CRGB::Green;

```

For this a `for` loop can be used counting from 0 to (excluding) 4:

```
for (led = 0; led < 4; led++)
{
    leds[led] = CRGB::Green;
}

```

**Variant 1: Color argument**

Next we see the first and last lines are almost identical. For this we can make a function, and change the variable items (like the color) with a variable passed to that function, which is called an argument:

First we create the `loop` function:

```
void loop()
{
   turnLEDs(CRGB::Red);   // Turn LEDs on (i.e. red), then pause
   turnLEDs(CRGB::Green); // Turn LEDs off (i.e. green), then pause
}

```

Then we need to make just a single function to change the color (place this before the `loop` function. The type of the color is `enum HTMLColorCode`, see http://fastled.io/docs/3.1/struct\_c\_r\_g\_b.html.

```
void turnLEDs(enum HTMLColorCode color)
{
    for (led = 0; led < 4; led++)
    {
        leds[led] = color;
    }
    FastLED.show();
    delay(5000);
}

```

**Variant 2: Boolean argument**

Another way, is to not pass the color, but pass ON or OFF, which is a boolean. For this we can use the so-called ternary operator: `a ? b : c` which means: if `a` is true, use `b`, otherwise `c`. We get:

```
void turnLEDs(bool enable)
{
    for (led = 0; led < 4; led++)
    {
        leds[led] = enable ? CRGB::Red : CRGB::Green;
    }
    FastLED.show();
    delay(5000);
}

void loop()
{
   turnLEDs(true);
   turnLEDs(false);
}

```
> 2 votes

---
Tags: arduino-uno, ws2812
---


title: Blink LED 5 times with for loop

text:
# Question
Title: Blink LED 5 times with for loop
Is it possible to let a LED blink, for example 5 times, with an Arduino? Should I use a `for` loop?

Something like this works in `setup`, but it will run continuously in the `void loop`, so my LED keeps blinking.

```
for (int i = 0; i <= 5; i++) {
  led HIGH
  delay(500);
  led LOW
  delay(500);
}

```

Also, the blink sequence has to be triggered, and have a reset after it is done.

The complete code is too big to share, but it runs a bit like the following:

There is a "bankValue", it is filled by a user, and counts back to zero.
If it's zero, then blink 5 times.
After the blink, the LEDs are off.
The sketch is waiting for a new user, who will fill the bankValue again and the LED blink should again be initiated.

# Answer
> 1 votes
Its really heavy to give a correct answer, if you don't show us the context where the for loop is used. But I'll try:

There should be a part in the void loop method where you detect that the "bankValue" is down to zero. Like:

```
if (bankValue == 0)
{

}

```

First you must be sure that, the for loop is called within this block.

```
if (bankValue == 0)
{
  // I corrected the loop to run exact 5 times (<= -> <)
  for (int i = 0; i < 5; i++)
  {
    led HIGH
    delay(500);
    led LOW
    delay(500);
  }
}

```

Then you need a flag `int blinkingDone = 0;` to indicate that the for loop has executed. This flag must be initialize with a falsy value, set to trueish after the loop is done and reset if the user "fills" the bankValue again.

Then you could use it as a guard to enter the for loop. Like:

```
int blinkingDone = 0;
int bankValue = 0;

..... somewhere else

if ( coin inserted or so )
{
  // fill bankValue
  blinkingDone = 0;
}

..... somewhere else

if (bankValue == 0 && ! blinkingDone)
{
  // I corrected the loop to run exact 5 times (<= -> <)
  for (int i = 0; i < 5; i++)
  {
    // led HIGH
    delay(500);
    // led LOW
    delay(500);
  }
  blinkingDone = 1;
}

```

There are potential better ways to do it. But I don't know your code. So this is the simplest way I can imagine.

---
Tags: arduino-uno, led, loop
---


title: Send custom HID values instead of keys

text:
# Question
Title: Send custom HID values instead of keys
I've been building a small macro keypad based on the ATmega32U4. So far, I've been able to send standard key presses to the host. But since I want a program on the host system to react to the key presses, I only send the keys to serial to avoid typing anything. For now, this does work.

I want to send custom HID values to the host which won't result in regular key presses. As I've been reading around different blog and forum posts, most of them are just about building a regular keyboard or gamepad but don't go into how to make use of anything else.

This is what I got so far:

```
#include <Keypad.h>

const byte rows = 3;
const byte cols = 5;

char keys[rows][cols] = {
  { '1', '2', '3', '4', '5' },
  { 'q', 'w', 'e', 'r', 't' },
  { 'a', 's', 'd', 'f', 'g' }
};

byte rowPins[rows] = { 10, 16, 14 };
byte colPins[cols] = { 9, 8, 7, 6, 5 };

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );

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

void loop(){
  char key = keypad.getKey();

  if (key != NO_KEY){
    Serial.println(key);
  }
}

```

The only obvious way I see to achieve this is to change the keys array but I don't know to which values.

---

**UPDATE**

I changed the code according to the answer by Majenko:

```
#include <HID-Project.h>
#include <HID-Settings.h>

uint8_t rawhidData[255];

byte rows[] = { 10, 16, 14 };
byte cols[] = { 9, 8, 7, 6, 5 };

const int rowCount = sizeof(rows)/sizeof(rows[0]);
const int colCount = sizeof(cols)/sizeof(cols[0]);

void setup() {
  for (int row = 0; row < rowCount; row++) {
    pinMode(rows[row], OUTPUT);
    digitalWrite(rows[row], HIGH);
  }

  for (int col = 0; col < colCount; col++) {
    pinMode(cols[col], INPUT_PULLUP);
  }

  RawHID.begin(rawhidData, sizeof(rawhidData));
}

void loop() {
  for (int row = 0; row < rowCount; row++) {
    digitalWrite(rows[row], LOW);

    for (int col = 0; col < colCount; col++) {
      if (digitalRead(cols[col]) == LOW) {
        String coordinatesString = String(row+1) + String(col+1);
        uint8_t coordinates = coordinatesString.toInt();

        uint8_t megabuff[sizeof(coordinates)];

        megabuff[0] = coordinates;

        RawHID.write(megabuff, sizeof(megabuff));

        while (digitalRead(cols[col]) == LOW) {
          delay(50);
        }
        break;
      }
    }

    digitalWrite(rows[row], HIGH);
  }
}

```

I removed the serial output since I don't need that anymore. The code looks crude and needs further refactoring but it does work.

# Answer
HID is a strange beast to get your head around.

It operates by way of "Report Descriptors". These are "maps" that lay out what the values you send mean. It's these descriptors that make a keyboard a keyboard and a mouse a mouse.

When you use `Keyboard.h` you attach a Keyboard report descriptor to the USB HID endpoint, and the computer knows to interpret the data coming in as keypresses. When you use `Mouse.h` you attach a Mouse report descriptor and the computer knows to interpret the data coming in as mouse movements and button presses.

If you want your computer to ignore the data that you send and allow your own program to be able to receive the raw data instead then you need to use a descriptor that the computer doesn't recognise. In such a case it just ignores the data.

There's a "Raw HID" library for Arduino that does that - it uses a "blank" report descriptor that just gives you a plain 64 byte block of data to do what you want with.

There's a good HID library by Nico Hood that implements the raw mode (as well as others).

For receiving the data on your computer you will have to have your program directly interface with the USB HID system. There's plenty of libraries for most languages to do this for you (hidapi in C / C++, hid in Python, hid4java for Java, etc).
> 3 votes

---
Tags: atmega32u4, hid
---


title: ESP-NOW with esp32 and esp8266

text:
# Question
Title: ESP-NOW with esp32 and esp8266
I want to use ESP-NOW with esp32 and esp8266. The esp32 will mostly send data to esp8266.I was not able to find any good tutorial on YouTube to achieve this. The only videos I found was for either communicating with esp32 to esp32 or esp8266 to esp8266. Is it possible to do this if yes how.

# Answer
In general, ESP-NOW uses the WIFI radio in an ESP processor as a physical layer. But uses it's own protocol which likely looks like garbage to a normal WIFI equipment. So, it's like being in a meeting room with a bunch of people only knowing German and occasionally someone pipes up taking French. As no one understands the French speaker, the French speaker is ignored.

Other things you need to know. ESP-NOW is more like UDP. There is not a higher layer looking out for you like in TCP. Any number of reasons can cause your ESP-NOW "blurp" from being received. For this reason ESP-NOW is better suited for periodically repeating information. Like reporting the temperature. Or for situations where the user can provide immediate feed back of success. Such as a remote control.

> The esp32 will mostly send data to esp8266

This infers reversing the direction of data flow over the ESP processor's WIFI radios. While this may be possible it may not be a trivial task.

> Is it possible to do this (communicate between an esp32 and esp8266) if yes how.

This shouldn't be problem. This link provided by Majenko appears to be a good place to start. Espressif them selves maintains this ESP-NOW web site. Likely, after programming the ESP8266 and ESP32 using the correct libraries, they will be able to send data over an ESP-NOW link.
> 2 votes

---
Tags: esp8266, arduino-ide, esp32
---


# Question
Title: can we make Drone with Dc 180 motor and Arduino?
I want to make a drone as a project for my university, But I am kinda newbie in this, I did many searches about this and I found I should do it with the brushless motors (BLDC) but I can't buy this kind of motors, So I want to do it with DC motors I found in youtube there is motor can be used in the drone it called ( 180 dc motor) but they didn't use them with Arduino.

My question is can I use Dc 180 motor with Arduino and make a drone Or Not?

# Answer
> 2 votes
Yes you could but you will have to use a motor driver or else the motors will not be able to get enough power and try using arduino micro or an esp32 if you want to use it with Bluetooth which will also help you to keep the weight down.

---
Tags: arduino-uno, drone
---


# Question
Title: TQFP Atmega328pu-th cant upload sketch sync error (breadboard)
So I have a USB to ftdi connected to my qtfp 32 socket trying to upload a sketch but I get a sync error , as far as I am aware I have uploaded the sketch correctly

# Answer
Hey guys I managed to figure it out I had to remove the dtr pin from pin 29 , I made a video to help anyone else looking to do it, I don't know if it breeches any self promotion? But hope it helps because i found it difficult to find any resources. https://youtu.be/5CPYz6Kde7M
> 1 votes

---
Tags: arduino-uno-smd
---


title: Power 5v from l298n to 5v pin arduino

text:
# Question
Title: Power 5v from l298n to 5v pin arduino
im using the l298n module, and 3x 18650 batterys (near 12v total), and supplying 12v to the 12v pin of the l298 module. Can i use the 5v pin of the module to power the 5v pin of arduino? Or i need a second power supply just for the arduino? Any tips?

# Answer
> 1 votes
Power the arduino from your batteries via the Vin (barrel Jack) use the arduino to supply the 5V to the L298 module and connect all the grounds together. That should do it.

# Answer
> 0 votes
The L298N is a chip, and the link you provided in the comments is to the chip, not to a full H-bridge module with voltage regulator and other components. We don't have any way to answer your question about your particular set-up without more info.

If the module you have uses a voltage regulator to provide clean 5V to its solid state chips, but does not use it to drive the motors, and it provides enough extra current to drive your Arduino then you might be able to get away with using it to feed your Arduino. If the H-bridge module uses the output of it's 5V regulator to drive the motors then I would not recommend using it to power your Arduino, since as the motor is switched on and off it will cause the voltage from the regulator to bobble. At the very least you would need a reservoir capacitor across the 5V rails near the Arduino to smooth out the 5V supply.

---
Tags: arduino-mega, power, l298n
---


# Question
Title: How might I add a delay, close the servo and go to the start again?
```
#include <Servo.h>
Servo myServo;

  const int piezo = A0;
  const int button = 2;
  const int yellow = 3;
  const int green = 4;
  const int red = 5;

  int knockVal;
  int buttonVal;

const int quietKnock = 10;
const int loudKnock = 100;

boolean locked = false;
int numberOfKnocks = 0;

void setup()
{
  myServo.attach(9);
  pinMode(yellow, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(button, INPUT);
  Serial.begin(9600);

  digitalWrite(green, HIGH);
  myServo.write(0);
  Serial.println("The box is unlocked!");
}

void loop()
{ //start of loop
  if (locked == false)
  { //start of if1
    buttonVal = digitalRead(button);
    if (buttonVal == HIGH)
    { //Start of if2
      locked = true;
      digitalWrite(green, LOW);
      digitalWrite(red, HIGH);
      myServo.write(90);
      Serial.println("The box is locked!");
      delay (1000);

    }     //end of if2
  }      //end of if1

  if (locked == true)

  { //start of if3

    knockVal = analogRead(piezo);

    if (numberOfKnocks < 3 && knockVal > 0)

    { //start of if4

      if (checkForKnock(knockVal) == true)

      { //start of if5

        numberOfKnocks++;

      }   //send of if5

      Serial.print(3 - numberOfKnocks);
      Serial.println(" more knocks to go");

    }     //end of if4

    if (numberOfKnocks >= 3)

    { //start of if6
      locked = false;

      myServo.write(0);
      delay(20);
      digitalWrite(green, HIGH);
      digitalWrite(red, LOW);
      Serial.println("The box is unlocked!");

    }   //end of if
  }   //end of if3
}           //End of loop

boolean checkForKnock(int value)
{ //start of boolean

  if (value > quietKnock && value < loudKnock)

  { //start of if7

    digitalWrite(yellow, HIGH);
    delay(50);
    digitalWrite(yellow, LOW);
    Serial.print("Valid knock of value ");
    Serial.println(value);
    return true;
  }   //end of if7
  else
  { //start of else
    Serial.print("Bad knock value ");
    Serial.println(value);
    return false;
  }   //end of else
}     // end of boolean

```

# Answer
```
if (buttonVal == HIGH)
{ //Start of if2
  locked = true;
  digitalWrite(green, LOW);
  digitalWrite(red, HIGH);
  myServo.write(90);
  Serial.println("The box is locked!");
  numberOfKnocks = 0;
  delay(1000);
}

```

I have added `numberOfKnocks = 0` at this part of the code so your knock value goes to zero on locking it which will not open the lock again as soon as you lock it. The problem was that you did not change the numberoflnock value which remains same even after locking it so when the code loops back to the unlocking part it automatically unlocks it.

Hope this helps you.
> 1 votes

---
Tags: led, servo, button, code-review, code-optimization
---


title: Using Arduino UNO as FTDI

text:
# Question
Title: Using Arduino UNO as FTDI
so , just bought some pre-bootloaded ATmega328(p/pu) to which I need to upload sketches on a breadboard using uno TX and RX pin as FTDI

Here is what I am to do.

1. I connected Uno GND and Reset .
2. Arduino Tx to Standalone Atmega Tx
3. Arduino Rx to Standalone Atmegaa Rx
4. Connected Crystal , capacitor to standalone pin 9, 10 (XTAL) then grounded it with 2 coupling capacitor.
5. Standalone vcc to arduino 5v Standalone GND to Uno GND

Is it possible to do what I need to or i need to buy some USB to TTL devices from the Amazon again?

Thanks for your precious time...

# Answer
> 2 votes
That sounds about right.

The only problem is that normally, when a serial connection is created, the Arduino's reset pin is briefly pulled LOW. You would have to do that manually on the ATMega on your breadboard. I can be a bit tricky to get the timing right.

There is no easy way to get this signal to your breadboard ATMega, while keeping the reset pin on the UNO's ATMega LOW.

Removing the ATMega from the UNO board would work.

# Answer
> 3 votes
https://youtu.be/EoHD0m3uUhA. Ig this should do it. There are many more tutorials on YouTube to achieve this.

---
Tags: arduino-uno, atmega328, ftdi, breadboard
---


# Question
Title: Certain componenet does not seen to respond when given voltage
I am using a part off an electronics set I got a long time ago. It is off a electronic set called

> snap circuits rover deluxe

Its a disc launcher and I have wired it to how it seems to want to be wired:

The idea is that these circles you can see on the disc launcher are button tops and connect to other with other buttons just like buttons on a coat and how the pop together. I have some special wires that allow these button tops to be connected to arduino wires (which are what I am using). In terms of a power supply I have connected a 9V power supply (not 9V transistor battery) and I have connected the + wire to the + button on the disc launcher and the same with the - wire being connected to the - button on the disc launcher. The only confusions that I now have are:

* What is the CONT button potentially used for?
* What is the EXT potentially used for? I just tried guessing by putting the 9V power supply into the CONT and EXT buttons by using a breadboard, nothing happened from this, and I was also thinking during this where is the ground for the CONT and EXT pins.

If this will not simply work then, I was wondering does anyone know where I can buy an arduino plastic missile launcher

# Answer
> What is the CONT button potentially used for?

That's the trigger. Connect that to (-) and a disc should fire.

> What is the EXT potentially used for? I just tried guessing by putting the 9V power supply into the CONT and EXT buttons by using a breadboard, nothing happened from this,

That is for triggering another device when this triggers. With your pop connections it can be hard to connect multiple things to the same signal, so for convenience they have given you a "pass through" connection. You could use that to chain together multiple disc launchers (EXT on one connected to CONT on the other)

> and I was also thinking during this where is the ground for the CONT and EXT pins.

The (-) battery connection is ground.
> 2 votes

# Answer
You need to connect (-) to both the battery - terminal and to the Arduino ground.

Connect CONT to a digital output pin on the Arudino. When you set the Arudino pin to LOW, it should trigger the disc launcher.

If the disc launcher uses CMOS logic you should be good to go. IF it uses TTL logic then you will need a TTL driver chip or a transistor or you might burn out the Arduino pin. You will need the specs for the disc launcher to be sure, or measure the current it drives through the CONT pin to ground. (It should be effectively zero for a CMOS pin, since CMOS inputs are capacitive. If it's a TTL input it will push like 20mA from the CONT pin to ground, as I recall.)
> 1 votes

---
Tags: battery, voltage, input
---


# Question
Title: Trying to use Nano Every as a sort of USB logic analyzer, but can't isolate it from "device under observation"
Here's the scenario: I have a radio that displays information on a 1602A LCD. The 1602A is plugged into a header so I can easily pull it out and instead plug in logic analyzer leads. The logic analyzer decodes the HD44780 protocol and shows me the data that would have gone to the 1602A. The logic analyzer, not surprisingly, doesn't have any noticeable effect on the radio.

Now I want to replace the logic analyzer with a Nano Every. I wired it up so that the signals to be observed are connected to digital input pins on the Every. The Every is powered through USB and doesn't intentionally draw any power from the radio. Everything runs as expected and the Every shuffles readings to the PC via serial. HOWEVER, in this combination, the radio draws at least twice as much current from the power supply and the radio's voltage regulators begin to heat up substantially!

I would have thought that the digital input pins of the Every are high enough impedance that it would have no significant effect on the radio, just like the logic analyzer didn't. I can only assume that "significant" current is flowing from the radio's LCD header into the Nano Self's input pins, since they are the only connection between the radio and the Nano.

So, I guess my question is this: How can I make the Nano Self work more like a logic analyzer? Do I need additional circuitry between the signals being tested and the Self's input pins, perhaps logic buffers? Or might something else be going on here?

# Answer
> 1 votes
@jsotola was correct and the software defined pin directions incorrectly. Looks like I fried one of the pins in the process (multimeter shows continuity between the pin and ground), but when I rewired to a new pin on Port D and ran the corrected software, everything seems to work as expected!

---
Tags: arduino-nano, system-design
---


title: IMU (MPU9250) and Ticker on ESP32

text:
# Question
Title: IMU (MPU9250) and Ticker on ESP32
I want to read the data from an IMU (MPU9250) periodically. To do that I use a ticker as shown in the following code:

```
#include <Ticker.h>
#include "MPU9250.h"

constexpr int SERIAL_BAUDRATE = 115200;
constexpr float SAMPLING_FREQUENCY = 1.0;

Ticker TimerIMU;
MPU9250 IMU(Wire, 0x68);

void readIMU()
{
    // read the sensor
  IMU.readSensor();
  // display the data
  Serial.print(IMU.getAccelX_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelY_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelZ_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroX_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroY_rads(),6);
  Serial.print("\t");
  Serial.println(IMU.getGyroZ_rads(),6);
}

void setup()
{
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}
  // start communication with IMU
  int retVal = IMU.begin();
  if(retVal < 0)
    Serial.println("IMU initialization unsuccessful: check your wiring or try resetting power to the sensor.");
   // start ticker
  TimerIMU.attach(1.0 / SAMPLING_FREQUENCY, readIMU);
}

void loop()
{
}

```

This approach does not produce the expected results: the IMU returns always the same values. Putting the readIMU function in the main loop and commenting the Ticker works well. I use an ESP32-WROVER.

Where is my error? Any suggestion would be appreciated.

# Answer
> 1 votes
`readIMU()` is called by the library from an ISR (Interrupt Service Routine). While the ISR runs, other interrupts cannot be handled. The IMU sensor works over I2C, which relies on interrupts being serviced. So, when initiating the communication inside an ISR, the transmission can never be finished correctly, since the needed ISRs are not executed. At least the library doesn't seem to block in that case, so the code runs, but the values are never updated.

You should not do interrupt dependent things inside of an ISR. Instead you can define a global flag variable, which you set inside the ISR. Then in your main code you just constantly check this flag and execute the ISR dependent code, if the flag is set. After the execution you reset the flag.

The response time is dependent on the speed, that your loop runs in. But this shouldn't be a problem here, since you don't have any other code in `loop()` and your frequency is just 1Hz, so a delay of a few microseconds should not be relevant.

---

Note, that using Serial is also interrupt dependent. So writing or printing to Serial inside an ISR is also not very good. Though you can get away with it, when you make sure, that you never send more data, than the Serial buffer can hold, and that you leave enough time between the interrupts for the actual transmission. Inside an ISR the printing and writing statements will just fill the buffer. The data will then gets send in the background via interrupts.

---

Note, that doing this with a Ticker (aka via interrupts) is really not necessary. Instead you can execute the code directly in `loop()` in a non-blocking style via `millis()`. Have a look at the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It demonstrates how to do timed things without blocking with delay calls.

---
Tags: esp32, timers, imu
---


title: voltage regulator

text:
# Question
Title: voltage regulator
This may not be the best pace to ask this but I have to use a 3.3v regulator with this esp12 . For that I have selected this regulator 3,3v regulator and in the discribtion it is saying to use two capacitors . so are the capacitors compulsory or not and what will happen if i dont use the capacitor

# Answer
> 2 votes
Yes, they are compulsory. They are to prevent oscillation of the regulator and to provide rapid delivery of current over short periods while the regulator adjusts to changing demands.

---
Tags: esp8266, voltage
---


title: ESP32 and wifi router

text:
# Question
Title: ESP32 and wifi router
I connected my ESP32 to Wifi and I can see this in my Wireless Statistics:

```
ID |       MAC Address      |Current Status| Packets Received | Packets Sent | SSID
1  | 3C: 71: BF: 0D: CB: 00 | Connected    |         52       |       47     |mySSID

```

I can ping via IP but I can't see ESP device in the DHCP list or ARP. Could you explain why? And how I can fix this?

# Answer
> 1 votes
I made a binding IP and MAC and now I see my ESP)

---
Tags: wifi, esp32
---


# Question
Title: Why Windows 10 does not see Nodemcu device?
* I am using a Windows 10 laptop. Behind the nodemcu it says that download CH340G driver.
* I already had arduino ide and the esp libraries were already installed because i was using a esp8266 01 device before.
* I bought a Nodemcu i downloaded the driver for it CH340G driver.
* When i install the driver it says that The drive is successfully pre-installed in advance!
* When I plug my Nodemcu to my computer with a new cable blue lights come from the board and it stops. And windows doesn't make a sound which indicates that it sees the device.
* I don't think the nodemcu is the problem. How do i fix this?

# Answer
Read through https://stackoverflow.com/questions/43007501/nodemcu-not-detected-by-computer#:~:text=I%20had%20to%20install%20the,Afterwards%2C%20it%20worked.&text=For%20future%20people%20with%20this,and%20it%20wouldn't%20detect. and also search few ways to remove oxidation from pins like using autosol (I have never used it ) . Try uploading code through FTDI modules or just get it replaced.
> 1 votes

---
Tags: esp8266, nodemcu, windows, ch340
---


# Question
Title: How to read two byte register address using arduino wire library
I want to read a register 0x012A from the device I2C address 0x0A, the value stored in the register is two bytes, If the register address is one byte i can use Wire.requestFrom and give the register address and how many bytes i want to read since here register address itself 2 bytes i'am bit confused . can any one help in this regard.

# Answer
> 3 votes
> i can use Wire.requestFrom and give the register address and how many bytes i want to read

So you give it `2` to ask for 2 bytes.

Then you combine them. How you do that depends on what the bytes represent. If the first is the upper byte and the second the lower byte of a 16 bit value then you would:

```
uint8_t b1 = Wire.read();
uint8_t b2 = Wire.read();

uint16_t val = (b1 << 8) | b2;

```

If it's the other way around then just swap the variables in the combining section.

However if the values are some other arrangement (I saw something recently that had two registers with a 12 bit value with overlapping bits) you will have to combine it in the way that is required for that specific arrangement.

---
Tags: i2c
---


# Question
Title: analogWrite(PIN, 1023) <> digitalWrite(PIN, HIGH)
This question is very similar to this one. I'm using an ESP8266 for which the maximum analogWrite value is 1023 rather than 255 for some other Arduino boards, but I believe the principal is just the same.

I'm driving 3 LEDs directly from 3 outputs via current limiting resistors.

When I turn them on using analogWrite(PIN, 1023) they are not quite a bright as when the same LED is driven by the same pin using digitalWrite(PIN, HIGH). Which leads me to think that either 1023 does not give a 100% duty cycle or the maximum voltage in the analog case is less than that in the digital one. Is this to be expected? Are the pins significant (4,5 and 14)?

Another similar Q&A would lead me to believe they should be the same.

# Answer
I can confirm that 1023 does indeed give 100% duty cycle. I connected an output of my D1 Mini to my oscilloscope and got a steady voltage.

I can also confirm that the same voltage is output for `digitalWrite()` and `analogWrite()`.

However the output drivers may not be the same. With `analogWrite()` it may be using a weaker output driver that can't deliver as much current, so the voltage droops slightly more than it would with `digitalWrite()`. However even with a 470Ω resistor connected between the output and GND (the smallest value I had easily to hand in a through hole variant) I see no variation in the voltage at all.

So if there is some variation then it might be some variable that is showing a variation in your specific unit but not mine.
> 2 votes

---
Tags: esp8266, analogwrite, digitalwrite
---


# Question
Title: How to get timestamp of when the data was collected
Basically I want to be able to display the time the arduino collected the data with the data value, not the time the arduino printed off the data. Theres a timestamp feature on the console, however I want to find the time the data was collected.

I'm a bit new to this so any help is greatly appreciated!

# Answer
Getting a "timestamp" of when data is collected is entirely down to you.

Most Arduinos don't have any concept of the current time, only the time since the program started running. To know what the time "now" is you have to have some mechanism to tell the Arduino what the time is, along with a method of keeping track of that time.

There are devices called Real-Time Clock (RTC) modules which keep track of the time for you. They don't magically know the time - you still have to tell them at least once.

You could tell it the time through the serial port to set the clock - from then on (assuming the RTC has power) the RTC will know what the time is.

Another option to get the time into the RTC is to use an internet connection (ESP8266, WiFi shield, Ethernet shield, etc) to perform a Network Time Protocol (NTP) query to a time server on the internet (such as `pool.ntp.org`) to get the current time and update the RTC. This should be done regularly to correct any drift in the RTC.

Once you have an RTC and a method of setting the time you can query the time whenever you sample some data and store that time along with the data in whatever way is most suitable for your situation.
> 2 votes

# Answer
It depends on how you define the time stamp. A Unix timestamp is the number of seconds elapsed since Unix epoch time, i.e. January 1 1970 00:00 UTC, this is a very common time stamp. You can setup with NTP via the internet, or you can use a RTC on your board. How you do it depends on how accurate you want it and what you have available. Try this link it may help: https://currentmillis.com/
> 1 votes

---
Tags: arduino-uno
---


title: Arduino led not blinking

text:
# Question
Title: Arduino led not blinking
```
#include <Arduino.h>

void setup()
 {
  pinMode(13, OUTPUT);
 }
void loop()
{
 digitalWrite(13, HIGH);
 delay(1);
 digitalWrite(13, LOW);
 delay(1);
}

```

I am trying to make an led glow for one second to glow and then go off but nothing happens

# Answer
> 3 votes
```
#include <Arduino.h>

void setup()
 {
  pinMode(13, OUTPUT);
 }
void loop()
{
 digitalWrite(13, HIGH);
 delay(1000);
 digitalWrite(13, LOW);
 delay(1000);
}

```

The problem with your code is that the delay function works in milliseconds and not seconds . 1sec = 1000ms .

# Answer
> 1 votes
by increasing the delay value, you can visualize it better.

```
{

 digitalWrite(13, HIGH);

 delay(2000);

 digitalWrite(13, LOW);

 delay(1000);

}

```

---
Tags: arduino-uno, led
---


# Question
Title: How much current can arduino ground absorb?
I am currently working on an LED 4x4 cube, so here is my pre planned circuit diagram.

https://easyeda.com/editor-mobile/#id=ffca9f3303f242a185b950b0bee4fa29|

1. I am to connect 220ohm to each positive terminals.(16)
2. I am to use 4 transistors(2n2222) for 4 negative layers of which, collector terminal will be connected to the negative terminal layers , base will be connected to 4 analog pins through 1k ohm, and emitter to be connected to the GND pin of arduino. Using transistor as a switch.

Can my studio ground get damaged if connected directly without a resistor.

If no?

Is there any way to make it?

Explanation with circuit diagram will highly be preferred...

Thanks for your precious time...

# Answer
> 1 votes
No your gnd won't get damaged if you source current through it. If u need explanation let me know

# Answer
> 0 votes
You are asking the wrong question. It does not matter how much current the arduino ground can adsorb, it was designed for what it needs not what other devices may need. What you want to do is connect all the grounds at the power supply (please tell me you are not using the arduino 5v for this). You might look as MOSFETs as you will have a lower voltage drop and much easier to drive.

---
Tags: arduino-uno
---


# Question
Title: 4-digit 7-segment display not showing value properly
I'm trying to add a 4-digit 7-segment display to an existing project (a temperature & relative humidity sensor) to show the temperature on the display.

I bought the display a long time ago and I it doesn't have any ID and I don't have any reference to a schematic, so I followed this article to find out both if it's a common cathode or anode and the pinout.

It turns out it's a common cathode display and the pinout goes like this (numbered from upper left):

1 -\> D1
2 -\> A
3 -\> F
4 -\> D2
5 -\> D3
6 -\> B
7 -\> E
8 -\> D
9 -\> DP
10 -\> C
11 -\> G
12 -\> D4

Where D{1,2,3,4} are the digit control pins and the rest are the segments.

So I added the SevSeg library to my project. And the sketch compiles, but when I upload it to my Arduino Uno all the LEDs in the digits 1 and 4 light up and digits two and three remain off.

I checked the pinout twice, with the same results and the display doesn't seem to be damaged. Do you see any issue on my code?

Thanks in advance!

# Answer
What caused the problem of the digit that driven by pin 12 is quite obvious to me. You use pin 11, 12, 13, 14 for driving the 7-segment digits. While SPI library by default uses pin 10, 11, 12, 13 as SS, MOSI, MISO and SCK, and set pin 12 (MISO) as `INPUT` which is in conflict with your pin 12 (as an `OUTPUT`) for driving the digit.

Pin 13 is also used by the interval blinking LED (i.e. `BUILTIN_LED`) when defined as a digital i/o.

Your code uses quite a few libraries, and those libraries could uses some of the I/O pins, I would suggest you reduce your code to only the code related to SevSeg, set the display to all '8888', and add each library one by one back to find out what caused the problem.
> 2 votes

# Answer
Your issue could be in code or in your hardware.

To work out which one, try running one of the example sketches like the `testWholeDisplay.ino` that comes with the library you are using. This way you have known working code and you are testing that your hardware is wired up correctly. If this step doesn't work, then you need to look into your wiring and/or setup.

If using the example sketch works, then you can start looking into your sketch. Divide it into chunks and test each chunk independently. If any chunk doesn't work then work out what is different from the example sketches compared to your code.
> 1 votes

# Answer
Reverse engineering your code, which is generated by https://examples.blynk.cc, I have found that you are using:

Your Blynk example code looked something like this.

For the 7 segment display you are using pins 3, 5, 6, 7, 8, 9, 11, 12, 13, A0, A1, A2.

```
byte digitPins[] = { 11, 12, 13, A2};
byte segmentPins[] = {3, A0, 5, 6, 7, 8, 9, A1};

```

However, the W5100 Ethernet controller uses pins 10, 11, 12 and 13 as seen on the Arduino Ethernet webpage:

> NB: Pins 10, 11, 12 and 13 are reserved for interfacing with the Ethernet module and should not be used otherwise. This reduces the number of available pins to 9, with 4 available as PWM outputs.

Pins 2 & 4 are used for the DHT11 and SD card chip select respectively.

All you have to do is change the wiring of the seven segment display to not use pins 11, 12 and 13, and then adjust your sketch accordingly. For example, you could use A3, A4 & A5.
> 1 votes

---
Tags: arduino-uno, 7-segment
---


title: No SPIFFS only OTA in NodeMCU ESP8266

text:
# Question
Title: No SPIFFS only OTA in NodeMCU ESP8266
I have a NodeMCU ESP8266 ESP-12E and I tried uploading a file thru the SPIFFS. I am not sure why I see OTA instead of the SPIFFS?

Is there a configuration that I missed?

# Answer
SPIFFS (SPI Flash File System) is also know as FS(File system) . so What you are seeing as FS is basically SPIFFS .The OTA partition on esp8266 is compulsory so you cant get rid of it .

Hope this helps
> 3 votes

---
Tags: esp8266, arduino-ide, nodemcu
---


# Question
Title: Running a DC motor for a set amount of time
I am trying to run a DC motor for 100ms and then turn it off completely. Here is my code any suggestions on why it might not be working?

My Code

```
const int pirPin = 9;
const int motorPin = 2;
int switchState = 0;
// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(motorPin , OUTPUT);
  pinMode(pirPin, INPUT);
}
void loop() {
  while (digitalRead(pirPin) == HIGH) {
    digitalWrite(motorPin, HIGH);
    delay(100);
    digitalRead(pirPin) == LOW;
    break;
  }
}

```

# Answer
> 1 votes
```
#include <Arduino.h>

const int pirPin = 9;
const int motorPin = 2;
int switchState = 0;
// the setup routine runs once when you press reset:
void setup()
{
 // initialize the digital pin as an output.
 pinMode(motorPin, OUTPUT);
 pinMode(pirPin, INPUT);
}
void loop()
{
 while (digitalRead(pirPin) == HIGH)//this part of the code gets executed if the pir
 //pin is read high
 {
   digitalWrite(motorPin, HIGH);//the motor pin is set high so if a motor is connected
   //the motor will start turning.
 }
 while (digitalRead(pirPin) == LOW)//this part of the code gets executed if the pir
 //pin is read low
 {
   delay(100);// so your motor stop after running for extra 0.1 seconds
   digitalWrite(motorPin, LOW);//the pin gets low and the motor should stop turning
 }
}

```

I have commented all the lines

Hope this helps.

---
Tags: arduino-uno, motor, time, timing
---


# Question
Title: How can I switch from ArduinoOTA to ESPhome safely?
I have an ESP8266 (ESP-12F), which I flashed with ElegantOTA, a variation of ArduinoOTA with just a different interface. I never managed to flash anything else, so it's a bare OTA I flashed using a dedicated programmer. The device has not even pins for further flashing.

The ESP is already in a device that I would like to avoid opening, and I would like to avoid soldering pins and flashing locally the ESPhome firmware (which is also configured for future OTA).

I'm not sure the bootloader or whatever is used to self-flash the chip is compatible. How can I do it?

Or should I just open the ArduinoOTA webpage, upload a ESPhome firmware and go on?

# Answer
I compiled a minimal ESPhome firmware, with only OTA and wifi captive portal, and I tried to upload it (300 KB, more or less).

Initially I got the error "Space is not enough", but then after rebooting the ESP8266 and trying again, it worked.

So as said by dandavis, different firmwares are compatible in regard to OTA capabilities and it's possible to cross-flash.
> 0 votes

# Answer
I've found that when a flash fails with a space error, I've usually specified the wrong flash size option in Arduino (under Tools-\>Flash Size). Depending on the version of Arduino you're using, try picking the one with "No SPIFFS" or FS:none that matches the size of your flash memory. Once you make that change, recompile and reupload.
> 1 votes

---
Tags: esp8266, ota
---


title: Detect 2 wire thermostat output

text:
# Question
Title: Detect 2 wire thermostat output
I have a 2 wire thermostat. R is +24VAC, W is Heater. I have no Ground wire (C), and I cannot open the thermostat.

When the heater goes on, the thermostat internal relay gets powered and connects R and W together.

How can I detect when the heater is on from those two wires?

# Answer
> 1 votes
With checking the temperature in the room. When the contact is closed store the current temperature. Check after a minute the temperature again. If it is higher, the heater is on.

---
Tags: sensors, relay
---


title: Wide range of protocols one chip?

text:
# Question
Title: Wide range of protocols one chip?
Is there some way to do raw radio on a esp32 and change frequencies. If not what would I need to transmit rf, wifi, bluetooth, zigbee etc. There seems to be no tutorials on how to do anything of the sort.

# Answer
> 1 votes
> There seems to be no tutorials on how to do anything of the sort.

That's because doing such a thing is not something the manufacturer of a part typically expects you to want to do. Yes, some chips may be capable of other protocols internally, but making them use those protocols would mean direct manipulation of the low level components in the chip.

Chips like the ESP32 or the nRF24L01 are geared towards specific protocols. They expose functionality that is good for those protocols.

There are other chips which are designed with (almost) any protocol in mind, but there's nothing "arudinoy" about using them. To access other protocols you would download the SDK for that chip and create new firmware specifically for the protocol you want to use. In many cases such SDKs and the associated documentation is protected under NDA so you or I getting access to such a thing is not usually possible.

In general though a chip is designed with a specific protocol and application in mind and is optimised specifically to handle the requirements of that protocol.

---
Tags: arduino-ide
---


title: Power supply for DIY Arduino CNC Router

text:
# Question
Title: Power supply for DIY Arduino CNC Router
I am making a CNC router from a dremel and 3-5 NEMA 17 steppers. I am really confused on how I can power all those motors. I am using a RAMPS 1.4 with Arduino Mega. I have a 2.4A USB power supply. Is that enough? If not, what is the minimum specs I need to ensure that I don't burn, blow, or under power anything? I am trying to get my hands on a ATX power supply.

# Answer
> I have a 2.4A USB power supply. Is that enough?

Not by a long way, no.

NEMA 17 motors are typically 12V, not 5V, so a USB power supply is not even close.

You will need a decent 12V power supply with a lot of current.

My 3D printer has 3 NEMA 17 motors and uses a 200W 12V power supply. Most of that goes to the motors with only a comparatively small proportion to the hot end.

You need to know the current draw of the motors you are using (note: NEMA 17 defines the physical size, not the electrical characteristics). Sum all those up for all your motors, and that's the absolute minimum you'll need from your power supply. Add some more on top for losses in the motor drivers and to power the Ardiuno.

And I'm not even considering the dremel in any of this...

So yes, an ATX power supply is probably a good choice.
> 1 votes

---
Tags: arduino-mega, power, stepper-motor
---


# Question
Title: Help a noob, no idea on Programming, only started 2 days ago Help please
As said no programming skills only started 2 days ago when Nano arrived. Heads in bits. This is how far i got. Any help much appreciated..

```
int EMagnetPin = 8;
int solenoidPin = 9;
int ReedPin = 13;

void setup()
{
  pinMode(EMagnetPin, OUTPUT);     // assign pin type
  pinMode(solenoidPin, OUTPUT);   // assign pin type
  pinMode(ReedPin, INPUT);        // assign pin type
  Serial.begin(9600);             //serial port open

void loop()
{
Serial.print(digitalRead(ReedPin));
if (digital REad(ReeddPin)==0 ) {
digitalWrite(solenoidPin,HIGH);

                  // Once magnet applied to Reed Switch Will activate the below

  digitalWrite(EMagnetPin, low);
  delay(11000);
  digitalWrite(EMagnetPin, HIGH);
  delay(500);
  digitalWrite(EMagnetPin, low);
  delay(500);
  digitalWrite(EMagnetPin, HIGH);
  delay(500);
  digitalWrite(EMagnetPin, low);
  delay(22500);
  digitalWrite(EMagnetPin, HIGH);
  delay(500);
  digitalWrite(EMagnetPin, low);
  delay(500);                          // Stops EMagnet
  digitalWrite(solenoidPin, HIGH);     //Start Solenoid
  delay(500);
  digitalWrite(solenoidPin, low);
  delay(500);
                    // Program Ends

```

# Answer
I presume you got some errors, like this:

```
/tmp/arduino_modified_sketch_836883/sketch_oct30a.ino: In function 'void setup()':
sketch_oct30a:13:3: error: a function-definition is not allowed here before '{' token
   {
   ^
sketch_oct30a:37:17: error: expected '}' at end of input
       delay(500);
                 ^
exit status 1
a function-definition is not allowed here before '{' token

```

You have to read those. At the end of a function you need a closing brace. So, setup for example would look like this:

```
void setup()
{
  pinMode(EMagnetPin, OUTPUT);     // assign pin type
  pinMode(solenoidPin, OUTPUT);   // assign pin type
  pinMode(ReedPin, INPUT);        // assign pin type
  Serial.begin(9600);             //serial port open
}   // <------- ADD THIS

```

Ditto for the end of the loop function.

The next problem is this line:

```
    if (digital REad(ReeddPin) == 0 ) {

```

The function "digitalRead" is spelt like that, not as two words. Also you misspelt "ReedPin" as "ReeddPin".

You have to go carefully through your code, look at the error messages, and fix them one by one. C++ is case-sensitive, you can't just thrown in extra spaces in the middle of words, and you have to be consistent with your variable names (ie. not misspell them).

---

I suggest you do a C++ tutorial, or find an Arduino tutorial. These are basic coding mistakes made by beginners. With a bit of practice, and some working through examples, you will stop making them.
> 1 votes

# Answer
```
#include <Arduino.h>
int EMagnetPin = 8;
int solenoidPin = 9;
int ReedPin = 13;

void setup()
{
  pinMode(EMagnetPin, OUTPUT);  // assign pin type
  pinMode(solenoidPin, OUTPUT); // assign pin type
  pinMode(ReedPin, INPUT);      // assign pin type
  Serial.begin(9600);           //serial port open
}

void loop()
{
  Serial.print(digitalRead(ReedPin));
  if (digitalRead(ReedPin) == 0)//it is known as digitalRead
  {
    digitalWrite(solenoidPin, HIGH);

    // Once magnet applied to Reed Switch Will activate the below

    digitalWrite(EMagnetPin, LOW);
    delay(11000);
    digitalWrite(EMagnetPin, HIGH);
    delay(500);
    digitalWrite(EMagnetPin, LOW);
    delay(500);
    digitalWrite(EMagnetPin, HIGH);
    delay(500);
    digitalWrite(EMagnetPin, LOW);
    delay(22500);
    digitalWrite(EMagnetPin, HIGH);
    delay(500);
    digitalWrite(EMagnetPin, LOW);
    delay(500);                      // Stops EMagnet
    digitalWrite(solenoidPin, HIGH); //Start Solenoid
    delay(500);
    digitalWrite(solenoidPin, LOW);
    delay(500);
  }
}// please close all loops
// Program Ends

```

please remember to close all loops ,enter right spelling

I would suggest you to take a tutorial and also use a program like platformio or Arduino on vscode which will help you to write the code as it has auto code completion so you will always speel the right name for variables and also type the right function names.

Hope this helps.
> 1 votes

# Answer
Note that others already gave good answers; this is just a way to make your code more elegant.

This part:

```
  digitalWrite(EMagnetPin, low);
  delay(11000);
  digitalWrite(EMagnetPin, HIGH);
  delay(500);
  digitalWrite(EMagnetPin, low);
  delay(500);
  digitalWrite(EMagnetPin, HIGH);
  delay(500);
  digitalWrite(EMagnetPin, low);
  delay(22500);
  digitalWrite(EMagnetPin, HIGH);
  delay(500);
  digitalWrite(EMagnetPin, low);
  delay(500);                          // Stops EMagnet
  digitalWrite(solenoidPin, HIGH);     //Start Solenoid
  delay(500);
  digitalWrite(solenoidPin, low);
  delay(500);

```

You see there is a lot of duplication (`digitalWrite` plus `delay`).

The only things changing are the pin number, the pin state and the delay time (which is mostly 500).

You can create a new function for this, e.g. `digitalWriteWithDelay`:

```
void digitalWriteWithDelay(int pinNumber, int pinState, int delayTime = 500)
{
    digitalWrite(pinNumber, pinState);
    delay(delayTime);
}

```

Now you can rewrite

```
  digitalWrite(EMagnetPin, low);
  delay(11000);
  digitalWrite(EMagnetPin, HIGH);
  delay(500);

```

to

```
digitalWriteWithDelay(EMagneticPin, LOW, 11000);
digitalWriteWithDelay(EMagneticPin, HIGH);

```

and all subsequent lines similarly. Btw, it's best to use LOW and HIGH (keep the capitalization consequent). As you can see in the last line, 500 need not to be passed as it is the default value.
> 1 votes

---
Tags: programming, programming-sequence
---


# Question
Title: Deriving the exact relationship between PWM and steering
I am using a L298n driver to make a basic RC car. I realise that PWM is used to control the speed of the motors and that the car would turn when the wheels on one side of the car have a rpm different from the other side. I am taking user input from the x-axis of a joystick.

However, I am not sure how to arrive at an exact relationship between rpm and the angle by which the car turns.

My approach so far :

1. If the car is turning left, the wheels on the left side are turning in a smaller arc and hence the inner wheels have a lower rpm. The sharper the turn the slower the inner wheels turn.
2. PWM is used to control the speed of the motors.
3. Each angle of turning corresponds to circles of different radii. Hence a sharper turn would correspond to a circle with a very small radius.
4. So I need to map the x-axis values of the analog stick to angles by which I want the car to turn. Once I know the relation between rpm and the angle by which the car turns, I can map the joystick values to PWM values.

This question has already been asked here and the consensus seems to be that some sort of feedback mechanism is required for an exact calibration.

I have two questions :

1. Where do I learn more about this feedback mechanism?
2. Purely from a physics perspective, considering an ideal environment, how do I derive a relation between rpm and the steering angle?

# Answer
> Where do I learn more about this feedback mechanism?

It depends on the kind of feedback. You can have *absolute* or *relative* feedback. Relative would be, for example, to use an encoder on each wheel to find out how much it has turned. Absolute would be using a compass to know exactly what direction the vehicle is facing at any time.

> Purely from a physics perspective, considering an ideal environment, how do I derive a relation between rpm and the steering angle?

If you know how much each wheel has turned then it is really just simple trigonometry. You have two arcs that are the same proportion around the circumference of two circles. The circles must have the same centre point. Well, I say "simple" - that's a relative term. And of course it depends if you are moving like a car (i.e., turning while moving forwards) or like a tank (turning on the spot) as to whether such calculations are particularly meaningful.

But then of course that's only if you actually know the RPM. Which requires feedback.

There is no easy relationship between PWM and the angle turned. This is because PWM does not define the RPM:

* PWM defines the current
* The current defines the torque
* The torque defines the acceleration (and ultimately maximum speed) under different loads and conditions.

Those loads and conditions change depending on lots of factors. With no way to change the angles of the wheels they will need to slip on the surface as you turn. That adds friction and varies depending on both the speed at which you turn, the angle you turn through, and the surface you are driving on at the time. A high friction surface will both increase the power transfer and at the same time require more power to turn. A sharper turn angle will slip more and require more power to overcome the friction.

It's a very complex relationship with far too many variables. Which is why cars have steering mechanism to change the angle of the wheels, and some vehicles have rear-wheel steering as well to change the angle of the rear wheels to reduce slip and friction (such as the Porsche 911 and many large heavy vehicles), and why London cabs use "Ackermann" steering which gives each wheel a different angle while turning to increase the angle the vehicle can turn through so it can turn in the road easier.

So all in all if you want to know what direction you are pointing at any time, although it's harder to interface with and use, and may be a little more expensive, a compass or other absolute rotation sensor is the way to go.

If you want to turn to a specific angle, (or turn through a specific angle, which is just a relative change between two specific angles) then it's a case of "move a bit" then "see what angle I'm at" then "move a bit more" and "see what angle I'm at".

You could either use a simplistic approach where you always move in discrete steps, or use a PID to calculate what would be a good amount to turn to get you closer and closer to the desired angle depending on how far you turned last time.
> 2 votes

---
Tags: pwm, robotics
---


title: Need some Hardware advice with arduino

text:
# Question
Title: Need some Hardware advice with arduino
I am fairly new(having less hands on experience) to Arduino and electronics in general. I have a project for which I know the features and required electromechanical parts. I need some advice in choosing the right Arduino. Here's my requirement :-

I need the board to handle the following Hardware/Software parts -

1. 3 Geared motors,
2. 1 BLDC 1000 kva
3. 2 cameras ( one is also ok)
4. TinyML for object detection
5. Mic to receive audio commands
6. Speaker to talk back.
7. Wifi shield to send/receive information to internet or a laptop.
8. 3 small servo motors.
9. 2 Proximity sensor.
10. 1 dc motor (6-9v)

Please advice which Arduino board will be perfect for the above requirements. I was thinking of Arduino Mega 2560, but after looking into various projects I couldn't decide if it was sufficient as I have many hardware parts.

# Answer
To process incoming images, voice commands, produce sounds, and also do WiFi is almost certainly beyond the capabilities of any **micro** computer, like the Arduino (maybe some of the more recent models might). I strongly doubt that the Mega 2560 would. It doesn't have a heap of RAM for one thing (it has 8k of RAM). Look at the sizes of images produced by cameras these days, they are usually measured in megabytes, not kilobytes.

What might work for you would be a Raspberry Pi, which is basically a small Linux computer on a board, with a substantial amount of RAM.
> 4 votes

# Answer
Your main bottleneck here is the camera. If you want to do real time video, I would suggest getting a Raspberry Pi or the equivalent then using it as a master over something easier to code like an arduino.

The camera and wifi would be handled by the raspberry pi ( using Robot Operating software ) and the low level stuff like motor would be handled by the arduino ( any will do, since the main computing task will be left to the Pi ).

As for the machine learning, most microcontrollers can't handle it. If you want to do machine learning, I would suggest the NVIDIA range of single board computers instead of a Pi, since they have better GPU performance.
> 3 votes

# Answer
If your project is more for fun and not mission-critical, and you have an older smartphone you're no longer using, you can repurpose it. For the motors (BLDC, DC, servos) and proximity sensors you can use any arduino (e.g. Nano) through either its USB port (if it has OTG) or bluetooth (e.g. Pro Micro). Your Arduino code in this case would be very simple, just a few lines to send proximity data, and set servo angles and motor PWMs.

If you choose this path (if you CAN choose it), you can get the most CPU power, memory, and in general doing this in Kotlin or Java is simpler than on any 8-bit microcontroller (or probably on a RPi which is a very good choice otherwise). You can use its camera (very good on most phones), wifi, microphone, speaker, etc. as well. There are libraries for object detection, and many other things. Using its accelerometer, gyro, GPS, mobile internet, NFC, light sensor, touchscreen could be a plus. And they come with batteries (UPS included).

Of course you need to have an old phone (most people replace theirs in around 2-3 years, just ask around in your family and friends), buying one for this costs more than an SBC. Also, Android can kill your app if you're not careful (just uninstall/disable everything else you can, and this probably won't happen), so don't use this to control a nuclear power plant or similar. If you need to build more units, getting old phones becomes harder. But for hobby projects this could work. If not, just choose a SBC (like Raspberry Pi, Orange Pi, BeagleBoard, etc.).
> 1 votes

# Answer
I would suggest you to go with esp32 as it already has a Wi-Fi module and also the specs are pretty good

1. 2 CPU (one dual core and other one ultra low power)
2. frequency 240 MHz
3. flask size upto 16 megabytes
4. also a inbuilt BLE module
5. it has around 34 usable pins

Hope this helps.
> 0 votes

---
Tags: arduino-mega, shields, robotics
---


# Question
Title: Using an Arduino to rotate a DC motor once a minute (edited)
I’m trying to write an arduino sketch that makes a dc motor turns one full rotation every 60s similar to a clock. The arduino will be connected to the gate of a typical mosfet and the dc motor will be connected to the drain of the mofset such that the arduino controls the speed of the motor. Any suggestions on how I go about this? I’m using an arduino mega 2560 in case that’s relevant.

# Answer
> 1 votes
The best way would be to check the datasheet: https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561\_datasheet.pdf and set an interrupt on one of the timer.

Example code of this application can be found on this stack here : How to make 1 second delay more accurate?

Another way of doing it if you don't need to do anything between rotation would be to wait by just waiting using delay in a for loop. Be aware that this is less precise than interrupts driven wait. https://www.arduino.cc/reference/en/language/functions/time/delay/

edit : if you want to complete one full rotation every 60s

```
int i = 0;
while(1) {
  i++;
  delay(1000);
    if( i == 60){
    doFullRotation();
    i = 0;
    }
}

```

---
Tags: arduino-mega
---


# Question
Title: What is the purpose of the I/O pin capacitor on the AVR microcontroller?
What is the purpose of the capacitor on the I/O pins on the ATmega328 (I imagine it's on other AVR microcontrollers as well)? Is it to reduce noise from other parts of the microcontroller?

# Answer
To make explicit the implicit parasitic capacitance on the pin.
> 16 votes

# Answer
The pin does not have a capacitor added to the integrated circuit (IC). Rather this capacitor is drawn to show that the input has capacitance that you need to be aware of.

The input drives a MOSFET - and as we know, MOSFETs have some parasitic capacitance.

For more information on parasitic capacitance of MOSFETs see these pages:
> 1 votes

---
Tags: pins, atmega328, hardware
---


# Question
Title: Firmata: how to set a particular pin to high on boot?
I'm working on a project that use J5, so is using the standard firmata, this project is using an opto 4 channel relay, when the board is booting the pins state are set to low, so as soon as I power the board my relay goes to a close state and make my motor run... this is a wrong behaviour for my purpose. How can I avoid that? By googleing around I stumble acros this:

A possible solution

but I can't uderstand if this is what I'm looking for.. plus I need only the PIN 7 to be set high on boot, any help please?

**EDIT: SCHEMATICS**

4 Channel 5V Relay Module

# Answer
It would seem you are right. If I understood the source correctly, Firmata initializes all digital pins as OUTPUT LOW. Hard to believe, as this seems like a silly thing to do... My understanding is that:

1. `setup()` calls `systemResetCallback()` in order to set the initial pin configuration (line 779)
2. `systemResetCallback()` loops over all pins and calls `setPinModeCallback(i, OUTPUT)` for every pin `i` that is not an analog pin (line 732)
3. `setPinModeCallback()` calls `pinMode()` to set the pin to OUTPUT (line 325).

If my understanding is correct, then the simplest solution would seem to patch `systemResetCallback()` and replace `OUTPUT` by `INPUT` on line 732.
> 3 votes

# Answer
Just put `digitalWrite(anyPin,HIGH)` in `void setup()` this will make that specific pin `HIGH` to reset. It works for me.

```
void setup()
{
  digitalWrite(8,HIGH);
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);

  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
  Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
  Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
  Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
  Firmata.attach(SET_PIN_MODE, setPinModeCallback);
  Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.attach(SYSTEM_RESET, systemResetCallback);

  // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
  // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
  // Serial1.begin(57600);
  // Firmata.begin(Serial1);
  // However do not do this if you are using SERIAL_MESSAGE

  Firmata.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101
  }

  systemResetCallback();  // reset to default config
}

```
> 1 votes

---
Tags: arduino-uno, c++, c, firmata, johnny-five
---


title: How to use while(1) loop in arduino?

text:
# Question
Title: How to use while(1) loop in arduino?
I have been trying to exit from the `while(1)` loop by getting a value from the sensor and then run the code outside `while(1)`.But the problem is that it does not exit. How may I fix this problem?

See Code Below.......

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

void loop() {
    int sensor;
    while(1)
    {
        sensor = digitalRead(2);
        if(sensor == 0)
        {
            Serial.println("inside while loop");
        }
        break;
    }
    Serial.println("Break......");
}

```

# Answer
> 6 votes
In the Arduino paradigm, unlike ordinary C programming where there is only 1 entry point called "main()", there are 2 entry points called "setup()" and "loop()". "setup()" is called only once after booting up. But "loop()" is called over and over again right after "setup()" is called. There is no need to create your own infinite loop (for example a "while(1)" statement) as in ordinary C programming.

# Answer
> 1 votes
instead of while(1), one can use the variable name in while and change the value of the variable when you want to exit the loop. part of the code can be modified based on the following concept. `bool condition= true;
while(condition){
if (sensor==0)
condition=false;` This is my suggestion for the above problem.

# Answer
> 1 votes
Used like this

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

void loop() {
     bool cond = true;

int sensor;
while(cond)
{
    sensor = digitalRead(2);
    if(sensor == 0)
    {
        Serial.println("inside while loop");
    }
    cond = false;
}

  // like this you can used while inside the void loop()

}

```

---
Tags: arduino-uno
---


title: Infrared Low Frequency Transmission

text:
# Question
Title: Infrared Low Frequency Transmission
I have some basic code that I will soon expand for my project which is a universal remote for air conditioners. I have all of the codes but the problem is 3 of the codes are below 1khz. (500hz). My sketch doesn't allow for anything to go lower and the frequency in the actual code doesn't seem to go that low. 108 is 38khz.

```
uint16_t fuck[] = {0,108,0,0,347,173,22,22,22,22,22,22,22,65,22,65,22,65,22,22,22,22,22,65,22,65,22,65,22,22,22,22,22,22,22,65,22,65,22,22,22,65,22,22,22,22,22,65,22,22,22,22,22,22,22,65,22,22,22,65,22,65,22,22,22,65,22,65,22,65,22,1527,347,87,22,3692};
static uint16_t sent_array_numbers;
static uint8_t ir_seq_index = 4;
static uint8_t pin_state;

void ir_on()
{
  TCCR1A |= 192;
  pin_state = 1;
}

void ir_off()
{
  TCCR1A &= -193;
  pin_state = 0;
}

void ir_toggle()
{
  if (pin_state)
    ir_off();
  else
    ir_on();
}

void ir_start()
{
  DDRB |= 10;
  ICR1 = 416;
  OCR1A = 104;
  TCCR1A = 2;
  TCCR1B = 24;
  TIMSK1 = 1;
  ir_on();
  TCCR1B |= 1;
}

ISR(TIMER1_OVF_vect) {

  sent_array_numbers++;

  if (sent_array_numbers == fuck[ir_seq_index]) {
    ir_toggle();
    sent_array_numbers = 0;
    ir_seq_index++;

       }
}

void setup() {
  ir_start();
}

void loop() {

}

```

# Answer
> 1 votes
Your whole question is not very clear, so I will mainly give you explanations, of how the Timer code works (since you don't seem to understand that) and give hints.

Let's look at `ir_start()`, where you configure Timer1 for the IR operation:

```
void ir_start()
{
  DDRB |= 10;
  ICR1 = 416;
  OCR1A = 104;
  TCCR1A = 2;
  TCCR1B = 24;
  TIMSK1 = 1;
  ir_on();
  TCCR1B |= 1;
}

```

First you should better not use the decimal representation of numbers here. Most of them consist of single or few bits, that a bound to a specific configuration option. You can better see, what is going on, when you use hex or better binary. So instead of `DDRB |= 10;` you would write `DDRB |= 0b1010;` (`0b` marking the binary representation, and `1010` being the binary representation of 10). That makes it easier to read by others or by you, when you leave that code for a time and come back to it. Using decimal is good in the cases, where you write registers, that represent a single value (like `ICR1`).

Now let's go through each line. Here I will only state, what the line does, not if that makes sense or if it is correct.

```
DDRB |= 10;

```

is equal to `DDRB |= 0b1010` and will set will configure PB1 and PB3 (pin 9 and 11 on the Uno) as output pins.

```
ICR1 = 416;

```

sets the input capture register 1, which - when not in input capture mode - sets the TOP value of the Timer, meaning the max value, to which it will count until overflow.

```
OCR1A = 104;

```

sets the timer value, where the Timer will toggle the output compare pin A of Timer1 (PB1, aka pin 9) (of course only, if the output compare mode is activated).

```
TCCR1A = 2;

```

is equivalent to `TCCR1A = 0b00000010`. It disables the output compare mode, thus normal port operation. Also bit `WGM11` is set to 1 and `WGM10` is set to 0 (explanation with the next line).

```
TCCR1B = 24;

```

is equal to `TCCR1B = 0b00011000`. It sets `WGM12` and `WGM13` to one. Together with the other bits of the last line, this sets the Timer mode to FastPWM, counting to the value in `ICR1`, resetting there. Also the clock source bits are all set to zero, so disabling the Timer.

```
TIMSK1 = 1;

```

This enables the Timer1 overflow interrupt, and is of course equal to `TIMSK1 = 0b1`.

In `ir_on()` you use

```
TCCR1A |= 192;

```

which is equal to `TCCR1A |= 0b11000000`. It enables the output compare for OC1A, configured for setting it at the compare match and clearing it on resetting (also called inverted mode).

```
TCCR1B |= 1;

```

will set the clock source of the Timer to the main clock without any prescaler. A prescaler would scale the counter values. For example with a prescaler of 8 (setting the clock source bits to `0b010`) would mean, that the Timer value would increment by one every 8 clock transitions, instead of on every transition. Here you have no prescaler, so the Timer runs with full speed. You can make it slower by changing the prescaler. The fine tuning can then be done by changing the `ICR1` value, which is used as TOP. Setting the clock source will also turn the Timer on.

Then in `ir_off()` you use

```
TCCR1A &= -193;

```

Decimal `-193` is a value, that needs 2 bytes as a signed integer (twos-complement). It's binary value is `0b11111111 00111111`. You assign to a 1 byte register, so the high byte will be cut off. So you actually use the decimal value `63`. It will disable the output compare for OC1A, so disabling the PWM output on the OC1A pin.

So, to sum up the actual function of that code: The Timer is configured to run from 0 to 416 without any prescaler. At the value 104 the OC1A pin is set, on timer reset/overflow it is reset. The frequency of the signal will be `16MHz / 416 = 38,5 kHz`, with a duty cycle of `(416 - 104) / 416 = 75%`.

By changing ICR1 and OCR1A, you can go down to `16MHz / 65535 = 244Hz`. So for a frequency of 500Hz, you could use the ICR1 value `32000`. For the same duty cycle you then need the OCR1A value of 8000.

If you need an even lower frequency, you could use the prescaler by setting the clock source bits correspondingly.

Note: You use the timer overflow as your smallest time measure (since you are incrementing `sent_array_numbers` in the ISR). So by changing the Timer frequency, you also change the amount of time, that one increment of `sent_array_numbers` represents. While this time is `1 / 38.5kHz = 26.3us` with 38.5kHz, it will be `1 / 500Hz = 2ms` for 500Hz. Just keep that fact in mind, when writing the IR pulse values into the array.

You can read about all this in the datasheet of the Atmega328p, which is used in the Arduino Uno.

---

Notes besides the Timer configuration:

* Make sure, that all variables, that get changed inside of an ISR, are declared as `volatile`, so that the compiler knows, that the variable can change at any time and that it cannot optimize the access to it.
* Make sure, that the index, that you use with the array, is not exceeding the size of the array. Otherwise you will read from whatever was placed behind that array in the memory.
* Every variable should have a fitting speaking name, which tells exactly, what it is. Its function might not be that obvious, when you look at your code after a few years.
* The first 4 values in the array with the IR codes are not used. From your code I cannot understand, why. (Though you suggested, that this is not the complete code).

---

I hope, that helps. If not, then you need to be more precise with your question. And provide a complete compilable minimal example code.

---
Tags: arduino-uno, arduino-ide, infrared
---


title: Minimizing IR Detection Interference

text:
# Question
Title: Minimizing IR Detection Interference
I'll start by saying that the goal here is to have a hand/distance detection device. Basically touch-less button.

I managed to get it working with a simple 2-pin IR emitter and 2-pin IR detector using analog read from the detector to trigger an event. The problem is that I get interference from the sun on bright days.

Is there a way to pulse the emitter at a specific frequency and have the detector activate only on that frequency and keep the 2-pin setup?

One solution I have been leaning towards is changing the IR detector to a IR decoder and basically treat it as a remote control but I can't see a way to detect distance using this method.

I am also open to any other ideas on getting something like this to work, without IR or ultrasonic.

Thanks.

# Answer
> 1 votes
This is actually something I have been meaning to try but never got around to it.

My idea is to drive the LED with PWM with a 50% duty cycle. The frequency isn't really that critical, but you don't want it too high for the next part.

Now you sample the receiver at a fixed frequency that is at least 2x the frequency of the PWM into a buffer.

Then you perform FFT on that buffer.

The bucket that contains the frequency of the PWM should have a power value that is proportional to the distance.

Other light sources will be unlikely to affect the same bucket as the PWM frequency - most will only affect the lowest (0Hz+) bucket.

Or that's the theory that I came up with. I have yet to try it in practice.

---
Tags: ir, remote-control
---


# Question
Title: What is the most efficient voltage divider for Arduino?
I need to make voltage divider, so I could read a battery voltage up to 14.4 V. Could I use very high resistance resistors for that, so the current would be very low (to not to discharge battery)?

On the Internet there are examples with 500 - 2000 ohm resistors, but could I use hundreds of thousands to reduce the current to minimum? Would Arduino's analog input still read the value?

# Answer
> 11 votes
The most efficient is not to have a voltage divider at all. Or at least to only have a voltage divider when you actually need one.

My preferred schematic is this:

simulate this circuit – Schematic created using CircuitLab

With this M1 is normally kept turned off by R3. When you want to take a measurement you turn on M2 by setting D3 HIGH (or whatever pin you attached it to) which pulls down the gate of M1 turning it on. This then connects the batter to the voltage divider R1/R2 and allows you to read the voltage at A0.

The voltage divider of 20k / 10k allows you to read up to 15V on the battery, and gives you an output impedance of 6.67kΩ which is within the recommended maximum of 10kΩ for the ATMega's ADC.

During "idle" times when M1 and M2 are both off the only current flowing is the minuscule leakage current through M2 tempered by the large 100kΩ resistor R3 (which itself pales into insignificance compared to the "off" resistance of M2 anyway).

Selecting M1 so that the ON resistance is very small (\<0.1Ω) allows you to essentially ignore it in your calculations since that will be swamped by the tolerance of R1 and R2 anyway. M2 needs to be selected so that it is "logic level" (i.e, with a gate threshold V\_GS well below 5V).

This double-FET arrangement should be used rather than just using an N-channel FET in the ground connection of the divider because when that simpler arrangement is turned off the Arduino will be seeing 12V directly connected to A0 which really is not good - you *will* kill the Arduino - so it is important that you switch the "high" side of the network not the "low" side, and to do that requires two FETs.

# Answer
> 3 votes
Yes, you can use very high value resistors for your voltage divider. But the recommended maximum is 10 kohms for the ADC pins. So the combined resistance of your two resistors should be maximum 10 kohms.

> it is recommended that whatever you connect to the A/D have an output impedance of 10k or less for best accuracy. This is to allow the A/D input capacitor on the sample and hold to charge up in the time allotted to it between switching the input multiplexer over and starting the conversion.

From: *Input Impedance of A0-A5*

# Answer
> 1 votes
I was able to implement it with 3 MΩ resistors. The problem is that the readanalog() function executes 10 reads. So the first one is the right value and then you will not measure the right value anymore.

Solution: A voltage divider with 2.5 MΩ and 500 kΩ with a 470 nF capacitor on the 500 kΩ resistor. The solution with the MOSFET is better. This is easier, and it works (but only for 20 years ).

# Answer
> 0 votes
This is a variation on Majenko's design above. It was such a good idea, I couldn't resist submitting this - a *reduced-component-count* version:

simulate this circuit – Schematic created using CircuitLab

The **TPS22810** is a *load switch* that enables or disables Vout (**2.7V ≤ Vin ≤ 18V; Iout ≤ 3A**). The output is determined by the `EN/UVLO` input that may be driven by a 1.8 V, 3.3 V or 5 V GPIO output. This component and the C1 bypass cap replaces 2 FETs and 2 Resistors. The TPS22810 cost is  $0.50 ea. in small quantities.

The TPS22810 will likely find its most useful application as a *high-side switch*, but it seems to serve the purpose of the OP's need for driving a voltage divider also.

# Answer
> 0 votes
Everybody is missing the point here. The lower limit on the series resistance of the voltage divider is the self-discharge rate of the battery. For instance, a Li-ion battery loses about 10% of its charge per month. For a 3000 mAH 18650 cell, that's about 300 mAH per month, meaning about 300/(30X24) = 0.42mA constant drain. So, for a 8V stack made of 2 18650 cells in series, we get a total series resistance of 8V/0.42 of about 19K-ohms. IOW, if I put a 19K resistor across an 8V stack, I would get about the same battery drain as the battery would see if I left it completely alone. As long as the series resistance is much greater than that, it won't affect the battery life at all. So, if I use 2ea 50K resistors for a total series resistance of 100K, it will have very little effect on battery life. 2ea 50K resistors will present an effective output impedance of about 25K to the ADC input port on a MCU, and that is low enough so there will be little or no distortion of the measured voltage, and any offset can be easily compensated out in software. Moreover, if you want to go to a higher division ratio (say 4:1 instead of 2:1) the effective output resistance goes DOWN because it's a parallel circuit from the ADC's POV, but still a series circuit from the battery's POV. If I use a 75/25K divider for a 4:1 ratio, the parallel output impedance is 18.75K.

So, no need for fancy switching circuits - just choose a series divider with a convenient ratio and with a total series resistance in the 100K range, and you are done.

# Answer
> -2 votes
I don't see any problem with reasonably high resistors (however see below). You are right that they would discharge the battery less.

> Would Arduino's analog input still read the value?

Of course, if there was a voltage there to read. Why wouldn't it? A *really* high resistance might let the reading be affected by stray voltages.

A possible work-around would be to only take the reading occasionally, say, every 10 seconds. You could do this by making the reading be between a couple of Arduino pins, and leave one "floating" until you are ready to read it.

**However** that is not a good idea for reading a 12V battery. You need the voltage divider to be "active" so you don't have 12V on the Arduino input pin. Majenko's suggestion sounds better in that respect.

I have a lengthy discussion about the ADC on the Atmega328P. Reply #5 on that page discusses how it takes its measurements. This is done by charging a "sample and hold" capacitor. With too high an input impedance the capacitor would charge too slowly, and thus the subsequent sampling would give incorrect readings. A source signal impedance of 10k is recommended in the datasheet, so a voltage divider along those lines would be appropriate.

Majenko's suggestion of 20k + 10k would only involve a 0.4 mA constant current flow through the voltage divider, which for a 12V battery is probably not a huge deal (even without all that switching circuitry).

---
Tags: analogread, voltage-divider
---