body:
You may have a problem in the casting of the variable t vs the variable waittime.  t is an int and waittime is a long so when you multiply t by 1000L you may be picking up a couple of extra bytes used by other parts of the code:

For instance if t is stored at location 0x100:0x101 in RAM, and some other variable or random data is stored at 0x102:0x103, you pass 100 to the function in variable t which you expect multiplies into waittime as 100,000mS or 100S, but if the data stored at 0x102:0x103 for instance is randomly 0xFFFF, the multiplication into waittime actually works out to (100*65536)+65535 = 6,619,135mS or 1.83 hours.

The way around this is to either pass a long in the function or recast t to match waittime:

waittime = (long) t * 1000L;

Note that the order of the bytes depends on how the compiler handles variable storage.


sender: user

message:
Have I damaged my arduino?

I was trying to build a finger print lock system.. While my arduino was connected with my pc, I mistakenly plugged the adapter and turned it on. I immediately switched it off. It was working fine (port 3?) Now suddenly port 3 disappeared and the only available option I have is port 1, which is not working! My window is also alerting me that it didn't recognize the device. I searched for it in device manger but no others devices option is available

sender: assistant

body:
Which model of Arduino?

The design of most models has circuitry that handles getting power from both the barrel connector and the USB port, and switches between them intelligently.

Thus the answer should be "no, no problem." However, what else does your 12 adapter power? You might want to post a full circuit diagram of your project.

Also, as Juraj says, Arduino brand microcontrollers are designed to handle this situation. Knockoff models may cut corners.


message:
What can I do to increase the amount of LEDs I can power with a pro micro?

I am new to arduino and have a sparkfun pro micro that I'm using to power a one meter (60 pixels) APA 102 strip. I currently power it via USB and have a program that sends lighting instructions to it. I can only seem to power ~15 pixels with full range of brightness and ~30 if I keep the brightness at about half.

Anything more and the pro micro will stop recieving data and either freeze at the last color it's recieved or turn a bright red (which I assume is a visual indication of the fail because I didn't code that). At this point, the COM port will also become inaccessible until the code is either re-uploaded or in some cases, I simply disconnect the strip. This leads me to believe that the amount of power that I am demanding is too much for the board to put out.

So am I right in this assumption? and If so, what can I do to increase the amount of pixels I can power at full range?

I'll also post my code below in case there is something I can do there to increase the pixel amount:
<!-- language-all: lang-cpp -->
```
#include <Adafruit_DotStar.h>
#include <SPI.h>

#define NUMPIXELS 60
#define DATAPIN    4
#define CLOCKPIN   5

Adafruit_DotStar strip(NUMPIXELS, DOTSTAR_BRG);

// Variables
int mode;
int numColors;
int fadeSpeed;
int BBCC;
int R;
int G;
int B;
int Bright;

void setup() {

#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif

  strip.begin(); // Initialize pins for output
  strip.show();  // Turn all LEDs off ASAP
}

int      head  = 0, tail = -10; // Index of first 'on' and 'off' pixels
uint32_t color = 0xFFFFFF;      // 'On' color (starts red)

void loop() {

  //strip.setPixelColor(head, color); // 'On' pixel at head
  //strip.setPixelColor(tail, 0);     // 'Off' pixel at tail
  strip.show();                     // Refresh strip
  delay(20);                        // Pause 20 milliseconds (~50 FPS)

  getData();

  if (mode == 1)
  {
    for (int i = 0; i < (60); i++)
    {
      if (i % 2 == 0)
        strip.setPixelColor(i, G, R, B);
    }
    strip.setBrightness(Bright);
    strip.show();
  }
  else
  {
    for (int i = 0; i < (60); i++)
    {
      if (i % 2 == 0)
        strip.setPixelColor(i, 150, 200, 40);
    }
    strip.setBrightness(255);
    strip.show();
  }
}

int readLine(int readch, char * buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0)
  {
    switch(readch)
    {
      case '\r':
      {
        break;
      }
      case '\n':
      {
        rpos = pos;
        pos = 0;
        return rpos;
      }
      default:
      {
        if (pos < len-1)
        {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
      }
  }

  return 0;
}
}

void getData()
{
  char buf[80];
  bool redo = true;

  if(readLine(Serial.read(), buf, 80) > 0)
  {
    int i = 0;
    int j = 0;
    bool skip = false;
    char fin[3];
    if (skip == false)
    {
    do//                                mode
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          mode = atoi(fin);
          //Serial.print(mode);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do//                     number of colors
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          numColors = atoi(fin);
          //Serial.print(numColors);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do//
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          fadeSpeed = atoi(fin);
          //Serial.print(fadeSpeed);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          BBCC = atoi(fin);
          //Serial.print(BBCC);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          R = atoi(fin);
          //Serial.print(R);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          G = atoi(fin);
          //Serial.print(G);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          B = atoi(fin);
          //Serial.print(B);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }

    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          Bright = atoi(fin);
          //Serial.println(Bright);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }
  }
}
```

body:
> So am I right in this assumption?

Yep.

> and If so, what can I do to increase the amount of pixels I can power at full range?

Simple: don't power it from the Arduino. Add a proper external power supply that is capable of providing the current you require.


body:
As Majenko already mention, use a separate power supply.

- Use that power to power the LED strip(s).
- Use the MCU to control the data and clock lines.
- Connect grounds together.


body:
Managing your power budget is a normal part of electronics projects. You can only draw about 500 mA total from the USB port, and less than that from the 5V line if your Arduino is powered from USB. If you drive your Arduino with ≈7V into the barrel connector you might be able to pull a full amp from the 5V rail, but it depends on how hot the voltage regulator gets. The higher the input voltage into the regulator, the more heat you generate for a given amount of current. On a genuine Arduino board the voltage regulator should have an overheat protection circuit, which will cause it to shut off when it gets too hot. Cheap knockoffs may just burn out.

When you start using higher current devices like motors or LED strips, it's usually a good idea to switch to a separate (regulated) power supply for those devices. Tie the ground lines together, and since you use separate power supplies for the Arduino and your other devices, they don't affect each other's supply voltages.


message:
Forward kinematics of a differential drive robot

I've been braking my head over this for the past few days and can't make it work.. So, I have a small robot with a rotary encoder on each wheel and i want to track its position (in x and y) on a flat plane. I know it's called forward kinematics, but i can't seem to get it working. I found a lot of great public sheets, but i think, out of all of them, this is [the best one][1] It had the equations of how to calculate the X and Y on page 74:

> Vicc=L * (Din / (Dout–Din) + ½) (page 73) //Din is the inner wheel of the turn traveled distance, Dout is the outer wheel
>
> Xtδ=Xt+Vicc*(sin(θt+θΔ) – sinθt)
>
> Ytδ=Yt+Vicc*(cosθt - cos(θt+θΔ))
>
> θtδ=θt+θΔ //angle measurement

Where Xtδ and Ytδ are the position of the robot (x, y); Xt/Yt/θt is the position of the robot when the counting of the position has been started; θΔ is the angle of the robot now;

 . Here's [The code][2] that I tried to write using the equations. I expected it to write my coordinates in x and y, but when i moved the wheels, it sent me big, random numbers, which are fluctuating up and down, which looks like a sine wave. What am I doing wrong? Could you guide me to the right path? My end result, that I want to reach is controlling 2 both motor speeds and knowing the robots position (doesn't need to be very precise though).
Thanks in advance!

EDIT: Added code from PasteBin

    #include <Encoder.h>

    Encoder Left(3, 2);
    Encoder Right(0, 1);

    float R = 385; //mm
    float r = 12.5; //Wheel diameter in mm
    float L = 8; //Distance between the wheels in cm

    double LeftDist = 0;
    long LOldPos  = -999;
    float LNewPos;
    int Correction;

    double RightDist = 0;
    long ROldPos  = -999;
    float RNewPos;

    int angle= 0; // Robots current angle
    unsigned long t;

    int Xold= 0; //position at the start of the calculation
    int Xnew= 0; //new, calculated position
    int Ystart= 0; //position at the start of the calculation
    int Ynew= 0;//new, calculated position
    int OldAngle= 0; //angle at the start of the calculation
    int NewAngle= 0;// new angle at the end of the calculation
    int Vicc;

    void setup() {
      Serial.begin(9600);
      t = millis();
    }

    void loop() {
      Encoders();
      if ((millis() - t) >= 100) {
        Xold= Ynew; //setting the new position to old
        Yold= Ynew; // setting the new position to old
        OldAngle= NewAngle; //Setting the new angle to old

        Vicc = (L * (LeftDist / (RightDist / LeftDist))) + 0.5;
        Xnew= Xold + (Vicc * (sin(OldAngle + Angle) - sin (OldAngle))); //Calculation of X
        Ynew= Yold+ (Vicc * (cos(OldAngle) - cos(OldAngle+ Angle))); //Calculation of Y
        NewAngle = OldAngle+ Angle;

        t = millis();
      }

      Serial.print(angle);
      Serial.print("        ");
      Serial.print(Xnew);
      Serial.print("        ");
      Serial.println(Ynew);
    }

    //0.9mm/1 deg
    void Encoders() {
      LNewPos = Left.read();
      if (LNewPos != LOldPos) {
        LOldPos = LNewPos;
        LeftDist = ((LNewPos / 840) * (2 * r * 3.14)) / 10; //cm/ Rev
      }
      //-----------------------------------------------------
      RNewPos = Right.read();
      if (RNewPos != ROldPos) {
        ROldPos = RNewPos;
        RightDist = ((RNewPos / 840) * (2 * r * 3.14)) / 10; //cm/ Rev
      }
      angle= (abs(RightDist - LeftDist) * 0.9) - Correction; //calculate the angle the robot has turned
      if (fi >= 360) Correction += 360;
      else if (fi <= -360) Correction -= 360;
    }

  [1]: http://people.scs.carleton.ca/~lanthier/teaching/COMP4807/Notes/5 - PositionEstimation.pdf
  [2]: https://pastebin.com/e6S31U7F

body: From your use of the number 360 at the end of the Encoders() function, I am thinking that you are using degrees for the angles.  That won't work with sin and cos.  The trig functions all expect angles in radians.  To convert degrees to radians, multiply by PI/180.


message:
Why am I getting an 'invalid conversion' error on compile?

I have one of [these][1] NodeMCU ESP8266 OLED Arduino Wifi Modules which I am trying to load with SpaceHuhn's deauther software from [Github][2]

I am trying to compile the source code using Arduino IDE with the display enabled and have followed the instructions to do so from github repository [here][3].

I initially downloaded the latest software but as I didn't know which display option to enable before compiling, I went for an earlier version, [v1.6][4], which has a video on how you are supposed to install it on [YouTube][5].

After uncommenting line 18 from:

   `//#define USE_DISPLAY /* <-- uncomment that if you want to use the display */`

so that it reads:

`#define USE_DISPLAY /* <-- uncomment that if you want to use the display */`

and then trying to compile, I get this error:

    D:\Documents\Innovateking-EU Nodemcu ESP8266\Deauther\esp8266_deauther-v.1.6\esp8266_deauther\esp8266_deauther.ino: In function 'void setup()':

    esp8266_deauther:592:32: error: invalid conversion from 'const char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]

       display.setFont(Roboto_Mono_8);

    In file included from D:\Documents\Arduino\libraries\esp8266-oled-ssd1306-master\src/SSD1306Wire.h:34:0,

                     from D:\Documents\Arduino\libraries\esp8266-oled-ssd1306-master\src/SSD1306.h:33,

                     from D:\Documents\Innovateking-EU Nodemcu ESP8266\Deauther\esp8266_deauther-v.1.6\esp8266_deauther\esp8266_deauther.ino:28:

        D:\Documents\Arduino\libraries\esp8266-oled-ssd1306-master\src/OLEDDisplay.h:243:10: error:   initializing argument 1 of 'void OLEDDisplay::setFont(const uint8_t*)' [-fpermissive]

         void setFont(const uint8_t *fontData);

    Multiple libraries were found for "SSD1306.h"
     Used: D:\Documents\Arduino\libraries\esp8266-oled-ssd1306-master
     Not used: C:\Users\cos\AppData\Local\Arduino15\packages\deauther\hardware\esp8266\2.0.0-deauther\libraries\esp8266-oled-ssd1306-4.0.0
    exit status 1
    invalid conversion from 'const char*' to 'const uint8_t* {aka const unsigned char*}' [-fpermissive]

The youtube video shows the process working, assuming nothing was edited out....  As far as I can see I have done everything the same.

Has anyone had any experience of loading this on to these boards?  Or know what the problem is?

  [1]: https://www.amazon.co.uk/gp/product/B07JFD21SW/ref=ppx_yo_dt_b_asin_title_o00_s01?ie=UTF8&psc=1
  [2]: https://github.com/spacehuhn/esp8266_deauther
  [3]: https://github.com/spacehuhn/esp8266_deauther/wiki/Installation#compiling-using-arduino-ide
  [4]: https://github.com/spacehuhn/esp8266_deauther/releases/tag/v.1.6
  [5]: https://www.youtube.com/watch?v=elKXLAs3zII

body:
go in the data.h TAB

find : `const char Roboto_Mono_8[] PROGMEM = {`

and replace with : `const uint8_t Roboto_Mono_8[] PROGMEM = {`

Voilà


message:
Unable to burn bootloader with avrisp

I want to burn the arduino `optiboot_atmega328.hex` bootloader but it doesn't work. I remember that I was able to burn the BL using the arduino IDE which was quite easy, this time I'm having some problems.

I'm always using an avrispv2 programmer to flash my atmegas and it was also this programmer I used once to burn the BL. When I try, the IDE gives the following output:

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

             System wide configuration file is "/home/xxx/Downloads/arduino-1.8.7-linux64/arduino-1.8.7/hardware/tools/avr/etc/avrdude.conf"
             User configuration file is "/home/xxx/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

             Using Port                    : /dev/ttyACM2
             Using Programmer              : stk500v1
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

    avrdude done.  Thank you.

    Fehler beim Brennen des Bootloaders.

After this didn't work I tried to manually upload the `optiboot_atmega328.hex` with avrdude on the commandline ([following this guide][1]). The output of avrdude is as follows:

    avrdude -b 19200 -c avrispv2 -p m328p -v -e -U efuse:w:0x05:m -U hfuse:w:0xD6:m -U lfuse:w:0xFF:m -P /dev/ttyACM2

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

             System wide configuration file is "/etc/avrdude.conf"
             User configuration file is "/home/tabaluga/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

             Using Port                    : /dev/ttyACM2
             Using Programmer              : avrispv2
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500V2
             Description     : Atmel AVR ISP V2
             Programmer Model: STK500
             Hardware Version: 10
             Firmware Version Master : 2.10
    avrdude: stk500v2_command(): command failed
    avrdude: stk500v2_getparm(): failed to get parameter 0x9a
             Topcard         : Unknown
             Vtarget         : 3.3 V
             SCK period      : 17.4 us
             Varef           : 3.3 V
             Oscillator      : Off

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.00s

    avrdude: Device signature = 0x1e950f (probably m328p)
    avrdude: safemode: hfuse reads as D9
    avrdude: safemode: efuse reads as FD
    avrdude: erasing chip
    avrdude: reading input file "0x05"
    avrdude: writing efuse (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of efuse written
    avrdude: verifying efuse memory against 0x05:
    avrdude: load data efuse data from input file 0x05:
    avrdude: input file 0x05 contains 1 bytes
    avrdude: reading on-chip efuse data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: verification error, first mismatch at byte 0x0000
             0xfd != 0x05
    avrdude: verification error; content mismatch

    avrdude: safemode: hfuse reads as D9
    avrdude: safemode: efuse reads as FD
    avrdude: safemode: efuse changed! Was 5, and is now fd
    Would you like this fuse to be changed back? [y/n] y
    avrdude: safemode: Wrote efuse to 5, read as fd. 9 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 8 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 7 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 6 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 5 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 4 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 3 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 2 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 1 attempts left
    avrdude: safemode: Wrote efuse to 5, read as fd. 0 attempts left
    avrdude: and COULD NOT be changed
    avrdude: safemode: Fuses not recovered, sorry

    avrdude done.  Thank you.

As I'm unable to set the fuses it's no wonder that the actual upload doesn't work as well:

    avrdude -b 19200 -c avrispv2 -p m328p -v -e -U flash:w:optiboot_atmega328.hex -U lock:w:0x0F:m -P /dev/ttyACM2

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

             System wide configuration file is "/etc/avrdude.conf"
             User configuration file is "/home/tabaluga/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

             Using Port                    : /dev/ttyACM2
             Using Programmer              : avrispv2
             Overriding Baud Rate          : 19200
             AVR Part                      : ATmega328P
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
               lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500V2
             Description     : Atmel AVR ISP V2
             Programmer Model: STK500
             Hardware Version: 10
             Firmware Version Master : 2.10
    avrdude: stk500v2_command(): command failed
    avrdude: stk500v2_getparm(): failed to get parameter 0x9a
             Topcard         : Unknown
             Vtarget         : 3.3 V
             SCK period      : 17.4 us
             Varef           : 3.3 V
             Oscillator      : Off

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.00s

    avrdude: Device signature = 0x1e950f (probably m328p)
    avrdude: safemode: hfuse reads as D9
    avrdude: safemode: efuse reads as FD
    avrdude: erasing chip
    avrdude: reading input file "optiboot_atmega328.hex"
    avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
    avrdude: writing flash (32768 bytes):

    Writing | ################################################## | 100% 0.00s

    avrdude: 32768 bytes of flash written
    avrdude: verifying flash memory against optiboot_atmega328.hex:
    avrdude: load data flash data from input file optiboot_atmega328.hex:
    avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
    avrdude: input file optiboot_atmega328.hex contains 32768 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 32768 bytes of flash verified
    avrdude: reading input file "0x0F"
    avrdude: writing lock (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of lock written
    avrdude: verifying lock memory against 0x0F:
    avrdude: load data lock data from input file 0x0F:
    avrdude: input file 0x0F contains 1 bytes
    avrdude: reading on-chip lock data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: verification error, first mismatch at byte 0x0000
             0xcf != 0x0f
    avrdude: verification error; content mismatch

    avrdude: safemode: hfuse reads as D9
    avrdude: safemode: efuse reads as FD
    avrdude: safemode: Fuses OK (E:FD, H:D9, L:62)

    avrdude done.  Thank you.

I personally doubt that the µC or my programmer are bricked because I'm able to upload program code via ISP as I always used to, also I've tried two different ATmega328p.

Do you see what I'm doing wrong?
Why does one actually have to change fuses before flashing the bootloader (just curious)?

[1]: https://learn.sparkfun.com/tutorials/installing-an-arduino-bootloader/all

body:
I can see you are on Linux so I won't give you instructions for using AVR Studio - but do know that if you have access to a Windows machine that is another option you could try.

I can't tell you exactly why it is not working through the Arduino IDE - it could be that the settings are not set correctly or any number of reasons. What I can say is that it is not seeing the AVRISPmkII. Try turning on verbose mode in the Arduino SE settings.

However when using avrdude, you are requesting the efuse be set to 0x05. The value of 0x05 (or b0000 0101) means that you are requesting a brownout detection of 2.7V. But because only the last 3 bits of the fuse are relevant, the chip fills the rest of the bits with 1 not 0. So b0000 0101 (aka 0x05) becomes b1111 1101 (aka 0xFD), hence you get a mismatch.

Also, according to my `\Arduino-x.x.x\hardware\arduino\avr\boards.txt` file, the fuses for the Arduino/Genduino Optiboot are:

 - low_fuses=0xFF
 - high_fuses=0xDE
 - extended_fuses=0xFD

Change your avrdude command to the following:

    avrdude -b 19200 -c avrispv2 -p m328p -v -e -U efuse:w:0xFD:m -U hfuse:w:0xDE:m -U lfuse:w:0xFF:m -P /dev/ttyACM2

The last block of output in your question shows that you are trying to load the optiboot hex file. That part works so it seems, as it writes and verifies successfully. The interesting part is the lock bit fails verification. It is reading 0xCF which means it is in bootloader protection mode #3: LPM and SPM prohibited in boot loader section.

From the datasheet:

> SPM = Store Program Memory instruction
> LPM = Load  Program Memory instruction

And

> SPM is not allowed to write to the Boot Loader section, and LPM executing from the Application section is not allowed to read from the Boot Loader section. If Interrupt Vectors are placed in the Application section, interrupts are disabled while executing from the Boot Loader section.

But it appears that these lock bits can be removed by doing a chip erase:

> The Boot Lock bits can be set in software and in Serial or Parallel Programming mode, but they can be cleared by a Chip Erase command only.

And

> The Chip Erase will erase the Flash and EEPROM(1) memories plus Lock bits. The Lock bits are not reset until the program memory has been completely erased. The Fuse bits are not changed. A Chip Erase must be performed before the Flash and/or EEPROM are reprogrammed.

So it looks like you need to do a full chip erase with avrdude.

----------

For reference I use the following fuse calculators:

 - http://www.engbedded.com/fusecalc/
 - http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega328p


message:
Two Arduino boards with I2C sensors

I am new and lost. I have been searching the internet about how to transfer data of multiple sensors from one Arduino to another using I2C but no luck. All the codes and tutorials online focus on multiple slaves with one sensor.

The attached Fritzing is not my project, but my project involves 22 pressure sensors and I need to log their readings in Excel using plx, so the picture is just for demonstrating the idea.

The main idea is to transfer the sensors' data from the slave to the master over I2C.

I just need an answer if this doable or not plz

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/GhaqD.jpg

body:
There's two basic ways of doing it.

1. Send a byte from the master to the slave *first* to select which sensor you want, then request the data for the currently selected sensor, or
2. Request lots of bytes from the slave and fill them in one at a time as the requests arrive.

The first way is the slow, but "I2C" way of doing it - basically each sensor is its own register in the slave, and you select which register you want to read from.

The second way is faster, but you have to keep track internally of where you are.

A good compromise is to implement "auto increment" which does both scenarios: if you send a byte it sets the current sensor to read from. Then each read returns the current sensor and increments the sensor number internally in the slave, so the next read will get the next sensor.

That way you have a way to "reset" the sensor index that you are reading from, and it's reasonably quick to get all the sensors, since you just need to do multiple reads after a single write.


message:
Is the arduino nano 33 IOT schematic wrong?

As am i was copying the schematics of the arduino nano 33 IOT from the [Official arduino schematic][1] i noticed something was wrong in the schematic, specifically in the PRTV5V component

Here is a snip on the schematic
[![enter image description here][2]][2]

It would seems that the pin numbering on the PRTR5V is wrong. Here are snippits from the [PRTR5V Datasheet][3]

[![enter image description here][4]][4]
[![enter image description here][5]][5]

The sample schematic does look like the same of the arduino but if you look at it using the pin number it is different.For example on the arduino schematic pin 2 is at the middle of the two diodes, while on the datasheed pin 2 is before the diodes.

Now which one should i follow? Did arduino intentionally pin it that way ?

  [1]: https://content.arduino.cc/assets/NANO33IoTV2.0_sch.pdf
  [2]: https://i.stack.imgur.com/Clnva.jpg
  [3]: https://assets.nexperia.com/documents/data-sheet/PRTR5V0U2F_PRTR5V0U2K.pdf
  [4]: https://i.stack.imgur.com/FYUTu.jpg
  [5]: https://i.stack.imgur.com/EXqAy.jpg

body:
It is correct. You are looking at the wrong datasheet.

This is the correct one:

* https://assets.nexperia.com/documents/data-sheet/PRTR5V0U2X.pdf


message:
Can I disable the TX pin by setting its mode to INPUT while still receiving data on the RX pin of a UART?

I'm using the ATmega328PB in a personal project with MiniCore. My board streams data in on the RX pin from another microcontroller, but my board also has a DIP switch connected to the TX pin, that's used for configuration. My board has already been manufactured, so a hardware solution means a board redesign and extra cost/time.

This DIP switch is connected between TXD (Arduino pin "1") and GND. Upon startup, I read the value of this pin when in mode INPUT_PULLUP. However, when I go to start the Serial, if this switch is in the closed position, it shorts the TXD pin to GND.

**Is it possible to disable the TX pin by putting it into INPUT mode while still receiving data on the RX pin?**

body:
Well, I ended up answering my own question in a few minutes of forum research.

You can disable the TX pin of the hardware UART with:

    UCSR0B &= ~bit (TXEN0);


message:
invalid conversion from 'const char*' to 'char*' [-fpermissive]

With WebSocket various messages arrive.

Task:

 1. Find message "setBrightness: 15"
 2. Extract the value "15" from the message (the value can be any)
 3. Convert this value to uint8_t

My code:

    #include <string.h>

    String payload_str = "setBrightness: 15"; // WebSocket message
    const char* payload = payload_str.c_str(); // Convert string to char

    const char* value; // Message value
    uint8_t brightness;

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

      if(strncmp(payload, "setBri", 6) == 0) { // Search message
       value = strtok(payload, " ");
       value = strtok(NULL," "); // Get value (15)
       brightness = (uint8_t)atoi(value); // Convert to uint8_t
      }
    }

    void loop() {}

Compilling error:

> error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
>
> error:   initializing argument 1 of 'char* strtok(char*, const char*)' [-fpermissive]

Maybe I'm doing it completely wrong and not safe. How can this be fixed?

body:
`strtok` modifies the char buffer entered as first parameter. It replaces the delimiters with terminating zeros. To parse a constant string with `strtok`, you must first copy it into a working char buffer.

For your test you can initialize a char array as in following example.

    char payload[] = "setBrightness: 15";

    uint8_t brightness;

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

      if(strncmp(payload, "setBri", 6) == 0) { // Search message
       strtok(payload, " ");
       const char* tok = strtok(NULL," "); // Get value (15)
       brightness = (uint8_t) atoi(tok); // Convert to uint8_t
      }
    }

    void loop() {}

----------

if you know the 'name' part of the name:value string, you can skip it for `atoi` this way:

`brightness = (uint8_t) atoi(payload + strlen("setBrightness: "));`

(`strlen("setBrightness: "` will be evaluated at compile time to a constant number)

    const char payload[] = "setBrightness: 15";

    uint8_t brightness;

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

      if(strncmp(payload, "setBri", 6) == 0) { // Search message
         brightness = (uint8_t) atoi(payload + strlen("setBrightness: ")); // Convert to uint8_t
      }
    }

    void loop() {}


message:
why data value is 0

i want to apply formula. but getting 0 at output.

#include "HX711.h"
int data;
HX711 scale(A1, A0);		// parameter "gain" is ommited; the default value 128 is used by the library

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

  scale.set_scale(2280.f);
  scale.tare();

}

void loop() {
  Serial.print("one reading:\t");
  data==(scale.get_units()/10);
  Serial.println(data);

		        // put the ADC in sleep mode
  delay(500);

}

body:
It's zero because you never assign it a value.

Here you are comparing the current value of `data` (0) with the results of your calculation:

    data==(scale.get_units()/10);

I think you intended to use the assignment, not comparison, operator `=`:

    data = (scale.get_units()/10);


message:
Can I use this board to control multiple vibration motors?

I am looking at this: https://learn.adafruit.com/16-channel-pwm-servo-driver

Although it’s meant for servos, I was wondering if I could use them to control vibration motors.

Motors like these: Diameter Flat Button Type 3V-4.5V Cellphone Micro Vibration Motor (Pack of 3) https://www.amazon.in/dp/B07CQXZBZD/ref=cm_sw_r_cp_tai_yzSvDb8V7JAF4

Any suggestions? I would like to control about 200 motors with minimal number of controllers.

Each motor should be controllable individually.

body:
Not directly, no.  Those boards are designed to generate a low power PWM signal for passing to a servo with a built-in controller. To use that output directly with a motor you will need to add a transistor to each output to control the motor.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/bbfWT.png)

<!-- End schematic -->


message:
how to interrupt the loop function and restart it?

I have a project with some NeoPixels and other LEDs and an Arduino UNO.
Once switched on, the `defaultLEDAnimation` with colors and blinking, etc. starts.

I want to trigger some other animations, so I connected two buttons to the Arduino. Whenever you press `button1`, the Arduino should stop everything it is doing and run `animation1`. The same goes for `button2`. if you press it, the Arduino should run `animation2`. All animations are quite complex and run for several seconds and even minutes.

**Now for the challenge**: How do I use the two buttons to immediately stop every animation happening and display the appropriate animation?

The tried using interrupts and connected the two buttons to pin 2 and 3.
**However, when I press the buttons, the animation starts after several seconds delay.** Is there any way to restart the loop function immediately after the interrupt has been made? Or is there another way to trigger my animations with those two buttons?

The code looks something like this:

    #define button1 2
    #define button2 3

    volatile bool shouldPerformButton1Action = false;
    volatile bool shouldPerformButton2Action = false;

    void setup() {
        attachInterrupt(digitalPinToInterrupt(button1), button1Pressed, RISING);
        attachInterrupt(digitalPinToInterrupt(button2), button2Pressed, RISING);
    }

    void loop() {
        if (shouldPerformButton1Action) {
            doAnimation1();
            shouldPerformButton1Action = false;
        } else if (shouldPerformButton2Action) {
            doAnimation2();
            shouldPerformButton2Action = false;
        } else {
            runDefaultAnimation();
        }
    }

    void button1Pressed() {
        shouldPerformButton1Action = true;
    }

    void button2Pressed() {
        shouldPerformbutton2Action = true;
    }

    void doAnimation1() {
        for(int i=0; i<10; i++){
            neoPixelStrip.setPixelColor(neoPixelArray[i], neoPixelStrip.Color(255, 0, 0, 255));
            neoPixelStrip.show();
            delay(100);
        }
        delay(1000);
        for(int i=0; i<10; i++){
            neoPixelStrip.setPixelColor(neoPixelArray[i], neoPixelStrip.Color(0, 0, 0, 0));
            neoPixelStrip.show();
            delay(100);
        }
    }

The function `doAnimation1` is just an example. It will be much more complex.

body:
"How to interrupt the loop function and restart it?"

You don't. That's not how you write Arduino code. You need to have your loop function call a series of non-blocking functions that check to see if it's time to do something, do a very small bit of work if it is time, or just return if it's not time yet.

What I've done is to create a class ArduinoObject that has a setup function,  a start function, a stop function, a loop function, and a boolean property `running`. My main program has a global variable that holds an array of `ArduinoObject`s.

Every time through the loop, I check all the `ArduinoObject`s in the array, and call their loop functions.

The first thing each object does is check its `running` flag. If `running==false`, it exits immediately.

Each object uses unsigned long values to track the next `millis()` time count when it should do something.

Let's say the object does an animation, so it has an unsigned long `nextAnimationStepTime`. In the `loop()` function, if `nextAnimationStepTime<millis()`, it doesn't do anything. If instead `nextAnimationStepTime>=millis()`, the object advances the animation to the next step, and sets `nextAnimationStepTime = millis() + animationStepDuration`. That way, next time the object is called, it will wait until it's time to advance the animation yet another step.

Each object is written to only do a tiny bit of work on each pass through the loop, and return as quickly as possible.

With this design, I can add an arbitrary number of objects/tasks to my loop, and all of them get attention on every pass through the loop. Most objects simply decide they're not running, or it's not time to do anything, and return.

You can then add control logic that starts and stops individual objects based on things like button presses.

With this approach you'd have your button 1 press stop animation 2 if it was running and run animation 1. Conversely, pressing button 2 would stop animation 1 if


body:
Basically you have to make the animation loops return if the condition is met, for example:

    void doAnimation1() {
        for(int i=0; i<10; i++){
            if (digitalRead (button1) == HIGH)  // Time to stop?
               return;
            neoPixelStrip.setPixelColor(neoPixelArray[i], neoPixelStrip.Color(255, 0, 0, 255));
            neoPixelStrip.show();
            delay(100);
        }
        delay(1000);
        for(int i=0; i<10; i++){
            if (digitalRead (button1) == HIGH)  // Time to stop?
               return;
            neoPixelStrip.setPixelColor(neoPixelArray[i], neoPixelStrip.Color(0, 0, 0, 0));
            neoPixelStrip.show();
            delay(100);
        }
    }

If you don't want to wait for the 100 ms delay (or the 1000 ms delay) then you could replace that with code that waits for 100 ms to elapse, but also checks the button.

Interrupts are not the way to do it. Interrupts let you briefly stop doing something, do something else, then go back to what you were doing before. They don't "interrupt" your entire workflow.

For example, you might interrupt your movie watching to answer the phone, you don't "interrupt" your movie watching to go out to dinner with a friend. That is just a case of doing a different thing.


message:
SPIMemory does not write always correctly

I'm using a WinBond 25Q128FVIQ (Flash 128 mbit, 3.3V) in combination with the [Marzogh SpiMemory][1] library on my Arduino Nano (also 3.3V).

After using the default example, I found out what was read, did not always fully match what I wrote. So I created a slightly alternative example writing 16 bytes:

    #include<SPIMemory.h>

    uint32_t address;

    #define BAUD_RATE 115200
    #define RANDPIN A0

    //SPIFlash flash(SS1, &SPI1);       //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus
    SPIFlash flash;

    bool readSerialStr(String &inputStr);

    void setup() {
      Serial.begin(BAUD_RATE);
    #if defined (ARDUINO_SAMD_ZERO) || (__AVR_ATmega32U4__)
      while (!Serial) ; // Wait for Serial monitor to open
    #endif

      flash.begin();
      Serial.println(F("Flash Test"));
      Serial.print(F("Capacity: "));
      Serial.println(flash.getCapacity());

      char writeBuffer[16] = "0123456789ABCDEF";
      char readBuffer[17];

      for (int n = 0; n < 5; n++)
      {
        memset(readBuffer, 17, 0);
        randomSeed(analogRead(RANDPIN));
        address = random(0, flash.getCapacity() - 16);
        bool err = flash.writeAnything(address, writeBuffer, true);
        delay(50);
        Serial.print(F("Write: "));
        Serial.println(err);
        for (int m = 0; m < 10; m++)
        {
          if (flash.readAnything(address, readBuffer, true))
          {
            Serial.print(m);
            Serial.print(F(", read: "));
            Serial.print(readBuffer);
            Serial.print(F(", from address: "));
            Serial.println(address);
          }
          delay(50);
        }
      }
    }

    void loop() {

    }

    //Reads a string from Serial
    bool readSerialStr(String &inputStr) {
      if (!Serial)
        Serial.begin(115200);
      while (Serial.available()) {
        inputStr = Serial.readStringUntil('\n');
        Serial.println(inputStr);
        return true;
      }
      return false;
    }

Short explanation: 5 times I write a string (hex numbers), and I read this 5 times. The result is: (one example, differs every time):

     Flash Test
    Capacity: 8388608
    Write: 1
    0, read: 0123456789ABCDEF, from address: 6252204
    1, read: 0123456789ABCDEF, from address: 6252204
    2, read: 0123456789ABCDEF, from address: 6252204
    3, read: 0123456789ABCDEF, from address: 6252204
    4, read: 0123456789ABCDEF, from address: 6252204
    5, read: 0123456789ABCDEF, from address: 6252204
    6, read: 0123456789ABCDEF, from address: 6252204
    7, read: 0123456789ABCDEF, from address: 6252204
    8, read: 0123456789ABCDEF, from address: 6252204
    9, read: 0123456789ABCDEF, from address: 6252204
    Write: 1
    0, read: 0123456789ABCDEF, from address: 5680766
    1, read: 0123456789ABCDEF, from address: 5680766
    2, read: 0123456789ABCDEF, from address: 5680766
    3, read: 0123456789ABCDEF, from address: 5680766
    4, read: 0123456789ABCDEF, from address: 5680766
    5, read: 0123456789ABCDEF, from address: 5680766
    6, read: 0123456789ABCDEF, from address: 5680766
    7, read: 0123456789ABCDEF, from address: 5680766
    8, read: 0123456789ABCDEF, from address: 5680766
    9, read: 0123456789ABCDEF, from address: 5680766
    Write: 0
    0, read: , from address: 5277398
    1, read: , from address: 5277398
    2, read: , from address: 5277398
    3, read: , from address: 5277398
    4, read: , from address: 5277398
    5, read: , from address: 5277398
    6, read: , from address: 5277398
    7, read: , from address: 5277398
    8, read: , from address: 5277398
    9, read: , from address: 5277398
    Write: 0
    0, read: , from address: 4941258
    1, read: , from address: 4941258
    2, read: , from address: 4941258
    3, read: , from address: 4941258
    4, read: , from address: 4941258
    5, read: , from address: 4941258
    6, read: , from address: 4941258
    7, read: , from address: 4941258
    8, read: , from address: 4941258
    9, read: , from address: 4941258
    Write: 0
    0, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    1, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    2, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    3, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    4, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    5, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    6, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    7, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    8, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153
    9, read: ⸮⸮⸮⸮⸮l⸮څ⸮w⸮r⸮0123456789ABCDEF, from address: 4689153

  [1]: https://github.com/Marzogh/SPIMemory

Conclusion: The write seems to be the problem as the read consequently returns the same value (either garbage or the correct string).

What do I wrong?

Actually, I even don't want the 50 ms delay (and when I remove it, the result is the same).

body:
I made a stupid mistake; I accidentally removed the next line at the end of the application which takes care of erasing the sector. If this is omitted, then the next time write actions will fail (or fail sometimes):

    flash.eraseSector(address);


message:
Arduino PWM 1kHz and 10-bit resolution

As the title says, I need 1khz frequency signal with 10-bit resolution. But I am not good with uControllers and complicated programming.

I need a simple code for this task.

I tried using this [Interactive PWM][1] from arduinoslovakia.eu but I dont know what the frequency is at 10-bit resolution and how to set frequency in this code.

  [1]: https://www.arduinoslovakia.eu/blog/2017/7/16-bitove-rozlisenie-pwm-pre-arduino?lang=en

body:
I see you are talking about using the 16-bit timer, which is Timer 1 on the Uno.

Assuming you are using a Uno this code will do it:

<!-- language: lang-c++ -->

    // Clock frequency divided by 1 kHz frequency desired
    const long timer1_OCR1A_Setting = F_CPU / 1000;

    const byte outputPin = 10;  // Timer 1 "B" output: OC1B

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

      // set up Timer 1
      // Fast PWM top at OCR1A
      TCCR1A = bit (WGM10) | bit (WGM11) | bit (COM1B1); // fast PWM, clear OC1B on compare
      TCCR1B = bit (WGM12) | bit (WGM13) | bit (CS10);   // fast PWM, no prescaler
      OCR1A =  timer1_OCR1A_Setting - 1;                 // zero relative
      OCR1B =  (timer1_OCR1A_Setting / 2) - 1;           // 50 % duty cycle
      }  // end of setup

    void loop()
      {
      }

You can change the 1000 in the calculation for timer1_OCR1A_Setting, within reason, to get other frequencies.

See [my page about timers](http://www.gammon.com.au/timers) for more background information.


message:
LED fader function freezes and becomes unresponsive after a few cycles

My LED controller has a color fader mode that I am making. The controller's loop() function grabs incoming serial data to set the amount of colors, fade speed, mode, and other info then runs the correct mode with the colors that it read from the serial port

When in color fader mode, the controller "freezes" at a certain color and becomes unresponsive to further input until I unplug it and plug it back in or reupload the code (the latter means that it still responds to something).

For testing purposes I am using red, green, and blue in that order. This stopping color can happen anywhere from in the middle of the transition from red to green in the first cycle to going through multiple cycles and stopping on blue depending on the fade speed. This only became a problem after I switched from using delay() to millis(). Why is that and what can I do to fix it?

The reason I switched to using millis is because the delays would stack infinitely and the arduino would become unresponsive to commands

Here is my relevant code:

```c
#include <Adafruit_DotStar.h>
#include <SPI.h>

#define NUMPIXELS 60
#define DATAPIN    4
#define CLOCKPIN   5

Adafruit_DotStar strip(NUMPIXELS, DOTSTAR_BRG);

// Variables
int mode;
int numColors;
int fadeSpeed;
int BBCC;
int R[100];
int G[100];
int B[100];
int Bright[100];

int currColor;

void setup() {

#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif
  strip.begin(); // Initialize pins for output
  strip.show();  // Turn all LEDs off ASAP

  currColor = 0;
}

void loop() {
  strip.show();                     // Refresh strip
  delay(20);                        // Pause 20 milliseconds (~50 FPS)

  getData();

  switch (mode)
  {
    case 1:                  // Mode 1: Solid Color
    {
      for (int i = 0; i < NUMPIXELS; i++)
      {
        if (i % 2 == 0)
          strip.setPixelColor(i, G[0], R[0], B[0]);// Sets whole strip to Color 1
      }
      strip.setBrightness(Bright[0]);
      strip.show();
      break;
    }
    case 2:                  // Mode 2: Multi Color Fader
    {
      colorFade();
      break;
    }
    case 3:                  // Mode 3: Multi Color Pattern
    {
      int j = 0;
      for (int i = 0; i < NUMPIXELS; i++)
      {
        if (i % 2 == 0)
        {
          strip.setPixelColor(i, G[j], R[j], B[j]); // sets a repeating pattern
          if (j == (numColors - 1))
            j = 0;
          else
            j++;
        }
      }
      strip.setBrightness(Bright[0]);
      strip.show();
      break;
    }
    case 4:                  // Mode 4: Music-Reactive Wave Form
    {

      break;
    }
    case 5:                  // Mode 5: Music-Reactive Color Jump
    {

      break;
    }
    default:                 // Default Mode: Incandecent Simulation
    {
      for (int i = 0; i < NUMPIXELS; i++)
      {
        if (i % 2 == 0)
          strip.setPixelColor(i, 150, 200, 40); // Sets whole strip to default value
      }
      strip.setBrightness(255);
      strip.show();
      break;
    }
  }

}

void colorFade()
{
  int del = 100;     // 100 milisecond
  if (currColor >= numColors - 1)
  {

    int steps = fadeSpeed * del;
    int Rdiff, Gdiff, Bdiff, BrightDiff;

    Rdiff = R[0] - R[currColor];
    Gdiff = G[0] - G[currColor];
    Bdiff = B[0] - B[currColor];
    BrightDiff = Bright[0] - Bright[currColor];

    for (int i = 0; i <= steps + 5; i++)
    {
      for (int j = 0; j < NUMPIXELS; j++)
      {
        if (j % 2 == 0)
          strip.setPixelColor(j, (G[currColor] - (Gdiff * i)), (R[currColor] - (Rdiff * i)), (B[currColor] - (Bdiff * i))); // Sets whole strip to value
      }
      //strip.setBrightness((Bright[currColor] - (BrightDiff * i)));
      strip.show();
      //delay(del);
      int timer = millis() + del;
      while(millis() < timer)
      {

      }
    }
    currColor = 0;
  }
  else
  {
    int steps = fadeSpeed * del;
    int Rdiff, Gdiff, Bdiff, BrightDiff;

    Rdiff = R[currColor + 1] - R[currColor];
    Gdiff = G[currColor + 1] - G[currColor];
    Bdiff = B[currColor + 1] - B[currColor];
    BrightDiff = Bright[currColor + 1] - Bright[currColor];

    for (int i = 0; i <= steps + 5; i++)
    {
      for (int j = 0; j < NUMPIXELS; j++)
      {
        if (j % 2 == 0)
          strip.setPixelColor(j, (G[currColor] - (Gdiff * i)), (R[currColor] - (Rdiff * i)), (B[currColor] - (Bdiff * i))); // Sets whole strip to value
      }
      //strip.setBrightness((Bright[currColor] - (BrightDiff * i)));
      strip.show();
      //delay(del);

      int timer = millis() + del;
      while(millis() < timer)
      {

      }
    }
    currColor++;
  }
}
```

body:
The problem with the above code lies with overflow. timer should be an unsigned long, because millis() outputs an unsigned long. This causes the freeze because after timer hits its upper limit, This setup works better:

```c
unsigned long timer = (unsigned long)millis() + del;
      while((unsigned long)millis() < timer)
      {
        //wait for as long as del says to
      }
```

This setup should be able to run for a long time without overflowing


message:
strcat parameters throwing pointer errors in my tcp server / parser application

I am attempting to use an Arduino Uno WiFi Rev2 board to integrate some lonely data. I will use the NINA WiFi chipset and associated libraries to start a server that will periodically request and receive client information hosted on multiple types of devices that will run concurrently; thus it's pretty much divided in 2 sections:
1.) Manage the client connections and their character arrays
2.) Parsing the information and responding accordingly from a control aspect

This is what I have so far, and what I was just compiling the other day:

    #include <stdlib.h>
    #include <SPI.h>
    #include <WiFiNINA.h>

    char ssid[] = "***";                // House -- Network SSID (name)
    char pass[] = "***";              // House -- SSID password (WPA2-PSK)

    #define MAX_CLIENTS 5
    #define MAX_LINE_LEN 50
    char inputs[MAX_CLIENTS][MAX_LINE_LEN] = {0}; // Instantiate 2D array of
    client/received data
    int msg_array[] = {0,0};
    int net_status = WL_IDLE_STATUS;              // The Wifi radio's status
    WiFiServer server(80);           // Create server object on port of WiFi
                                     // server, which will be used to
                                     // respond to commands

    WiFiClient *clients[MAX_CLIENTS] = {NULL};    // Create client objects
                                                  // limited to size of
                                                  // MAX_CLIENTS

    byte mac[] = {0xDE,0xAD,0xBE,0xEF,0xFE,0xED}; // Arduino's physical MAC
    byte ip[] = {192,168,9,25};              // IP of this controller
    byte gateway[] = {192,168,0,1};          // Router address (internet)
    byte subnet[] = {255,255,0,0};           // Subnet mask

    unsigned long wd_Dside, wd_Cside = millis();   // Gather current tstamp
    unsigned long wd_Delap, wd_Celap = 0;          // Create an elapsed time
                                                   //counter

    void setup(){

       pinMode(4, OUTPUT);                 // pin selected to control D SIDE
       pinMode(5, OUTPUT);                 // pin selected to control C SIDE

       //enable serial data print
       Serial.begin(9600);
       while (!Serial){
           Serial.println("No serial.");
       }

          Serial.println("Serial.begin was initiated.");

       if (WiFi.status() == WL_NO_SHIELD) {  // check for the WiFi module:
          Serial.println("Wi-Fi: Communication with NINA has failed!");
          // do nothing here
          while (true);
       }

       String fv = WiFi.firmwareVersion();
       if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
          Serial.println("Please upgrade the firmware");
       }

       while (net_status != WL_CONNECTED) {
          Serial.print("Attempting to connect to WPA SSID: ");
          Serial.println(ssid);

          // Connect to WPA/WPA2 network:
          net_status = WiFi.begin(ssid, pass); // Attempt to join this SSID

          // wait 5 seconds for connection:
          delay(5000);

          listNetworks();

          server.begin();                      // Start Wi-Fi server
          Serial.print("Server started on ");
          Serial.println(WiFi.localIP());
        }
    }

    void loop() {

        delay(5);

        WiFiClient newClient = server.available(); // Begin listening for
                                                   // client messages
        if (newClient) {
            Serial.println("New client discovered."); // Could use this as
                                                      // an ACK/handshake on
                                                      // client-side host
            for (int i=0; i<MAX_CLIENTS; i++) {
              if (clients[i] == NULL) {
                clients[i] = new WiFiClient(newClient);
                break;
          }
       }
    }

        for (int i=0; i<MAX_CLIENTS; i++){      // Check client for data
          if (clients[i] != NULL && clients[i]->available()){
             // If the data isn't garbage and the data is available..

            char newChar = clients[i]->read();
            // Read the data

            if (newChar == 'x') {
            // Check for a termination character for separation

            // Now parse with strtok in order to get parameterization
              char delimiters[] = ",";
              char* valIndex;
              valIndex = strtok(inputs[i], delimiters);
              for (int j=0; j < 2; j++){
                // Expand later to largest anticipated character count
                msg_array[j] = atoi(valIndex);
                Serial.print(msg_array[j]);
                valIndex = strtok(NULL, delimiters);
              }

              switch(msg_array[0]) {
              // Determine type of message received (Character 0 parsed as
              // Message Type)

                case '3':
                // Examine string for client cmds to turn sides on or off.
                if(msg_array[1] == '1')
                // Msg type 3, Instruction 1: Turn D side ON
                  {
                    digitalWrite(4, HIGH);
                    // Set pin 4 high
                    Serial.println("Dside started.");
                    wd_Delap = 0;
                    // Reset elapsed time watchdog time value for D side.
                    wd_Dside = millis();
                    // Last good heartbeat from client device on D side.
                  }
                if(msg_array[1] == '2')
                // Msg type 3, Instruction 2: Turn D side OFF
                  {
                    digitalWrite(4, LOW);
                    // Set pin 4 low
                    Serial.println("Dside stopped");
                    wd_Delap = 0;
                    // Reset elapsed time watchdog time value for D side.
                    wd_Dside = millis();
                    // Last good heartbeat from client device on D side.
                  }
                if(msg_array[1] == '3')
                    // Msg type 3, Instruction 3: Turn C side ON
                  {
                    digitalWrite(5, HIGH);
                    // Set pin 5 high
                    Serial.println("C side started.");
                    wd_Celap = 0;
                    // Reset elapsed time watchdog time value for C side.
                    wd_Cside = millis();
                    // Last good heartbeat from client device on C side.
                  }
                if(msg_array[1] == '4')
                    // Msg type 3, Instruction 4: Turn C side OFF
                  {
                    digitalWrite(5, LOW);
                    // Set pin 5 low
                    Serial.println("C side stopped.");
                    wd_Celap = 0;
                    // Reset elapsed time watchdog time value for C side.
                    wd_Cside = millis();
                    // Last good heartbeat from client device on C side.
                  }
                break;

                case '6':

                    // Examine string for another message type TBD
                break;

                default:
                  Serial.println("Default break. Received crap.");
                break;

              }

            inputs[i][0] = '\0';
            // Clear out this array element for the next message
            // clients[i]->stop();
            // By default, kill client session, just wait for new TCP open
            // delete clients[i];
            // Remove client element's data
            // clients[i] = NULL;
            // Reset to NULL

            }

            else {

               if (strlen(inputs[i]) > MAX_LINE_LEN) {
                    // First check for size compliance
               Serial.println("Max line length exceeded from client.");
               inputs[i][0] = '0';
                    // Clear out this array element for the next message
               }
               else {
               **strcat(inputs[i], newChar);**
                    // Add character to the received string
               }

              Serial.println();
              Serial.println(newChar);
            }
          }

        // Update watchdog timers

        wd_Delap += (millis()-wd_Dside);
        wd_Celap += (millis()-wd_Cside);

        if (wd_Delap>=60000)
              {
                Serial.print("Elapsed time on watchdog, D side: ");
                Serial.println(wd_Delap);
                Serial.print("Last message received: ");
                Serial.println(wd_Dside);
                digitalWrite(4, LOW);    // set pin 4 low
                Serial.println("D side didn't hear from a client in 60s;
                               defaulting to OFF.");
              }

        if (wd_Celap>=60000)
              {
                Serial.print("Elapsed time on watchdog, C side: ");
                Serial.println(wd_Celap);
                Serial.print("Last message recieved: ");
                Serial.println(wd_Cside);
                digitalWrite(5, LOW);    // set pin 5 low
                Serial.println("C side didn't hear from a client in 60s;
                                defaulting to OFF.");
              }

       }
    }

I previously had this compiling and running, though with issues that I intedned on iteratively troubleshooting. Now it won't compile because of the following error:

>arduino:302:37: error: invalid conversion from 'char' to 'const char*' [-fpermissive]
>
>strcat(inputs[i], newChar);   // Add character to the received string

..which I have attempted to bold above in the final else clause. I realize these parameters require pointers, but it seems like some of the other functions like strtok and strlen which ask for pointers as well seem to work okay in my code.

Are there any suggestions or alternatives to strcat() as to how I could make this work? I have mostly stuck with character arrays instead of declaring String objects. I am also obviously pretty rusty at C(++) as I haven't been actively working with it in a while.

Thank you

body:
`strcat` is a function to concatenate strings. It expects a char array as second parameter. You have only a single char `newChar` to add to your string.

    size_t l = strlen(inputs[i]);
    inputs[i][l] = newChar;
    inputs[i][l + 1] = 0;

Note: It would be better to track the length of the `inputs` then use `strlen`. `strlen` iterates over the array until terminating zero.


message:
Understanding datasheet of a HCHO gas sensor

I have a gas sensor whose datasheet is attached:
[DS-HCHO][1]

Now it says that UART communication is needed (P2P) where it (module) waits for Data Frame before tx the data frame to host which I need.

All i know is that I can send start bit in I2C but how shall I proceed.
Also if I have multiple sensors how shall I connect them to ESP-32?

  [1]: http://allsensing.com/product/detail.html?product_no=1195&cate_no=93&display_group=1

body:
First, you need to be communicating by UART, *not* I2C.  That means using Serial or some similar object (On ESP32 you can define your own on whatever pins you want).  However, the datasheet omits one vital piece of information: the baud rate it communicates at - so you will have to guess that and try various different standard baud rates until you find the one that works.

Then you have to send the "Give me the data" instruction.  The module then responds with the data.

For example (untested):

    HardwareSerial mySerial(1);

    #define PIN_RX 21
    #define PIN_TX 22

    void setup() {
        Serial.begin(115200);
        mySerial.begin(9600, SERIAL_8N1, PIN_RX, PIN_TX); // This is the one you need to guess since the DS omits it...
    }

    void setup() {

        // Once a second send the request to get the data

        static uint32_t ts = millis();
        if (millis() - ts > 1000) { // Once a second
            ts = millis();
            // "Give me the data"
            mySerial.print("\x42\x4d\x01\x00\x00\x00\x90");
        }

        // When 10 or more bytes have arrived then assume that they are correctly
        // framed and print them.  Really it should read one byte at a time and
        // look for the correct start sequence of 0x42 0x4d 0x08 and read only
        // from there, but this will server for demonstration purposes.

        if (mySerial.available() >= 10) { // We expect 10 bytes returned
            uint8_t packet[10];
            mySerial.readBytes(packet, 10);
            Serial.print("ID:   ");
            Serial.println(packet[3]);
            Serial.print("UNIT: ");
            Serial.println(packet[4]);
            Serial.print("VH:   ");
            Serial.println(packet[5]);
            Serial.print("DHH:  ");
            Serial.println(packet[6]);
            Serial.print("DLL:  ");
            Serial.println(packet[7]);
            Serial.print("LRCH: ");
            Serial.println(packet[8]);
            Serial.print("LRCL:   ");
            Serial.println(packet[9]);
        }
    }


message:
How to connect LED lights for 3D Printed Robot

I'm new here and a newbie in electronics. I have a project to create a 3d printed robot with lights. I came across neopixels led's and the ardruino microcontrollers recently and find it to be a great possible sollution for what I need.

For my project, the 3d printed toy will have several parts that would need lights and I plan to use roughly over 40 LEDs connected to one source. I' m thinking of using the WS2812B LEDs.

I plan to use one neopixel ring for the robot's chest similar to Iron-Man's arch reactor.. While the head head will have 2x LEDs for the eyes, a smaller neopixel ring for the headpiece, another 2x LEDs for on the side of the robot mouth and 3x LEDs inside each vents on both sides of the robots head.

I need all the LEDs to turn on with a white light with a switch and turn red with another button. Although, I'd still be happy if they can only work with white.

For the power source, I was thinking about using a small powerbank or 2x 18650 batteries as the power source.

As mentioned, I'm very new to electronics and based on my research so far, i get confused really fast from all the jargons used and I'm not sure how to proceed.

Hopefully, i can get some answers here.

So.... My question is, is it possible to connect all the LEDs i plan to use on one microcontroller (ie: Ardruino Uno or Nano)

Most of the examples I can see on youtube are projects using LED strips. Are they diffrences in the way they are connected?

Another problem is coding for the ardruino..i'm totally clueless.

Any suggestions or help would be very much appreciated.

body:
The key point for WS2812B LEDs is, that they can be daisy chained. This means, that everyone of them has one data input and 1 data output. If you connect the data output of one LED to the data input of the other, you created a short strip with 2 LEDs. Doing this multiple times creates a bigger LED strip. It's not relevant, if the LEDs are arranged into a physical strip, or arranged into complex forms. The LEDs are addressed by their position in the strip. The microcontroller sends a data stream to the first LED. It will read the first 3 bytes (1 byte per color) and forward the rest of the stream to it's data output, so to the next LED.

So you can wire all the LEDs on your robot in a way, that you basically only have 1 LED strip. In this case you only need 1 pin on your Arduino (plus Vcc and ground of course).

Or, if it's to cumbersome to wire all LEDs together, you can make multiple strips, divided by zones on your robot (like 1 strip for the face, 1 strip for the chest, ...). Every strip will need it's own pin on the Arduino.

Which way you go is your decision and also depends on how many pins you have free.

> My question is, is it possible to connect all the LEDs i plan to use on one microcontroller (ie: Ardruino Uno or Nano)

Yes, one microcontroller is plenty enough for this. As I wrote, for 1 strip you only need 1 data pin.

> Most of the examples I can see on youtube are projects using LED strips. Are they diffrences in the way they are connected?

This depends on what strips they have. If they use WS2812B strips, it is all the same. As said, the physical arrangement of the LEDs doesn't matter. But there are also other types of strips, for example the not-individually-addressable-single-color types, or the not-individually-addressable-RGB types (which often have one PWM line per color).

> Another problem is coding for the ardruino..i'm totally clueless.

Have a look at the [Adafruit Neopixel][1] library or the [FastLED][2] library (both on github). They are libraries, that will hide most of the complexity from you and will make it easy to control the LEDs. They both have examples, that you can use to get started. Adafruit also has good tutorials for this. You can google them.

> For the power source, I was thinking about using a small powerbank or 2x 18650 batteries as the power source.

I don't know, how much current these batteries can give you. I will leave that to you for your research. But be sure, that you can always provide the needed current. One WS2812B LED can draw up to 60mA (20mA per color), if you set them to full brightness white. So 40 WS2812B LEDs, can draw up to 2.4A. I guess, that your robot also has motors, which can also draw a big amount of current. So keep the total current draw in mind and don't ever try to draw this current through the Arduino (since this might fry the voltage regulator).

  [1]: https://github.com/adafruit/Adafruit_NeoPixel
  [2]: https://github.com/FastLED/FastLED


message:
to increase the reading and writing/printing speed of data from Arduino Nano to Raspberry Pi 3B+

In my project, I have to read the input pin number(send by RPi), where 8 sensors are attached to Arduino Nano, after reading Arduino Nano send the real-time values of all sensors through serial USB communication. All is fine, but my problem is that I need to speed up the sending of data since it takes to long to read from Rasberry pi.
I put the delay of 70 milliseconds but if I try to reduce more than that, I encounter a problem i.e data overwrites. My baud rate is 115200.
Kindly help me with the code to make it fast.
```
int analogInputPin;
float voltage;

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(115200);
}

void loop() {
  // if any data on the serial port are available
  // read it and try to update the analogInputPin
  // based on the number that was read on the serial
  if (Serial.available() > 0) {
    analogInputPin = Serial.parseInt();
  }

  // read the analog value:
  int analogInputPinValue = analogRead(analogInputPin);
  voltage=(5./1023.)*analogInputPinValue;

  // print the results to the serial port:
  // the output should have the following form: INPUTPIN:VALUE
  // followed by a newline character
  Serial.print(analogInputPin);
  Serial.print(":");
  Serial.print(voltage);
  Serial.println("");

  // wait 50 milliseconds before the next loop
  delay(50);
}
```

body:
`parseInt` reads digits and stops after a non-digit characters occurs or the function times out because no next characters arrives. The timeout is at default 1 second. So this is where you loose time.

Simplest solution for your code is to send some non-digit character after the number sent from Raspberry. This will terminate parseInt immediately. Usual is to send a new line character. It will separate the numbers nice if you debug the communication with prints to serial terminal.

Not a very good option, but I mention it, is to set the timeout of blocking read functions like the `parseInt` to a smaller time with `Serial.setTimeout(ms)`.

To really speed up the communication you would send the numbers in binary form and not as text like you do now.


message:
How to delegate code compilation to a remote machine?

Sometime I write Arduino code on a slow Windows laptop that I use for controlling hardware projects and 3D printing.

My main Windows computer and also my Linux home server are located somewhere else but are much faster and I would like to use those for compilation.

Remote Desktop or equivalent are not practical due to different screen resolutions. Also, my main Windows machine is not always on, only the server is, but it has no GUI installed.

The sources are already located on a shared network folder and I use an external editor for the code. Arduino IDE just does compilation and sometimes upload (which often I could do via OTA).

How to delegate compilation of Arduino projects to a remote machine?

body:
If you don't have a GUI, you can still compile and upload sketches by using the [Arduino CLI][1]. With it you can do most things, that you can do with the Arduino IDE. I'm using this myself to upload new code to a Nano, that is connected to a Raspberry Pi in a project in use.

You can connect via ssh to the remote server and let it compile/upload the sketch. I wrote a simple bash script to first copy the source to the server (since you are using a network share, this is not necessary for you) and invoke the compilation and upload.

Note: Before you can actually compile with the Arduino CLI, you have to download the correct core for your chip. This is described in the README of the linked github project.

  [1]: https://github.com/arduino/arduino-cli


message:
Wemos D1 won't work with MH-Z19B (CO2 sensor)

I would like to connect a CO2 sensor to the Wemos D1. I would like it to work via UART (RX, TX) and not the PWM pin. I've encountered numerous libraries on Github, but I can't seem to get it working. I've connected the following things:

[![enter image description here][1]][1]

I've tried a lot of snippets from all over the internet, and a lot of libraries on Github, but I can't seem to get it working. For the sake of this question, I am going to use this [advanced library][2].

This is my code:

    #include <Arduino.h>
    #include "MHZ19.h"                                         // include main library
    #include <SoftwareSerial.h>                                // Remove if using HardwareSerial or non-uno library compatable device

    #define RX_PIN D1                                          // Rx pin which the MHZ19 Tx pin is attached to
    #define TX_PIN D2                                          // Tx pin which the MHZ19 Rx pin is attached to
    #define BAUDRATE 9600                                      // Native to the sensor (do not change)

    MHZ19 myMHZ19;                                             // Constructor for MH-Z19 class
    SoftwareSerial mySerial(RX_PIN, TX_PIN);                   // Uno example
    //HardwareSerial mySerial(1);                              // ESP32 Example

    unsigned long getDataTimer = 0;                             // Variable to store timer interval

    void setup()
    {
        Serial.begin(9600);                                     // For ESP32 baudarte is 115200 etc.
        mySerial.begin(BAUDRATE);                               // Uno example: Begin Stream with MHZ19 baudrate
        //mySerial.begin(BAUDRATE, SERIAL_8N1, RX_PIN, TX_PIN); // ESP32 Example
        myMHZ19.begin(mySerial);                                // *Important, Pass your Stream reference
        myMHZ19.autoCalibration();                              // Turn auto calibration ON (disable with autoCalibration(false))
    }

    void loop(){
        if (millis() - getDataTimer >= 2000)                    // Check if interval has elapsed (non-blocking delay() equivilant)
        {
            int CO2;                                            // Buffer for CO2

            /* note: getCO2() default is command "CO2 Unlimited". This returns the correct CO2 reading even
            if below background CO2 levels or above range (useful to validate sensor). You can use the
            usual documented command with getCO2(false) */

            CO2 = myMHZ19.getCO2();                             // Request CO2 (as ppm)
            Serial.print("CO2 (ppm): ");
            Serial.println(CO2);

            int8_t Temp;                                         // Buffer for temperature
            Temp = myMHZ19.getTemperature();                     // Request Temperature (as Celsius)
            Serial.print("Temperature (C): ");
            Serial.println(Temp);

            getDataTimer = millis();                            // Update interval
        }
    }

I am constantly getting this:

```
19:39:59.750 -> !Error: Timed out waiting for response
19:39:59.784 -> !ERROR: Failed to verify connection(1) to sensor. Failed to stablise
19:39:59.853 -> !ERROR: Initial communication errorCode recieved
19:40:00.272 -> !Error: Timed out waiting for response
19:40:00.758 -> !Error: Timed out waiting for response
19:40:00.792 -> CO2 (ppm): 0
19:40:01.280 -> !Error: Timed out waiting for response
19:40:01.315 -> Temperature (C): -17
```

Am I connecting something wrong or what am I doing wrong?

**EDIT:**
Version using only the serial instead of library that also doesn't work:

```
#include <SoftwareSerial.h>
SoftwareSerial co2Serial(3, 1);
unsigned long startTime = millis();

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

void loop() {
  Serial.println("------------------------------");
  Serial.print("Time from start: ");
  Serial.print((millis() - startTime) / 1000);
  Serial.println(" s");
  int ppm_uart = readCO2UART();
  delay(5000);
}

int readCO2UART(){
  byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
  byte response[9]; // for answer

  Serial.println("Sending CO2 request...");
  co2Serial.write(cmd, 9); //request PPM CO2

  // clear the buffer
  memset(response, 0, 9);
  int i = 0;
  while (co2Serial.available() == 0) {
    Serial.print("Waiting for response ");
    Serial.print(i);
    Serial.println(" s");
    delay(1000);
    i++;
  }

  if (co2Serial.available() > 0) {
      co2Serial.readBytes(response, 9);
  }

  // print out the response in hexa
  for (int i = 0; i < 9; i++) {
    Serial.print(String(response[i], HEX));
    Serial.print("   ");
  }
  Serial.println("");

  // checksum
  byte check = getCheckSum(response);
  if (response[8] != check) {
    Serial.println("Checksum not OK!");
    Serial.print("Received: ");
    Serial.println(response[8]);
    Serial.print("Should be: ");
    Serial.println(check);
  }

  // ppm
  int ppm_uart = 256 * (int)response[2] + response[3];
  Serial.print("PPM UART: ");
  Serial.println(ppm_uart);

  // temp
  byte temp = response[4] - 40;
  Serial.print("Temperature? ");
  Serial.println(temp);

  // status
  byte status = response[5];
  Serial.print("Status? ");
  Serial.println(status);
  if (status == 0x40) {
    Serial.println("Status OK");
  }

  return ppm_uart;
}

byte getCheckSum(byte *packet) {
  byte i;
  unsigned char checksum = 0;
  for (i = 1; i < 8; i++) {
    checksum += packet[i];
  }
  checksum = 0xff - checksum;
  checksum += 1;
  return checksum;
}
```

  [1]: https://i.stack.imgur.com/kpCD2.png
  [2]: https://github.com/WifWaf/MH-Z19

body:
I know it is rather late to respond. What worked for me working with a *WEMOS D1 mini* and  the *MH-Z19C* was reassigning the Software Pins used *SoftwareSerial co2Serial(D1, D2);*
In that case the second sketch posted works atleast for me.

The problem might be that the ESP8266 uses the hardware serial lines for connection to the USB-to-Serial bridge (usually a CH340 or CP2102 in most designs) which means you might encounter problems if you want to use the same serial line for more than one device.


message:
How to return Char Array Value in Arduino IDE Function?

**Function**

    char* getConnectDetail(int starting){
      String data;
      for(int i=0;i< 1024 ;i++) {
        if(EEPROM.read(i+starting) != 0){
        data += char(EEPROM.read(i+starting));
        }
       }

       int str_len = data.length() + 1;
      char char_array[str_len];
      data.toCharArray(char_array, str_len);
      return char_array;
    }
When I call it I get the garbage value... without creating the function there isn't any error.. Kindly solve it.
I just want to know whats wrong with my returning method.

body:
`char char_array[str_len];` is local to the function - it is created on function entry and its memory is released on function exit. The contents of that memory are undefined once it has been released and its data may or may not be valid.

If the caller creates `data` and passes it to the function, it survives the entire function call-and-return, and the caller will find the correct data in it. Another (less elegant) way to do it is to make `data` a global object, which again, gives it a lifetime greater that that of the function, but globals are subject to accidental over-writes and abuse by other functions, so they are not recommended unless they are truly the best solution in a given situation.


message:
Why Won't my Serial Read value stay the same

I am trying to write to serial to control the brightness of an LED. When I initially type in a value such as '50' or '100', the LED lights up, but then the 'ppm' value drops down to '10' and just stays there (regardless of what I enter in initially. **Any idea why this is occurring?**
<!-- language-all: lang-cpp -->
```
int ledpin1 = 3;
int pwm = 0;

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  pinMode(ledpin1, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // reads input to serial monitor
  if (Serial.available() > 0) {
    pwm = Serial.read();
  }

  analogWrite(ledpin1, pwm);
  Serial.print("PWM value is: ");
  Serial.println(pwm);
  delay(1000);

}
```

body:
When you type "100" you aren't sending the number 100. You're sending the characters "1", "0", "0", and whatever selected line ending you have (CR, LF, or CR and LF).

So if you have CR+LF for your line ending you're reading the numbers 49, 48, 48, 13 then 10.

You need to read the characters as they arrive and group them into a representation of the number (up until you get the line ending), then convert that representation into an actual number.

* [Reading Serial on the Arduino](https://majenko.co.uk/blog/reading-serial-arduino)


message:
Callback functions when using a class

This question is somewhat similar to https://arduino.stackexchange.com/questions/56026/how-to-pass-non-static-class-member-to-callback, but there are a few differences, especially since a lot of my uses have "interesting" additional complexities. I'd like to understand better my options in using them, since I have not gained enough understanding from other answers (and I need to write both the callback and the function that calls it).

I have a number of libraries that produce "events" that I'd like to be able to write separate classes or functions to respond to (so I don't need to customize every library every time I develop something). The annoying part is that I've long-since discovered the `this` pointer that's hidden in class method calls, which prevents me from passing `currentgui.leftbutton` as a function to `menu.leftbuttonpressed(void (*callbackfuncptr)(void))`.

I'm **also** using the ESP8266 web server library, which needs a callback in the context of the server object that can call the server as a global to actually get the data sent to it! (Unless the server passes its *own* `this` as a parameter to the callback, *which I don't know* since the documentation consists almost solely of a small number of "examples" which don't show the majority of the actual features of the web server, rather than a real explanation.)

I could use some variant of a pointer to a class method, but the syntax for that is eye-gouging and I'm using more than one class to provide callbacks to (especially for the task scheduler), so this would require customizing the library to handle pointers to every class I use again. **I can't use polymorphism, either**, since some classes contain *multiple* scheduler callbacks to be done on different times/conditions.

*How do I handle these callbacks?* My current method is to write a function that wraps the method's function, but that relies on a specific instance of that method, so it can't be reused. It's also really awkward since I'm now dealing with multiple functions/methods that are now very similar.

I would **also** like to be able to have a class, that when passed a web server object, registers itself as a callback to a particular page event (I want to write a network connection manager similar to the WiFiManager library, but with the ability to integrate with an existing webpage. I have all the code, but it currently can't be nicely integrated into a standalone class because of this issue). It needs to store a pointer to the server object to get the data once the callback's called, but it also needs to be attached to the callback of the class that holds that particular pointer AND the other handler functions once the data's retrieved.
There is already a library that does something similar, but I can't figure out at all how this works, since I was under the impression that this is not possible. Can someone help me understand how the following class operates?
https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/src

body:
The ESP8266WebServer uses callback functions to handle HTTP request by your code. This callback functions can't be members of a class. But you can use [anonymous functions][1] to implement this callbacks. And if you like you can implement them as 'redirects' to functions of your objects.

    server.on("/leftbutton", []() {
      currentgui.leftbutton(server);
    }

Note: this anonymous functions are called lambda functions and they can do some tricks with parameters too

  [1]: https://en.wikipedia.org/wiki/Anonymous_function#C++_(since_C++11)


body:
> They call the same instance of the class' member functions to get data back.

Yes, but if they eventually call the class' member function to get data, other than static data, then the need to know what *instance* of the class to get the data from.

>  I'd like to know how to get a class I wrote (nothing special about it, but how do I connect it?) to register itself as a callback so IT gets data and I don't need a bunch of disconnected non-class functions around

If function X (not a member of this class) needs to be able to access the data from instance A or instance B then clearly X needs to know which instance it is looking at (the `this` pointer). This is not a syntax thing, you need to have a way of solving this problem.

In fact, when you say "a class I wrote" then that would also have instance data (its own `this`) so now you are trying to connect two instances of two classes.

How many server objects do you have? If just one in this particular case you might be able to fudge your way around it by storing its `this` somewhere, or making some glue routines.


message:
ESPAsyncWebServer how do you escape the % character?

% characters are used for [template processing](https://github.com/me-no-dev/ESPAsyncWebServer#template-processing) but I want it to just send the % through. How do you tell it to do that?

body:
You'd use `%%` to get a single `%` as output.

From the source code: [double percent sign encountered, this is single percent sign escaped.](https://github.com/me-no-dev/ESPAsyncWebServer/blob/fc71230a31c25ddebec7462d60cd495c919244c8/src/WebResponses.cpp#L402)


message:
Why does a function inside void set up is repeating after some minutes

I am trying to time sync my arduino hardware to NTP server. I have a `setSyncProvider(getNtpTime)´ function to do it and called inside the void setup. I have another function (mainFunction) inside the main loop, that calls every minute. I have added a function to display time inside this mainFunction so that time will update every minutes.  Code works fine for first five minutes. Then it calls the getNtpTime again even though it is not inside the loop. Why is it happening?
<!-- language-all: lang-cpp -->
~~~
time_t getNtpTime()
{
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  Serial.println("Transmit NTP Request");
  sendNTPpacket(timeServer);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Serial.println("Receive NTP Response");
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-(");
  return 0; // return 0 if unable to get the time
}

~~~

body: The `setSyncProvider` function of the TimeLib sets a function which will be called by the library every `interval` seconds. The `interval` is set with `setSyncInterval`. Default interval is 300 seconds.


message:
SIM800L HTTP request is not reliable

I have a question regarding SIM800L and HTTP GET request. I'm using this [https://exploreembedded.com/wiki/Setting_up_GPRS_with_SIM800L][1] simple code to communicate with SIM800l with AT commands. To perform the HTTP request, I use the following set of AT commands:

    AT+CFUN=1
    OK

    AT+CSTT="internet","",""
    OK

    AT+CIICR
    OK

    AT+CIFSR
    10.180.xxx.xx

    AT+CIPSTART="TCP","84.42.xxx.xx",80
    OK

    CONNECT OK

    AT+CIPSEND=52
    >
    GET /bakalarka.php/? HTTP/1.1
    Host:84.42.xxx.xx

    SEND OK
    HTTP/1.1 200 OK
    Date: Mon, 19 Aug 2019 16:20:27 GMT
    Server: Apache
    X-Frame-Options: SAMEORIGIN
    Vary: Accept-Encoding
    Transfer-Encoding: chunked
    Content-Type: text/html; charset=UTF-8

    10
    time201908191820
    0

    CLOSED

The problem is that sometimes. Or every other time, I don't get the whole HTTP answer. I usually get only the beginning. Something like this:

    AT+CIPSEND=52
    >
    GET /bakalarka.php/? HTTP/1.1
    Host:84.42.xxx.xx

    SEND OK
    HTTP/1.1 200 OK
    Date: Mon, 19 Aug 2019 16:20:27 GMT
    Server: Apac

and then after a couple of seconds, the connection closes.

    CLOSED

Do you know what could cause that? It's literally random. I need the information from the webpage (it's the current time) and currently, it's really unreliable.

Another question. What does the "10" and "0" mean in the HTTP request? The "time201908191820" is the current time from printed from PHP.

Thank you very much!

  [1]: https://exploreembedded.com/wiki/Setting_up_GPRS_with_SIM800L

body:
> Do you know what could cause that? It's literally random.

Could be your code, could be your network provider / signal. It's impossible to tell without you providing your code for us to inspect.

> Another question. What does the "10" and "0" mean in the HTTP request? The "time201908191820" is current time from printed from PHP.

Those look to be part of the response body - so they are printed by whatever the PHP script is that you are requesting. Either that or they are generated by your undisclosed Arduino program.


body:
Thank you for your answer. The code is as follows:

    #include <SoftwareSerial.h>

    String Arsp, Grsp;
    SoftwareSerial gsm(12, 8); // RX, TX

    String GET = "GET /bakalarka.php/? HTTP/1.1\r\nHost:84.42.xxx.xx\r\n\r\n";

    void setup() {

      Serial.begin(115200);
      Serial.println("Testing GSM SIM800L");
      gsm.begin(19200);

    }

    void loop() {

      AT("AT+CFUN=1");
      AT("AT+CSTT=\"internet\",\"\",\"\"");
      AT("AT+CIICR");
      AT("AT+CIFSR");
      AT("AT+CIPSTART=\"TCP\",\"84.42.xxx.xx\",80");

      int get_length;
      get_length = GET.length();

      AT("AT+CIPSEND=" + String(get_length));
      AT(GET);
    }

    void AT(String AT){

      gsm.println(AT);

      if(gsm.available()){

        Grsp = gsm.readString();
        Serial.println(Grsp);
      }
    }

I was thinking about a couple of things that could cause this.
1. Hardware design - some noise could cause a freeze of the GSM module while getting the answer from the server. After thinking through I don't think it's likely to be that. The power supply is made to be really beefy and there are enough bypass caps to reduce the noise and provide enough energy during current spikes. Also, the module doesn't freeze. It's still connected to the server, after a couple of seconds it closes the connection exactly as it should be.

2. Serial buffer gets somehow full. This was just a quick thought. The buffer of Arduino could get somehow full so it's not able to save any more incoming data. I think it's nonsense, but...

Thank you for your answers.

Krystof


body: I've figured it out. The answer to HTTP GET request was read as a string. The string has aroud 284 bytes. Since it's so big, string gets to be saved fragmented, which is apparently a problem. The solution is to create a buffer and save the characters there from the Serial.