message:
Preforming impedance termination for UART Communication (TX and RX) pins

I need two Arduino devices (Arduino Mega and Nano) to communicate with each other via UART. The two Arduino devices are long distance apart from each other. The distance is `1.5` meters.

 - The *Arduino 1* TX pin is connected to *Arduino 2* RX pin.
 - The *Arduino 1* RX pin is connected to *Arduino 2* TX pin.

Now, I have to use resistor to preform impedance termination so that the long distance does not cause transmitting and receiving issues between the two devices. I did some research and [*found*][1] an  image that shows the signal differences when impedance termination is preformed and when it is not.

[![enter image description here][2]][2]

I have *two* questions:

**1**. Since the distance between both Arduino devices is `1.5` meters, what resistor value should I use? How is that calculated?

**2**. Where do you put the resistors? It's not really clear on where to connect the resistors. Between ground and the RX pins on each device?

I don't know the gauge ratings of my wire but if that information is needed, I am using [this][3] wire.

  [1]: https://forum.arduino.cc/index.php?topic=489310.msg3343649#msg3343649
  [2]: https://i.stack.imgur.com/qHLvS.png
  [3]: https://www.banggood.com/1M-50M-5-Pin-Extension-Cable-Line-Cord-Wire-For-35285050-RGBW-LED-Strip-Light-p-1050044.html?ID=46118&cur_warehouse=CN

body:
The relevant parameter is not the length of the link, but its
[characteristic impedance][Z0]. For a twisted pair connection, this is
typically in the order of 100 to 120 Ω. It should be specified in
the datasheet. Your cable is not a twisted pair, but its geometry is
quite close. Just make sure that there is a ground or Vcc line between
the two data wires in order to minimize cross-talk. If you want to
compute that impedance yourself, here is an [online
calculator][calculator].

Connect the resistor in series with the TX pin, i.e. between the pin and
the data wire. Note that the pin already has an internal output
resistance of about 25 Ω, so you would add no more than 100 Ω
in series.

If you search online about termination resistors, you may learn tat they
are often put between the receive pin and ground, or even at both the
sending and the receiving end. In high frequency applications, the
latter is often the preferred configuration, as it prevents the signal
to be reflected from either end of the link. However, for logic-level
signals, that configuration would attenuate the signal too much. On the
other hand, terminating only at the receiver would put excessive load on
the TX pin. Thus, sender-side termination is your best option. A
resistor in series with TX does not prevent a reflection at the RX end,
but it prevents the reflected signal to be reflected again and cause
oscillations.

[Z0]: https://en.wikipedia.org/wiki/Characteristic_impedance
[calculator]: https://www.eeweb.com/tools/twisted-pair


sender: user

message:
Connecting Winsen ZE11-C2H4 Sensor to Arduino

How should I connect the [ZE11 Ethylene Sensor][1] to an Arduino Uno? I want to know how to attach the pins of the sensor to the Arduino and which resistor I should use. I'm very unprofessional at working with circuits so I most likely will need step-by-step help. To make things easier, I am attaching the datasheet associated with the sensor. The pin identification and technical parameters are on pages 3-4. Also if someone taught me how to do advanced coding for this project then that would be great. Please note that Winsen is a company based in China, so some things can be inaccurate because of translation. Any help is appreciated.

  [1]: https://www.winsen-sensor.com/products/gas-sensor-module/industrial-application-gas-sensor-module/ze11.html

sender: assistant

body:
Pin 5 & pin 6 are UART Bus. To use UART, connect pin 5 with TX pin on Arduino and pin 6 to RX pin on Arduino. Details about communication settings are at 4th page.
I can't find library for that sensor so guess you're on your own.

UART also Know as [Serial communication](https://www.arduino.cc/reference/en/language/functions/communication/serial/).


message:
Getting at the PS_ON pin on a RAMPS1.4 mounted to a Mega

Got it! Check end of post for solution.

I'm running a Mega 2560 with a RAMPS 1.4 Shield which is usually used for 3D printing applications. For my use case I only want to get at the stepper motor drivers. The RAMPS is pulling its own 12V power supply (using an old xbox 360 brick rated for 12V and have tested with a multimeter) and the Arduino is pulling 5V from an RPI. But for some reason I seem unable to get the stepper motor A4988 drivers to pull anything from the 12V power supply. The LED on the RAMPS turns on, and the stepper drivers are pulling a little power (also tested) but obviously not enough to get them to make the motors turn. In other words, the RAMPS isn't using the external power supply.

I'm NOT using any of the 3D printer firmware like Marlin since it can't compile on Raspbian and I only want to get at the Stepper Motor Drivers and now in my case the PS_ON pin...

Here's the schematic:

[![Schematic][2]][2]

My code for trying to get the motors to turn (and flip the PS_ON switch) is as follows:

    int PS_ON = 12;
    int X_STEP_PIN = 54;
    int X_DIR_PIN = 55;
    int X_ENABLE = 38;
    int NUM_OF_STEPS = 400;
    int WAIT_TIME = 500;
    int LED_PIN = 13;

    void setup(){

      digitalWrite(LED_PIN, HIGH);

      delay(2000);

      pinMode(PS_ON, OUTPUT);

      delay(20000);

      pinMode(X_DIR_PIN, OUTPUT);
      pinMode(X_STEP_PIN, OUTPUT);
      pinMode(LED_PIN, OUTPUT);
      pinMode(X_ENABLE, OUTPUT);

      digitalWrite(PS_ON, LOW);
      digitalWrite(X_ENABLE, LOW);

      digitalWrite(X_DIR_PIN, HIGH);
      for(int n = 0; n < NUM_OF_STEPS; n++){
        digitalWrite(X_STEP_PIN, HIGH);
        digitalWrite(X_STEP_PIN, LOW);
        delay(WAIT_TIME);
        digitalWrite(LED_PIN,!digitalRead(LED_PIN));
      }

      delay(3000);

      digitalWrite(X_DIR_PIN, LOW);
      for(int n = 0; n < NUM_OF_STEPS; n++){
        digitalWrite(X_STEP_PIN, HIGH);
        digitalWrite(X_STEP_PIN, LOW);
        delay(WAIT_TIME);
        digitalWrite(LED_PIN, !digitalRead(LED_PIN));
      }
    }

    void loop(){

    }

Any thoughts would be appreciated.

  [2]: https://i.stack.imgur.com/rVVmR.png "Schematic"

Here's how I got it to work.

Firstly if you're going to use a Xbox 360 PSU to power the RAMPS you need to tie together the red wire and the blue wire to force the box out of standby and make it give out a constant 12V (if you buy a 3rd party psu then the wire colors/layout will be different and you're on your own, but all the ones made by Microsoft for the base xbox 360 are color coded like this, including current Xbox One PSUs as far as I can tell).

There's also the option of connecting the blue to VCC and the red to GND on the RAMPS board (im not sure why that also works, but it's also mentioned in the docstring of the config.h or config_adv file under power supply settings in the Marlin firmware which is where I got the idea)

At that point, if you're reading 12V on a multimeter on the 5A rail of the RAMPS, make sure the RAMPS is able to power itself without the Arduino, if it can you should be good to go. There seems to be no need to get at the PS_ON at this point and you can power the RAMPS without any firmware.

body: Got it working without using any firmware, going to sleep. Will update post in the morning for how I got it working for anyone else with a similar question in the future.


message:
How to read the raw data from GY-85 module?

This module has 3 sensors. Gyroscope, Accelerometer and Magnetometer.

I think I'm reading the raw data in the wrong way.

For example, for the magnetometer HMC5883L, I'm using this code which I copied from a library and it gives the correct values, but when I use the same code for reading the raw data from the accelerometer ADXL345 then it's not what it should be according to different sources I've read.

1. The magnetometer HMC5883L:

  void HMC5883L_print_Serial(void)
  {
    int16_t x,z,y;
    uint8_t data[6];
    float heading,heading_in_degrees,declination_angle_YANBU;

    data_read(data);

    // This one doesn't
          x = data[1] << 8 | data[0];
    z = data[3] << 8 | data[2];
    y = data[5] << 8 | data[4];

    // This one works OK
          /*x = data[0] << 8 | data[1];
    z = data[2] << 8 | data[3];
    y = data[4] << 8 | data[5];*/

    heading = atan2(y,x);
    declination_angle_YANBU = ((3.0 + (52.0 / 60.0)) / (180 / M_PI));  // in yanbu city it's
    heading += declination_angle_YANBU;

    // Correct for heading < 0deg and heading > 360deg
    if (heading < 0){
   heading += 2 * PI;
    }

    if (heading > 2 * PI){
   heading -= 2 * PI;
    }

    heading_in_degrees = heading * 180 / M_PI;
    Serial.println(heading_in_degrees);
    _delay_ms(20);

  }

2. The accelerometer ADXL345

  void ADXL345_print_Serial(void){
    int16_t x,z,y;
    uint8_t data[6];

    ADXL345_read_raw(data);

          // This one gives values from -255 to +255
    x = data[1] << 8 | data[0];
    z = data[3] << 8 | data[2];
    y = data[5] << 8 | data[4];

          // This one give values from -32768 to +32768
    /*x = data[0] << 8 | data[1];
    z = data[2] << 8 | data[3];
    y = data[4] << 8 | data[5];*/
   Serial.print(x);Serial.print("\t");
   Serial.print(y);Serial.print("\t");
   Serial.println(z);
   _delay_ms(100);
  }

So basically I want to learn how to work with these sensors and also I want to know the principles about each one, because I'm confused between then I feel they are the same and each one provides similar functions; like, tilt sensing.

body:
One of the places where the datasheets for the sensors of the GY-85 module can be found is here: https://www.hotmcu.com/gy85-9dof-imu-sensor-module-p-298.html

The following information comes from these datasheets:

Both the HMC5883L and the ADXL345 have internal registers which are numbered consecutively. When reading more than one register they are most efficiently read in the order they are numbered. For each of the three axes both sensors use two 8-bit registers to hold the measured value.

In the HMC5883L the register with the lower number holds the most significant byte (MSB) and the register with the higher number holds the least significant byte (LSB). This means that in a consecutive read the MSB is read first followed bij the LSB. When you combine these two bytes into one 16 bit number (datatype int) you have to shift the MSB-holding byte (the first byte received) 8 places to the left and "OR-in" the LSB-holding byte (the second byte received).

In the ADXL345 the internal numbering is the other way around: the register with the lower number holds the LSB and the register with the higher nummer holds the MSB. When reading, the LSB is red first followed by the MSB. So this time you have to shift the second byte received and "OR-in" the first byte received.

Both sensors give the measured value as a 16-bit 2-complement number, corresponding to datatype int (Arduino Uno). An 16-bit int can hold values from -32,768 to +32,767 but the sensors don't (can't) use this full range:

The ADXL345 has an adjustable range with a maximum of 13 bits (-4096 to +4095).

The HMC5883L has a range of 12 bits (-2048 to +2047).


message:
I2C_graphical_LCD_display, fatal error: avr/pgmspace.h: No such file or directory

I have a problem with an ESP32 devkit V1 card. I'm trying to connect a WG12864A Winstar mod graphics display via the I2C MCP23017 adapter (RobotDyn), using Nick Gammon's `I2C_graphical_LCD_display.h` library.

Everything works well by connecting it to the Arduino Uno - Duemilanove board. Loading the sketch `LCD_Demo_Using_I2C` present in the library is compiled correctly without errors.

If I connect the display to ESP32 devkit V1, I try to compile it I get the following error:

    C: \ Users \ Topolino \ Documents \ Arduino \ libraries \ I2C_graphical_LCD_display-master / I2C_graphical_LCD_display.h: 62: 26: fatal error: avr / pgmspace.h : No such file or directory.
    Compilation terminated.
    exit status 1
    Error during compilation for DOIT ESP32 DEVKIT V1 card.

I tried to compile it with PlatformIO presents the usual compilation error.
You can help me, someone has some ideas to solve the problem.

body:
The authors of the ESP32 core didn't bother to create a proper set of compatability shims for the PROGMEM system - chiefly because it's not needed for ESP32 operation.

We did for chipKIT, though, and you can grab a copy of ours [here](https://github.com/chipKIT32/chipKIT-core/tree/master/pic32/cores/pic32/avr) and place it in with the core files for the ESP32 in your Arduino installation (you only need the `pgmspace.h` file, and place it in an `avr` folder inside the core source folder).

It's completely architecture agnostic and basically defines some pretty much empty macros, and maps `_P` variants of various functions to the non `_P` alternatives.


message:
How can I concatenate these two values as a string?

I've tried all the supposed solutions for the exact error, pasted into google, that I could find on every forum including this one and no matter the alleged solution I will either get the error about unsigned int to char*, the error below, or invalid pointers.

Why is this platform so completely unfriendly in data type conversion? It's almost as if the creator/s never wanted any data types to be able convert.

Here's my code that is apparently useless:

      char* DeviceName = "Device-" +  ESP.getChipId();
      wifiManager.autoConnect(DeviceName);

Error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
   char* DeviceName = "Device-" +  ESP.getChipId();

Then I tried to use the pointers, but I have no idea what I'm doing and I keep getting invalid pointer errors, and/or invalid conversion errors.

body:
You can use the c function sprintf(<dest>, <format>, <data>...)
The char array has to be big enough to hold your text plus a null to terminate the string.

    #include <Arduino.h>

    void setup() {
      Serial.begin(115200);
      delay(1000);
      char out[20];
      sprintf(out, "Device-X",ESP.getChipId()); // X\n formats the hex and pads with 0s.

      Serial.println(out);
    }

    void loop() {}

Output:

    Device-005D4D9D


message:
D1 mini does not resume operation as expected after deep sleep

I'm trying to get the D1 mini to return operation after `ESP.deepsleep()`. The code below compiles and gives the expected output for the first run. Five seconds after the announcement that that the device is going to sleep, there is a brief flash on the on board LED and I get a string of garbage on the serial monitor. Ideas for things to try would be appreciated.

    // Testing d1 mini deep sleep
    // D0 and RST are connected

    /*  platformio.ini:
      [env:d1_mini]
      platform = espressif8266
      board = d1_mini
      framework = arduino
      monitor_speed = 115200
    */

    #include <Arduino.h>

    void blink();

    void setup() {
      Serial.begin(115200);
      pinMode(D0, WAKEUP_PULLUP);
      pinMode(LED_BUILTIN, OUTPUT);
    }

    void loop() {
      blink();
      delay(1000);
      Serial.println("Going for some deep sleep");
      ESP.deepSleep(5e6); // 5e6 is 5 seconds
    }

    void blink() {
      digitalWrite(LED_BUILTIN, LOW);
      delay(500);
      digitalWrite(LED_BUILTIN, HIGH);
      delay(500);
    }

As you can guess I'm running this with platformio. The output on the serial monitor is:

    stefan@Cameron ~/.../Projects/Deep sleep $ platformio device monitor --baud 115200
    --- Miniterm on /dev/ttyUSB0  115200,8,N,1 ---
    --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
    Going for some deep sleep
    sl␀l��|␀�l�|␂␌␌␄�␄l�␌c|ǃ␃�␛�r�cd�c��gg�doo���␌cpp��$sd{d␛�{��o�c�gbx␀�

There is a blink of the LED on the first run, nothing there either after the apparent reset.

body:
The garbage is because the ESP8266 outputs boot information at 76800. This should include the boot reason and may help you understand why the code's not working as expected.

Try changing your Serial speed to 76800 in your code (just so that your messages don't end up being gibberish), use 76800 on platformio's monitor and you should be able to at least see what the D1 says it's doing.

You should see a line that ends in something like:

> rst cause: x, boot mode:(y, z)

_x_ should be 1 ("Power reboot"), 2 ("External reset or wake-up from Deep-sleep" - obviously what you want), 3 ("Software WDT" - the software watchdog went off) or 4 ("Hardware WDT reset" - the hardware watchdog timer went off)

boot mode indicates where the runtime image came from - _y_ should be 3 ("Flash"); anything else is really unlikely for your setup.

There's more info on this at [ESP8266 Reset Causes
and Common Fatal
Exception Causes](https://www.espressif.com/sites/default/files/documentation/esp8266_reset_causes_and_common_fatal_exception_causes_en.pdf)

If you try this please post how it goes! I'd like to hear more about what's going on here.


message:
Trying to run Timer1 in ATmega2560 with assembly

I have a slight problem with Timer1 in arduino (ATmega2560) while coding it in assembly. I try to run the Timer1 in CTC mode - I configure everything well in my opinion, but the TCNT1 just doesn't increment each clock cycle, as it should. I checked the registers in Atmel Studio and everything seems okay, but maybe I forgot about something?

Here is the code

    .ORG 0
 jmp start

    .ORG 0x22
 call isr_toggle_PA0

    .ORG 0x400
    start:
 LDI R16, HIGH(RAMEND)
 OUT SPH, R16
 LDI R16, LOW(RAMEND)
 OUT SPL, R16 ; initialize stack pointer
 clr r16

 ldi r16, 0xff
 out DDRA, r16 ; port A output
 ldi r16, 0x00
 out DDRD, r16 ; port D input
 clr r16

 ldi r20, 1<<OCIE1A
 sts TIMSK1, r20 ; enable Timer1 A comapre match interrupt
 sei

 ldi r20, HIGH(25000)
 sts OCR1AH, r20
 ldi r20, LOW(25000)
 sts OCR1AL, r20

 ldi r20, 0b00000010 ; CTC mode, int clk;
 sts TCCR1A, r20
 ldi r20, 0b000000101 ; prescaler /1024
 sts TCCR1B, r20
 ldi r20, 0
 sts TCCR1C, r20

 ; --- start main
    main:

    inc r16
    rjmp main
 ; --- end main

 isr_toggle_PA0: // toggle bit on PA0
  ldi r16,0x00000001
  in r17, PORTA
  eor r17,r16
  out PORTA, r17
  reti

Thank you and have a good day :)

body:
Here:

    ldi r20, 0b00000010 ; CTC mode, int clk;
    sts TCCR1A, r20
    ldi r20, 0b000000101 ; prescaler /1024
    sts TCCR1B, r20

you are setting the bit `WGM11` on `TCCR1A`. The timer then runs in mode 2 (PWM, Phase Correct, 9-bit) rather than mode 4 (CTC).


message:
Code working well on Arduino Uno is not working with Mega 2560

Following is the code block from my script. It uses timer1. Why it is not compatible with Arduino Mega?

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

    TCCR1A = theTCCR1A; // 0b10000010;
      /*10 clear on match, set at BOTTOM for compA.
       00 compB disconected initially, toggled later to clear on match, set at BOTTOM.
       00
       10 WGM1 1:0 for waveform 15.
       */
      TCCR1B = 0b00011001;
      /*000
       11 WGM1 3:2 for waveform 15.
       001 no prescale on the counter.
       */
      TIMSK1 = 0b00000001;
      /*0000000
       1 TOV1 Flag interrupt enable.
       */
      sei();             // Enable global interrupts.
      // Set outputs pins.
      DDRB   = 0b00000110; // Set PB1 and PB2 as outputs.
      pinMode(13, OUTPUT); // Set trigger pin to output

body:
It's not working because code you write is code that will work only on ATmega328. Every ATmega328 chip will run this code without any problem.
If you want that Mega does same task as Uno, then you have to rewrite whole code and use Arduino functions(such as `pinMode`, `digitalRead` etc..) or read [ATmega2560 datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf) and use ATmega2560 registers. Also Search for `ATmega2560 pin layout`, you'll need it if you want use registers.


message:
FastLED: Can't address led individually

I'm unable to access the first led in my strip with this code:

    void loop()
    {
      leds[0] = CRGB::White; FastLED.show(); delay(100);
      leds[0] = CRGB::Black; FastLED.show(); delay(100);
    }

Instead, it blinks 3 leds, though I expect it to blink only the first one.

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

Here's how my setup code looks like:

    #define DATA_PIN    1
    #define CLK_PIN   5
    #define LED_TYPE    WS2812B
    #define COLOR_ORDER RGB
    #define NUM_LEDS    60
    CRGB leds[NUM_LEDS];

    #define BRIGHTNESS          10

    void setup() {
      delay(1000); // Power-up delay

      // tell FastLED about the LED strip configuration
      FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

      // set master brightness control
      FastLED.setBrightness(BRIGHTNESS);
    }

The led was bought from here: https://www.aliexpress.com/item/0-5-5M-30-60-LEDs-M-2811-Pixels-Programmable-Individual-Addressable-LED-Strip-light-WS2811/32849630888.html?spm=a2g0s.9042311.0.0.8e664c4dU4dru2

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

body:
The description in the link of where you bought the strip says:

> Description:
>
> 1. LED Type: 5050SMD with External IC WS2811 （1 IC control 3leds）

So, this is probably as intended.

Note the application circuits in the [datasheet for the controller IC (WS2811)][1] [Page 5] where, for 5V, you can address a single LED, but for a 12V configuration, you must group the LEDs in sets of 3.

[![enter image description here][2]][2]

  [1]: https://cdn-shop.adafruit.com/datasheets/WS2811.pdf
  [2]: https://i.stack.imgur.com/kOXy2.png


message:
Receiving junk values in Arduino serial monitor console

I want to send a character from a Zigbee transmitter to an Arduino Mega 2560. After the character is received, Arduino should send some data back to Zigbee. But Arduino is always receiving junk values at the console. If I send a character, suppose 'a', instead of 'a', Arduino console is always showing 'y'. It is the same for every character I send.

    #include <EEPROM.h>
    #include <SoftwareSerial.h>
    SoftwareSerial XBee(19, 18); // RX, TX
    int addr = 0;
    unsigned long startMillis;  //some global variables available anywhere in the program
    unsigned long currentMillis;
    const unsigned long period = 1000;  //the value is a number of milliseconds
    void setup()
    {

      XBee.begin(9600);
      Serial1.begin(9600);
      Serial.begin(9600);
      startMillis = millis();  //initial start time
     }
    void loop()
    {
      int id = 1;
      EEPROM.write(addr, id);
      if (Serial1.available()>0)
        {
          currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
      if (currentMillis - startMillis >= period)  //test whether the period has elapsed
      {
        char recbyte=Serial.read();
        Serial.print(recbyte);
        // delay(1500);
        Serial1.write(id);
        Serial1.write(" 30 ");
        Serial1.write(" 99 ");
        Serial1.write(" 72 ");
        Serial1.write(" 1098 ");
        Serial1.write(" 728 ");
        Serial1.write(" 578 ");
        // Serial1.write("$");
        Serial1.write('PS=1\r\n');
        Serial1.end();
        startMillis = currentMillis;
      }
        }
    }

body:
You have created a SoftwareSerial instance called XBee which is taking pins 17 and 18. You then use Serial1 which is pins 17 and 18.

You do not want, nor need, the XBee SoftwareSerial instance, since you are using hardware serial pins.  Delete it and all references to it.

Also, you are turning off Serial1 after using it, which means it will never work again:

    Serial1.end();

You would only use that instruction in very very specific circumstances.  Delete it.

After checking to see if there is data available to read on Serial1 you then proceed to try and read it from Serial:

    char recbyte=Serial.read();

That should be:

    char recbyte=Serial1.read();

You are writing to EEPROM on every single iteration of loop:

    EEPROM.write(addr, id);

It is likely that you have already killed your EEPROM.  C'est la vie...


message:
Running ADC triggered by TIMER1_COMPB

I'm trying to run ADC on channel 0 triggered by TIMER1_COMPB.
Everything seem to work ok but basic arithmetics is not working and variables inside ISR and even main loop don't get updated (x == 2 all the time)

Can somebody explain me why is it so? Even volatile variable was not changing...
Arduino UNO,
IDE v 1.8.6

    #define SAMPLES_SIZE  205

    const int adc_channel = 0;
    const uint16_t t1_load = 0;

    // 250 corresponds to 8kHz
    const uint16_t t1_comp = 25000;

    uint16_t samples[SAMPLES_SIZE];
    volatile uint8_t samplePos = 0;

    static int x = 0;

    void initADC() {
      // Init ADC free-run mode; f = ( 16MHz/prescaler ) / 13 cycles/conversion
      ADMUX  = adc_channel; // Channel sel, right-adj, use AREF pin
      ADCSRA = _BV(ADEN)  | // ADC enable
               _BV(ADSC)  | // ADC start
               _BV(ADATE) | // Auto trigger
               _BV(ADIE)  | // Interrupt enable
               _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128:1 / 13 = 9615 Hz
      ADCSRB = _BV(ADTS2) | _BV(ADTS0);              // Timer/Counter1 Compare Match B
      DIDR0  = _BV(adc_channel); // Turn off digital input for ADC pin
    }

    void initTimer() {
      // Reset Timer1 Control Reg A
      TCCR1A = 0;

    // Set CTC mode
      TCCR1B &= ~(1 << WGM13);
      TCCR1B |= (1 << WGM12);

    // Set prescaler to 8
      TCCR1B &= ~(1 << CS12);
      TCCR1B |= (1 << CS11);
      TCCR1B &= ~(1 << CS10);

    // Reset Timer 1 and set compare value
      TCNT1 = t1_load;
      OCR1B = t1_comp;

    // Enable Timer 1 compare interrupt
      TIMSK1 = (1 << OCIE1B);
    }

    void setup() {
      cli();
      initADC();
      initTimer();
      sei();

      Serial.begin(115200);
    }

    void loop() {
      while(ADCSRA & _BV(ADIE)); // Wait for audio sampling to finish
      cli();
      x = x + 2;
      Serial.print(samples[0]);
      Serial.print("\t");
      Serial.println(x);
    //  for (int i = 0; i < SAMPLES_SIZE; i++) {
    //    Serial.println(samples);
    //  }
    //  samplePos = 0;

      ADCSRA |= _BV(ADIE);       // Resume sampling interrupt
      sei();
    }

    ISR(ADC_vect) {
      int16_t sample = ADC;

      samples[0] = sample;
    //  samplePos++;
      ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off

      if(samplePos >= SAMPLES_SIZE) {
        ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off
      }
    }

    //ISR(TIMER1_COMPB_vect) {
    //}

Thanks in advance

body:
I've found the solution, it's strange since I enabled CTC mode, but it started to work normally as soon as I reset Timer 1:

    ISR(TIMER1_COMPB_vect) {
      TCNT1 = 0;
    }


message:
Can't drive servo

I purchased a [20KG Digital Servo, DS3218MG with a Control Angle of 270° ](https://www.amazon.com/gp/product/B076CNKQX4).

I am trying to get it to rotate with the following code:

    #include <Servo.h>

    Servo myservo;  // create servo object to control a servo

    void setup() {
      myservo.attach(9);  // attaches the servo on pin 9 to the servo object
    }

    int restingVal = 0;
    int keyDown = 80;

    void loop() {
      int minutesDelay = 1;
      Serial.print("Value");
      Serial.println(restingVal);

      delay(10000/2);

      myservo.write(keyDown);
      delay(500);
      myservo.write(restingVal);

    }

It makes a small "clicking" noise, but it never moves.  I have tried:

 - powering it from the arduino using a USB cable
 - powering it using a power cord plugged into an electrical outlet
 - powering it with 4 AA batteries in a battery pack (power from the battery pack to the servo with it's ground to the Arduino's ground and the arduino plugged into an outlet)
 - using a 470uF capacitor and then tried a 680uF capacitor.

What am I doing wrong?  Is there something else I could look at?

**update:**
changed code to:

    #include <Servo.h>

    Servo myservo;  // create servo object to control a servo

    void setup() {
      myservo.attach(9);  // attaches the servo on pin 9 to the servo object
      myservo.write(60);
      delay(2000);
      myservo.write(120);
    }

    int restingVal = 0;
    int keyDown = 80;

    void loop() {

    }

I get the same problem.

The power cord I'm using to connect the arduino is 12V DC 1A.

Here is a photo of the wiring in one configuration (with the battery pack and the wall outlet):
[![enter image description here][1]][1]

Orange wire goes to GND on arduino, the long green goes to ~9, yellow goes to VCC on battery pack.

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

body:
My guess is that the servo is drawing too much current from the Arduino 5v pin which can provide up to ~450mA when powered from USB and ~650mA from power jack.

Try providing 5v from an other source to the servo while keeping the GND of that power source and the Arduino common.


body:
The DS3218MG servo motor is a strong servo motor and it requires more current than normal servo motors.

With a normal servo motor the peak current can be 500 mA or even 1 A. This DS3218MG is specified [somewhere][1] at 1.8 A stall current (only 80 to 100 mA during normal operation). However [this YouTube video][2] measures a stall current of 2.3 A.

During normal operation, the average current will not even be near the stall current. The peak current on the other hand can be close to the stall current. The peak current occurs at the moment that the servo motors starts to move.

You need a 5 V 2.5 A power supply for that servo motor, together with wires and connectors that are suitable for that current.
You could cheat a little by adding a capacitor. I suggest 2200 µF or 4700 µF.

It is a common mistake to underestimate the current of a servo motor. A power supply is often more expensive than the servo motor.
If a lot of torque is required, perhaps a geared motor is easier to use.

  [1]: https://www.robotronics.ca/apps/webstore/products/show/7759972
  [2]: https://www.youtube.com/watch?v=9-QkfauM8Wk


message:
Resetting I2c Address - MLX90614

I was using my MLX90614 IRTherm sensor flawless and bought two more. I have connected two sensors serial with pull-ups to `SDA --> A4 and SCL --> A5`. After digging the internet I found out that I should change their default slave addresses to different addresses so that Arduino can recognize their 7-bit slave addresses.
After changing their address, now I can't read either two new serial MLX'es or my old MLX.

 - I might have messed up with their addresses and don't know how to
   reset their addresses.
 - How can i connect multiple sensors/ how can i change their adress properly?

> reading sensor data

    #include <Wire.h> // I2C library, required for MLX90614
    #include <SparkFunMLX90614.h> // SparkFunMLX90614 Arduino library

    IRTherm therm; // Create an IRTherm object to interact with throughout

    const byte LED_PIN = 8; // Optional LED attached to pin 8 (active low)

    void setup()
    {
      Serial.begin(9600); // Initialize Serial to log output
      therm.begin(0x5A); // Initialize thermal IR sensor
      therm.setUnit(TEMP_F); // Set the library's units to Farenheit
      // Alternatively, TEMP_F can be replaced with TEMP_C for Celsius or
      // TEMP_K for Kelvin.

      pinMode(LED_PIN, OUTPUT); // LED pin as output
      setLED(LOW); // LED OFF
    }

    void loop()
    {
      setLED(HIGH); //LED on

      // Call therm.read() to read object and ambient temperatures from the sensor.
      if (therm.read()) // On success, read() will return 1, on fail 0.
      {
        // Use the object() and ambient() functions to grab the object and ambient
     // temperatures.
     // They'll be floats, calculated out to the unit you set with setUnit().
        Serial.print("Object: " + String(therm.object(), 2));
        Serial.write('°'); // Degree Symbol
        Serial.println("F");
        Serial.print("Ambient: " + String(therm.ambient(), 2));
        Serial.write('°'); // Degree Symbol
        Serial.println("F");
        Serial.println();
      }
      setLED(LOW);
      delay(500);
    }

    void setLED(bool on)
    {
      if (on)
        digitalWrite(LED_PIN, LOW);
      else
        digitalWrite(LED_PIN, HIGH);
    }

> Setting address
>
>
>     #include <Wire.h> // I2C library, required for MLX90614
>     #include <SparkFunMLX90614.h> // SparkFunMLX90614 Arduino library
>
>     IRTherm therm; // Create an IRTherm object to interact with throughout
>
>     const byte oldAddress = 0x5A;
>     const byte newAddress = 0x5B;
>
>     void setup()
>     {
>       Serial.begin(9600); // Initialize Serial to log output
>       Serial.println("Press a key to begin");
>       while (!Serial.available()) ;
>
>       therm.begin(oldAddress); // Try using the old address first
>
>       byte address;
>       if (!therm.readID()) // Try reading the ID registers
>       {
>         // If the read fails, try re-initializing with the
>         // new address. Maybe we've already set it.
>         therm.begin(newAddress);
>
>         if (therm.readID()) // Read from the ID registers
>         { // If the read succeeded, print the ID:
>           Serial.println("Communicated with new address.");
>           Serial.println("ID: 0x" +
>                          String(therm.getIDH(), HEX) +
>                          String(therm.getIDL(), HEX));
>         }
>         else
>         {
>           Serial.println("Failed to communicate with either address.");
>         }
>       }
>       else
>       {
>         // If the read suceeds, change the address to something
>         // new.
>         if (!therm.setAddress(newAddress))
>         {
>           Serial.println("Failed to set new address.");
>         }
>         else
>         {
>           Serial.println("Set the address to 0x" + String(newAddress, HEX));
>           Serial.println("Cycle power to try it out.");
>         }
>       }
>     }
>
>     void loop()
>     {
>
>     }

Edit 1:
[Datasheet](https://www.sparkfun.com/datasheets/Sensors/Temperature/MLX90614_rev001.pdf)

body:
Page 13 of 35 in the datasheet states:

> In order to provide access to any device or to assign an address to a
> SD before it is connected to the bus system, the communication must
> start with zero SA followed by low RWB bit. When this command is sent
> from the MD, the MLX90614 will always respond and will ignore the
> internal chip code information.

Supposedly, all you have to do is to connect only one device and use the address zero to read/write the registers.


message:
Can SPI and serial.begin be used at the same time?

I have two modules where I want to control them through a single Arduino UNO.

I guess Serial.begin(9600) uses serial port and UART. But Im not sure about SPI.

Can I use SPI library hence the SPI communication together with serial communication(serial.begin) at the same time to communicate with two different modules?

body: Yes. UART and SPI are completely different things.  One uses pins 0/1, the other uses pins 11/12/13, and they use separate hardware and control registers inside the chip.


message:
Vary voltage using relay. Is this possible?

I am planning to control a RGB lamp using Arduino. The lamp is 24V and I want to be able to control the brightness of the lamp. I found a relay that will let me control the 3 channels (red green and blue), but will only let me turn it on and off (Not control brightness)

I am looking for a way to control the lamp both on/off and brightness. What component will do the same as my relay, but also let me use the varying voltage from the arduino to control my 24V lamp? (Just like a transistor)

I have an external 24V powersupply along with 5V for the arduino

Thanks!

body:
No, you can't vary the voltage with a relay. The only way you could do it with a relay would be to have a selection of different voltages available, and then use multiple relays to select which voltage is used. Less than ideal.

You need to use PWM to create a square wave with varying duty cycle. The duty cycle (the percentage of time the power is on within a given period) defines the average voltage of the output.  That PWM needs to be fed into a MOSFET which will in turn control the 24V power to the lamp.

It's exactly the same as driving RGB LED strips, except it's in the shape of a lamp not a long strip.


body:
Yes it is possible to vary voltage with a relay.  A relay is simply a 2 way 3 pole switch.

<!-- 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/9wnJG.png)

<!-- End schematic -->

By switching in a resistor to the supply voltage you have lowered the voltage and will dim the 24V light source.  The actual resistor value will depend on how dim you want to go.  Make sure the resistor is rated for the load you plan to place on it.


message:
How to Connect Dc motor with encoder (pololou) with motor shield and Arduino Mega 2560?

I tried to search a bout how to connect plolou motor with encoder to arduino mega and the motor control shield as in those pics [![enter image description here][1]][1] if any one knows how to connect those to each other please tell me

[![enter image description here][2]][2]

[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/iQKRs.jpg
  [2]: https://i.stack.imgur.com/i6m5f.jpg
  [3]: https://i.stack.imgur.com/UUB57.jpg

body:
A quick look on Pololu's website reveals that:

        Color  Function
      --------  --------------------------------------------
        Red  motor power (connects to one motor terminal)
        Black  motor power (connects to the other motor terminal)
        Green  encoder GND
        Blue  encoder Vcc (3.5 – 20 V)
        Yellow  encoder A output
        White  encoder B output

Thus: Red goes to M1A and Black goes to M1B on the motor shield.
The remaining wires are for the encoder and go to Arduino pins.
Green goes to Arduino GND, Blue goes to 5V, Yellow and White go to the
digital i/O pins of your choice.

Note: Your motor shield has extra 5V and GND pins so you can connect the Blue and Green wires there.


message:
How to remove the sketch for the LCD and retaining the sketch for the MPU6050?

I just got this from the internet and I only want to use the sketch for the MPU6050. Can someone help me to remove the code for the LCD? I'm sorry, I'm just noob when it comes to programming.

Here is my source: [Earthquake Detector using Arduino and MPU-6050][1]

Here is the sketch:

    #include <LiquidCrystal.h>

    #include <Wire.h>

    #include <MPU6050.h>

    #define minval -5

    #define maxval 3

    MPU6050 mpu;

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

    void setup()

    {   lcd.begin(16, 2);

    Serial.begin(115200);

    pinMode(7,OUTPUT);

    pinMode(8,OUTPUT);

    lcd.print("   EarthQuake ");

    lcd.setCursor(0, 1);

    lcd.print("   Detector");

    delay (2000);

    lcd.clear();

    // Initialize MPU6050

    Serial.println("Initialize MPU6050");

    while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))

    { Serial.println("Could not find a valid MPU6050 sensor, check wiring!");

    delay(500);}

    mpu.setThreshold(3);

    // Check settings

    checkSettings();

    }

    void checkSettings()

    {

    Serial.println();

    Serial.print(" * Sleep Mode:        ");

    Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");

    Serial.print(" * Clock Source:      ");

    switch(mpu.getClockSource())

    {case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and
    keeps the timing generator in reset"); break;

    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external
    19.2MHz reference"); break;

    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external
    32.768kHz reference"); break;

    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis
    gyroscope reference"); break;

    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis
    gyroscope reference"); break;

    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis
    gyroscope reference"); break;

    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz
    oscillator"); break;

    }

    Serial.print(" * Gyroscope:         ");

    switch(mpu.getScale())

    {case MPU6050_SCALE_2000DPS:        Serial.println("2000 dps"); break;

    case MPU6050_SCALE_1000DPS:        Serial.println("1000 dps"); break;

    case MPU6050_SCALE_500DPS:         Serial.println("500 dps"); break;

    case MPU6050_SCALE_250DPS:         Serial.println("250 dps"); break:}

    Serial.print(" * Gyroscope offsets: ");

    Serial.print(mpu.getGyroOffsetX());

    Serial.print(" / ");

    Serial.print(mpu.getGyroOffsetY());

    Serial.print(" / ");

    Serial.println(mpu.getGyroOffsetZ());

    Serial.println();}

    void loop()

    {   Vector rawGyro = mpu.readRawGyro();

    Vector normGyro = mpu.readNormalizeGyro();

    Serial.print(" Xraw = ");

    Serial.print(rawGyro.XAxis);

    Serial.print(" Yraw = ");

    Serial.print(rawGyro.YAxis);

    Serial.print(" Zraw = ");

    Serial.println(rawGyro.ZAxis);

    if(normGyro.XAxis > maxval || normGyro.XAxis < minval && normGyro.YAxis >
    maxval || normGyro.YAxis  < minval && normGyro.ZAxis > maxval ||
    normGyro.ZAxis  < minval)

    { digitalWrite(7,HIGH);

    digitalWrite(8,HIGH);

    delay(300);

    digitalWrite(7,HIGH);

    digitalWrite(8,HIGH);

    delay(300);

    lcd.clear();

    lcd.print("***EarthQuake***");

    delay (1000);

    lcd.clear();}

    else{digitalWrite(7,LOW);

    digitalWrite(8,LOW);}

    Serial.print(" Xnorm = ");

    Serial.print(normGyro.XAxis);

    Serial.print(" Ynorm = ");

    Serial.print(normGyro.YAxis);

    Serial.print(" Znorm = ");

    Serial.println(normGyro.ZAxis);

    delay(10);}

  [1]: http://microcontrollerslab.com/earthquake-detector-arduino/

body:
As Majenko states, carefully remove all lines with the `lcd` object in them. Due to the extremely poor formatting and indentation of the code, if you aren't careful you could lose some important syntax, such as the `{` and `}`.

Also, there is no need for the `LiquidCrystal` header file.

In addition, there is a typo in the posted code (it is beyond me why the author would post uncompilable (and hence untested) code), in this line:

    case MPU6050_SCALE_250DPS:         Serial.println("250 dps"); break:}

Here is the code with the `lcd` related lines stripped out, correctly formatted and indented, with the typo fixed:

    #include <Wire.h>
    #include <MPU6050.h>

    #define minval -5
    #define maxval 3

    MPU6050 mpu;

    void setup()
    {
      Serial.begin(115200);
      pinMode(7,OUTPUT);
      pinMode(8,OUTPUT);

      delay (2000);

      // Initialize MPU6050
      Serial.println("Initialize MPU6050");

      while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
      {
        Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
        delay(500);
      }

      mpu.setThreshold(3);
      // Check settings
      checkSettings();
    }

    void checkSettings()
    {
      Serial.println();
      Serial.print(" * Sleep Mode:        ");
      Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
      Serial.print(" * Clock Source:      ");
      switch(mpu.getClockSource())
      {
        case MPU6050_CLOCK_KEEP_RESET:
          Serial.println("Stops the clock and keeps the timing generator in reset");
          break;
        case MPU6050_CLOCK_EXTERNAL_19MHZ:
          Serial.println("PLL with external 19.2MHz reference");
          break;
        case MPU6050_CLOCK_EXTERNAL_32KHZ:
          Serial.println("PLL with external 32.768kHz reference");
          break;
        case MPU6050_CLOCK_PLL_ZGYRO:
          Serial.println("PLL with Z axis gyroscope reference");
          break;
        case MPU6050_CLOCK_PLL_YGYRO:
          Serial.println("PLL with Y axis gyroscope reference");
          break;
        case MPU6050_CLOCK_PLL_XGYRO:
          Serial.println("PLL with X axis gyroscope reference");
          break;
        case MPU6050_CLOCK_INTERNAL_8MHZ:
          Serial.println("Internal 8MHz oscillator");
          break;
      }

      Serial.print(" * Gyroscope:         ");
      switch(mpu.getScale())
      {
        case MPU6050_SCALE_2000DPS:
          Serial.println("2000 dps");
          break;
        case MPU6050_SCALE_1000DPS:
          Serial.println("1000 dps");
          break;
        case MPU6050_SCALE_500DPS:
           Serial.println("500 dps");
           break;
        case MPU6050_SCALE_250DPS:
           Serial.println("250 dps");
           break;
      }

      Serial.print(" * Gyroscope offsets: ");
      Serial.print(mpu.getGyroOffsetX());
      Serial.print(" / ");
      Serial.print(mpu.getGyroOffsetY());
      Serial.print(" / ");
      Serial.println(mpu.getGyroOffsetZ());
      Serial.println();
    }

    void loop()
    {
      Vector rawGyro = mpu.readRawGyro();
      Vector normGyro = mpu.readNormalizeGyro();
      Serial.print(" Xraw = ");
      Serial.print(rawGyro.XAxis);
      Serial.print(" Yraw = ");
      Serial.print(rawGyro.YAxis);
      Serial.print(" Zraw = ");
      Serial.println(rawGyro.ZAxis);

      if (normGyro.XAxis > maxval ||
          normGyro.XAxis < minval &&
          normGyro.YAxis > maxval ||
          normGyro.YAxis < minval &&
          normGyro.ZAxis > maxval ||
          normGyro.ZAxis < minval)
      {
        digitalWrite(7,HIGH);
        digitalWrite(8,HIGH);
        delay(300);
        digitalWrite(7,HIGH);
        digitalWrite(8,HIGH);
        delay(300);
        delay (1000);
      }
      else
      {
        digitalWrite(7,LOW);
        digitalWrite(8,LOW);
      }
      Serial.print(" Xnorm = ");
      Serial.print(normGyro.XAxis);
      Serial.print(" Ynorm = ");
      Serial.print(normGyro.YAxis);
      Serial.print(" Znorm = ");
      Serial.println(normGyro.ZAxis);
      delay(10);
    }

The page that you got your code from does not specify which MPU6050 library to use. It is not the library by Jeff Rowberg, as linked to from the Arduino Playground, [MPU-6050 Accelerometer + Gyro][1]. It is in fact this library, [MPU6050 Triple Axis Gyroscope & Accelerometer Arduino Library][2].

  [1]: https://playground.arduino.cc/Main/MPU-6050
  [2]: https://github.com/jarzebski/Arduino-MPU6050


message:
Arduino LCD Brightness

I've made this small device that uses a ultrasonic sensor to tell how far away an object is and display it on a 16x2 display.

Here's the code:

    #include <LiquidCrystal.h>

    int Contrast=100;
     LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    const int trigPin = 7;
    const int echoPin = 8;
    // defining variables
    long duration;
    int distance;
    void setup() {
    pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin, INPUT); // Sets the echoPin as an Input
    Serial.begin(9600); // Starts the serial communication
      analogWrite(6, Contrast);

      lcd.begin(16, 2);
      lcd.clear();
    }
    void loop() {

    // Clears the trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration = pulseIn(echoPin, HIGH);
    // Calculating the distance
    distance = duration / 29 / 2;
    // Prints the distance on the Serial Monitor
    Serial.print("Distance: ");
    Serial.println(distance);
      lcd.setCursor(0, 0);
      lcd.print("Distance: ");

     lcd.setCursor(0, 1);
      lcd.print(distance);
      delay(100);
      lcd.clear();
    }

Every thing works fine apart from the fact that the lcd backlight is too dim(barely visible). I tried looking online but is there any way i can get max brightness without a potentiometer? I do have resistors , can i use them somehow?

body:
The back light of the LCD is just an LED connected through a resistors on the A (15) and K (16) pins on the display. The LED doesn't require an external resistor since according to the [datasheet][1] there is a build in resistor on the board itself. If you aren't using any external resistors and applying a constant voltage of 5V and the screen is still dim than this means that the led is most likely dead and you would need to replace the back light panel.

If you are talking about the contrasts of the display. Than I would recommend you to hook up the contrast pin to a PWM pin on the Arduino and by using `analogWite` to tune the display in order to get the desired value of contrast.

  [1]: https://www.openhacks.com/uploadsproductos/eone-1602a1.pdf


message:
Faster way to parse a HTTP response in Arduino

I send a GET http request to a server and get following data back.

    HTTP/1.1 200
    Content-Type: application/json;charset=UTF-8
    Transfer-Encoding: chunked
    Date: Fri, 16 Nov 2018 16:30:05 GMT
    Connection: close

    35
    {
      "uuid" : "13b29524-7e12-48fb-bbf9-4396aefff45d"
    }
    0

with the following code I get the header info and the body.

    void parseResponse() {
      boolean headerEnd = false;
      byte lineCount = 0;
      String line;
      char endOfLine[] = "\r\n";
      while (1) {
        if (client.available()) {
          char inChar = client.read();
          if (!headerEnd && line.endsWith(endOfLine)) {
            // Just save the first then headers
            if (lineCount == 10) {
              headerEnd = true;
            } else {
              headers[lineCount] = line;
              line = "";
              lineCount++;
            }
          }

          if (line.endsWith("close")) {
            line = "";
            headerEnd = true;
          }

          if (headerEnd && line.endsWith("}")) {
            line.toCharArray(response, sizeof(response));
            client.stop();
            break;
          }

          line += inChar;
        }
      }
    }

this thakes 60 - 70ms to parse. Is there a faster way to parse? I think that's slow, for so little text, in the world of AVRs.

body:
there are nice functions inherited from [Stream class][1]

    int parseResponse(char uuid[], int size) {
      if (!client.find("HTTP/1.1")) // skip HTTP/1.1
        return -1;
      int st = client.parseInt(); // parse status code
      int l = -1;
      if (st == 200 && client.find("\"uuid\" : \"")) {
        int l = client.readBytesUntil('"', uuid, size);
        uuid[l] = 0; // terminate the C string
      }
      return l;
    }

  [1]: https://www.arduino.cc/reference/en/language/functions/communication/stream/


message:
Arduino Leonardo keyboard.print keeps printing equal sign

I am currently working on a DIY controller for Train Sim World. I am relatively new to the Arduino and the C programming language. My code is structured to look for button presses or PS2 joystick inputs and print a specific character for each button. I have also included a kill switch on pin 3. However when I run the code and open Notepad to see the results, the Arduino keeps printing the `=` character even if pin 3 is not pulled low. After I pull pin 3 low and press a button, there is a delay of about two seconds during which the `=` character keeps being printed over and over again, and after these 2 seconds elapse the Arduino prints the character attributed to the button several times before returning to printing `=` over and over again.

What can I do to fix this?

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

 #include <Keyboard.h>

 void setup() {
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
 }
 bool pantograph = 0;
 void loop() {
  while (digitalRead(3) == LOW) {
   Keyboard.write("M");
   if (digitalRead(1) == LOW) {
    Keyboard.write("W");
   } else if (digitalRead(2) == LOW) {
    Keyboard.write("S");
   } else if (digitalRead(0) == LOW) {
    Keyboard.write("Q");
   } else if (digitalRead(5) == LOW) {
    Keyboard.write("Y");
   } else if (digitalRead(6) == LOW) {
    Keyboard.write("T");
   } else if (digitalRead(7) == LOW) {
    Keyboard.write("G");
   } else if (digitalRead(8) == LOW) {
    Keyboard.write("K");
   } else if (digitalRead(9) == LOW) {
    Keyboard.write("Z");
   } else if (digitalRead(10) == LOW) {
    if (pantograph == 0) {
     Keyboard.write("P");
    } else {
     Keyboard.write("O");
    }
   } else if (digitalRead(11) == LOW) {
    Keyboard.write(9);
   } else if (digitalRead(12) == LOW) {
    Keyboard.write("N");
   } else if (digitalRead(13) == LOW) {
    Keyboard.write(32);
   } else if (analogRead(A0) > 700) {
    Keyboard.write(93);
   } else if (analogRead(A0) < 200) {
    Keyboard.write(91);
   } else if (analogRead(A1) > 700) {
    Keyboard.print(39);
   } else if (analogRead(A1) < 200) {
    Keyboard.print(59);
   } else if (analogRead(A2) > 700) {
    Keyboard.print("A");
   } else if (analogRead(A2) < 200) {
    Keyboard.print("D");
   }
  }
  delay(1000);
 }

body: The method `write` with one parameter takes char not string. Use `write('W')`, not `write("W");`


message:
Flashing an ATtiny85 with a NodeMCU?

I recently purchased a [Digispark](http://digistump.com/products/1) for some of my smaller electronics projects. After it initially being a great little board, I soon found myself unable to flash the board in the same way I had done before i.e. according to the method described [here](https://digistump.com/wiki/digispark/tutorials/connecting). I am still unsure as to why the previous flashing method stopped working but have been unable to overcome the issue, nor have I found many other accounts of similar problems online.

After a period of frustration, unable to even find a way to reset the board, it dawned upon me that I may be able to use an Arduino to flash the board as seen [here](https://www.hackster.io/arjun/programming-attiny85-with-arduino-uno-afb829). However, the issue is that all the tutorials I could find online assumed that an Arduino Uno could be easily accessed, which is not the case for me. Despite this, I do have a few NodeMCUs hanging around and would love it if I could use them to flash the Digispark.

My question is: how exactly would I flash the Digispark using a NodeMCU (if it is even possible)?

P.S. Whilst I am aware that the Digispark board has a number of other components aside from the ATtiny85 chip, the pinouts (not the USB) of the board allow for direct interfacing with the chip.

Thank you in advance for any help,

Kind regards,
Rocco

body:
It can be done. Your Digispark has SPI pins, which are ISP pins. For the esp8266 there is an [ESP8266AVRISP library][1] for OTA upload to AVR. You can use the example of the library.

You must wire the SPI pins and ground together. Wire reset pin of Digispark to io 5 (D1) of NodeMcu. You should use level conversion, but esp8266 tolerates 5 V TTL (not recommended for long term). Do not wire the SS pin.

  [1]: https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266AVRISP
  [2]: https://i.stack.imgur.com/AloGQ.jpg


message:
Make an Xbox 360 controller with an Arduino Uno

I was thinking of making a custom Xbox 360 controller (racing wheel) with the Arduino Uno plugged into the Xbox. How would I emulate the buttons/triggers on the original controller with the Arduino? Is there a library that can help me do this?

body:
Arduino Uno's do not have a native USB Connection. However, if you use an Arduino Leonardo or Pro Micro, you can use MHeironimus's Joystick library, However I am not sure if they are specifically compatible with the XBox.

https://github.com/MHeironimus/ArduinoJoystickLibrary


message:
ESP8266 ASCII to HEX convertion and checking

I am trying to convert ASCII to hex and check if the hex is equal to that hex that I want.

For example:

`1B 42 05` it means `B` in ASCII, I need to check if that hex is equal to `1B 42 05`.

Here I need to send converted hex code from ASCII code by using `SoftwareSerial`.

Example:

    02 20 2D 33 30 32 35 30 20 6B 67 0D 0A 03

I have to convert to

    -30250 kg

body:
Converting an ASCII HEX digit is simple enough.  Here's a little function I use all the time:

    uint8_t h2d(char hex) {
        if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case
        return(hex & 0xf);
    }

Pass it a single HEX digit as a `char` variable and it returns a number between 0 and 15.

To convert a pair of characters into an 8-bit value just call it twice with each character, shift one of them 4 bits to the left, and OR them together.  For instance:

    uint8_t h2d2(char h1, char h2) {
        return (h2d(h1)<<4) | h2d(h2);
    }

That would give you a number between 0 and 255 (or 016 and FF16, or 08 and 3778...)

How you receive and split up the incoming data properly is a whole other topic, but [this](https://majenko.co.uk/blog/reading-serial-arduino) and [this](https://majenko.co.uk/blog/splitting-text-c) could probably help you.


body:
A little explanation about HEX and ASCII:

About HEX

Raw computer data consists of zeros and ones. For humans it is difficult to read a (long) row of zeros and ones. You can represent such a row (of a certain length) by a decimal number, but then the relation with the underlying bits is not directly clear. For this reason the hexadecimal (HEX) representation is used (hexadeca comes from Greek and means 16.

Four bits can represent 16 different situations (= 16 different combinations of zeros and ones). The HEX digit belonging to each combination is:

0000 = 0; 0001 = 1; 0010 = 2; 0011 = 3; 0100 = 4; 0101 = 5; 0110 = 6; 0111 = 7

1000 = 8; 1001 = 9; 1010 = A; 1011 = B; 1100 = C; 1101 = D; 1110 = E; 1111 = F

When you memorize these 16 cases (from which the first 10 are easy because it is juist binary counting), you know immediately which bit-pattern belongs to a hexadecimal number and vice versa. For example: the HEX value 5A = 01011010.

About ASCII

Computer data contain not only numbers, but also text. As the computer can only handle bits (zeros and/or ones) we have to decide how letters (characters) are presented by bit patterns. And preferably in a standardized way, in order that different computers can handle each others text. Unfortunately there is more than one standard, but one that is very much used is the ASCII standard (see: https://en.wikipedia.org/wiki/ASCII).

The ASCII standard uses 7 bits codes and defines not only characters but also 'control codes' e.g. for 'line feed' and 'carriage return'. Often these 7 bits are stored in one byte (with the leftmost 8th bit set to 0) and can than be represented by two HEX digits.

Without further information nobody can tell what a row of bits represents. That's one of the reasons datatypes are used. They tell us what the row of bits represents and how many bits (or bytes) are used for the representation.

So the HEX representation of your row of 3 bytes is "1B 42 05" and, when these are characters, could stand for (look at the ASCII table): "ESCAPE B ENQ". In which 'ESCAPE' and 'ENQ' are control codes which meaning depends on the communication protocol.
The second row (of 14 bytes) could stand for: "STX SPACE - 3 0 2 5 0 SPACE k g CR LF ETX". STX and ETX stand for 'START OF TEXT' and 'END OF TEXT'. 'LF' stands for 'LINE FEED' and 'CR'stands for 'CARRIAGE RETURN'.

I hope that with this explanation you have a better idea about HEX and ASCII and that you now will be able to figure out how to handle your data.


message:
How can I get my (Arduino) Pro Micro schematic to allow me to program it through GPIO instead of USB

I'm trying this project so far I've got the schematic of a Pro Micro, which is powered through GPIO from a Raspberry Pi Zero, and want to remove the micro usb connection and able to flash it using an avr programer and a few pins.

How do I get to Achieve that? also the Pro Micro is getting D+/D- from the the raspberry's D+/D- pads as well. Schematic below for reference.
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/Pdf4W.png

body:
Why don't you buy a pi zero to USB  add-on board?
You can stack the pi on top and plug it into a normal female USB port on your computer.

The USB board has some pins that connect to the solder points of the mini USB, so you can delete all the connectors you won't need.

Other option is to solder a wire to the pi and extend the connector with a cable.

I'm not shire, if you can program the pi true its serial pins.
USB is a serial connection after all. So I think this should be possible


body:
Welcome to arduino.stackexchange.
You can program your ATmega32U4 on at least two ways:
1. Use Arduino's bootloader and D+/D- pins. This way you won't need an external programmer. Try search for phase "programming ATmega32U4 with bootloader".
2. Use ISP (In-System-Programming) method. In this case you can use your avr programmer. To do so you also need access to PINs named Reset, MISO, MOSI, SCLK. See [this link][1] or [this one][2]

As always, the important read is [ATMega32U4 datasheet][3].

  [1]: https://www.coreforge.com/blog/2014/09/recovering-arduino-pro-micro-atmega32u4/
  [2]: https://www.avrfreaks.net/forum/atmega32u4-programming
  [3]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf


body:
An avr programmer uses the ISP interface to program a chip. For this you need the pins for MOSI, MISO, SCK and Reset. Of course you have also to provide power to the board through Vcc and ground.

I'm not sure, if it's OK to keep the USB connection while programming via ISP, but since you want to remove that connection either way, this isn't a problem for you. You can remove the USB connection completely (no D+ or D- connection).

Note: when you are programming the Arduino Micro via ISP without also burning the bootloader, you won't be able to use USB for programming anymore, until you burn the bootloader again.


message:
What is 1.8 to 5.5 VDC?

I'd like to buy a standalone capacitive touch sensor to create interactive art.  It says it is powered by 1.8 to 5.5 VDC.  I am new to arduinos - what type of battery can I buy to power this sensor?  I'm hoping it's simple, not complicated. Thanks!

body:
do you have a 5V power supply?
If you do I'd suggest connecting your arduino to the power supply and then you can power your sensor with a pin of the arduino.


body:
VDC is an abbreviation for volts DC. DC means Direct Current you can read more a detailed explanation about it [here][1]. Basically what `powered by 1.8 to 5.5 VDC` means is that the DC voltage on the input of your sensor can vary from 1.8 volts up to 5.5 volts. So you can use either 3 AAA batteries in [series][2] since the sum of their voltage will be: `1.5V * 3 = 4.5V` what is in the range of recommended voltages for your sensor. Also, you can use a [Li-ion battery][3] in order to power your sensor since the voltage of this type of battery is 3.7V it is also in the range of recommended voltages for your sensor. However you would need an additional charge/discharge module in order to recharge and keep the battery in a good condition. You can read more about it on the web.

  [1]: https://www.diffen.com/difference/Alternating_Current_vs_Direct_Current
  [2]: http://www.zbattery.com/Connecting-Batteries-in-Series-or-Parallel
  [3]: https://en.wikipedia.org/wiki/Lithium-ion_battery


message:
Reading analog value while generating PWM signal

I'm trying to generate dim two LED strips simultaneously by generating two PWM signals based on potentionmeter value. The pot sets how bright each of the LED strips will be. To drive this I'm using Arduino Pro Micro equipped with Atmel 32u4 chip.

[![circuit schematic][1]][1]

I'm using following code:

    int sensorValue = 0;
    int outputValue = 0;

    void setup() {
    }

    void loop() {
      sensorValue = analogRead(A0);

      outputValue = map(sensorValue, 0, 1023, 0, 255);
      analogWrite(5, outputValue);
      analogWrite(6, 255 - outputValue);

      delay(2);
    }

The problem is, the `analogRead` never returns 1023 when the pot is fully open. The value is always around 980. This itself would not be a big deal.

The main issue is that the `analogRead` is incredibly noisy. The value returned for the maximum position is in range of [940-1020].

When I don't use the `analogWrite` to generate PWM, the problem goes away an the input is crystal clear in range [0-1023] as expected.

I have tried to turn off the PWM before reading the value in, but this generates flicker, as the LEDs are temporarily off.

Is there any HW or SW solution to this? I don't mind writing some assembly if required.

  [1]: https://i.stack.imgur.com/C74p0.png

body:
It was an issue with the power source. It's an USB led strip, so I was powering it through Arduino, which was a bad idea as it turns out.

When I have added external power source to the circuit everything started working correctly.


message:
How to convert string to byte array on arduino

Well my title pretty much sums it up , how to convert string to byte array? i cant find any usefull code

body:
Well, the C string is already byte array.

If you mean Arduino's `String` class, then it has `c_str()` method.

Both needs reinterpret cast to const byte pointer:

    byte const* byteArray = reinterpret_cast<byte const*>(yourString.c_str());


message:
I can't make more than one arduino gas sensor work at the same time

I'm doing a school project in which I need to track different kinds of gases, the problem is I can't read more than one sensor at the same time, I'm using four sensors (mq5, mq7, mq8 and mq135) and the code I'm using was one that I merged using four different codes that I found on github (https://github.com/mdsiraj1992/Gassensors). When I'm only one sensor it works normally, but when I use the code I merged the values are totally off. So basically I'm doing something wrong, but I don't know what. Please help me, I have to deliver the code this week.

    #include <Adafruit_Sensor.h>

    #include <Adafruit_Sensor.h>

    #include <DHT.h>
    #include <DHT_U.h>

    #include <DHT.h>
    #include <DHT_U.h>

    /***Hardware Related Macros***/

    #define         MQ5PIN                       (2)
    #define         RL_VALUE_MQ5                 (1)
    #define         RO_CLEAN_AIR_FACTOR_MQ5      (6.455)

    #define         MQ7PIN                       (3)
    #define         RL_VALUE_MQ7                 (1)
    #define         RO_CLEAN_AIR_FACTOR_MQ7      (26.09)

    #define         MQ8PIN                       (1)
    #define         RL_VALUE_MQ8                 (1)
    #define         RO_CLEAN_AIR_FACTOR_MQ8      (1)

    #define         MQ135PIN                     (5)
    #define         RL_VALUE_MQ135               (1)
    #define         RO_CLEAN_AIR_FACTOR_MQ135    (3.59)

    /***Software Related Macros***/

    #define         CALIBARAION_SAMPLE_TIMES     (50)
    #define         CALIBRATION_SAMPLE_INTERVAL  (500)
    #define         READ_SAMPLE_INTERVAL         (50)
    #define         READ_SAMPLE_TIMES            (5)

    /***Application Related Macros***/

    #define         GAS_LPG                      (1)
    #define         accuracy                     (0)
    #define         GAS_CARBON_MONOXIDE          (3)
    #define         GAS_HYDROGEN                 (0)
    #define         GAS_METHANE                  (2)
    #define         GAS_CARBON_DIOXIDE           (9)
    #define         GAS_AMMONIUM                 (10)

    /***Globals***/
    float           Ro = 10;

    void setup() {
      Serial.begin(9600);
      Serial.print("Calibrating...\n");

      Ro = MQCalibration(MQ5PIN);
      Serial.print("Calibration is done...\n");
      Serial.print("Ro5=");
      Serial.print(Ro);
      Serial.print("kohm");
      Serial.print("\n");

      Ro = MQCalibration(MQ7PIN);
      Serial.print("Calibration is done...\n");
      Serial.print("Ro7=");
      Serial.print(Ro);
      Serial.print("kohm");
      Serial.print("\n");

      Ro = MQCalibration(MQ8PIN);
      Serial.print("Calibration is done...\n");
      Serial.print("Ro8=");
      Serial.print(Ro);
      Serial.print("kohm");
      Serial.print("\n");

      Ro = MQCalibration(MQ135PIN);
      Serial.print("Calibration is done...\n");
      Serial.print("Ro135=");
      Serial.print(Ro);
      Serial.print("kohm");
      Serial.print("\n");
    }

    void loop() {

      Serial.print("METHANE:");
      Serial.print(MQGetGasPercentage(MQRead(MQ8PIN) / Ro, GAS_METHANE) );
      Serial.print( "ppm" );
      Serial.print("    ");
      Serial.print("HYDROGEN:");
      Serial.print(MQGetGasPercentage(MQRead(MQ8PIN) / Ro, GAS_HYDROGEN) );
      Serial.print( "ppm" );
      Serial.print("    ");
      Serial.print("GLP:");
      Serial.print(MQGetGasPercentage(MQRead(MQ5PIN) / Ro, GAS_LPG) );
      Serial.print( "ppm" );
      Serial.print("    ");
      Serial.print("CARBON_MONOXIDE:");
      Serial.print(MQGetGasPercentage(MQRead(MQ7PIN) / Ro, GAS_CARBON_MONOXIDE)
                  );

      Serial.print( "ppm" );
      Serial.print("    ");
      Serial.print("CARBON_DIOXIDE:");
      Serial.print(MQGetGasPercentage(MQRead(MQ135PIN) / Ro, GAS_CARBON_DIOXIDE)
                  );
      Serial.print( "ppm" );
      Serial.print("    ");
      Serial.print("AMMONIUM:");
      Serial.print(MQGetGasPercentage(MQRead(MQ135PIN) / Ro, GAS_AMMONIUM) );
      Serial.print( "ppm" );
      Serial.print("\n");
      delay(200);
    }

    /***MQResistanceCalculation*****************************************
      Input:   raw_adc - raw value read from adc, which represents the
      voltage
      Output:  the calculated sensor resistance
      Remarks: The sensor and the load resistor forms a voltage divider.
      Given the voltage
      across the load resistor and its resistance, the resistance of the
      sensor
      could be derived.

    *******************************************************************/
    float MQResistanceCalculation(int raw_adc)
    {
      return ( ((float)RL_VALUE_MQ5 * (1023 - raw_adc) / raw_adc));
      return ( ((float)RL_VALUE_MQ7 * (1023 - raw_adc) / raw_adc));
      return ( ((float)RL_VALUE_MQ8 * (1023 - raw_adc) / raw_adc));
      return ( ((float)RL_VALUE_MQ135 * (1023 - raw_adc) / raw_adc));
    }

    /*** MQCalibration*******************************************************
      Input:   mq_pin - analog channel
      Output:  Ro of the sensor
      Remarks: This function assumes that the sensor is in clean air. It use
      MQResistanceCalculation to calculates the sensor resistance in clean
      air
      and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is
      about
      10, which differs slightly between different sensors.
    ****************************************************************/
    float MQCalibration(int mq_pin)
    {
      int i;
      float RS_AIR_val = 0, r0;

      for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
        RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
        delay(CALIBRATION_SAMPLE_INTERVAL);
      }
      RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
      r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ5;

      return r0;

      for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
        RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
        delay(CALIBRATION_SAMPLE_INTERVAL);
      }
      RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
      r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ7;

      return r0;

      for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
        RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
        delay(CALIBRATION_SAMPLE_INTERVAL);
      }
      RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
      r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ8;

      return r0;

      for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
        RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
        delay(CALIBRATION_SAMPLE_INTERVAL);
      }
      RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
      r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ135;

      return r0;
    }
    /*****************  MQRead *********************************
      Input:   mq_pin - analog channel
      Output:  Rs of the sensor
      Remarks: This function use MQResistanceCalculation to caculate the
      sensor resistenc (Rs).
      The Rs changes as the sensor is in the different consentration of the
      target
      gas. The sample times and the time interval between samples could be
      configured
      by changing the definition of the macros.
    ********************************************************/
    float MQRead(int mq_pin)
    {
      int i;
      float rs = 0;

      for (i = 0; i < READ_SAMPLE_TIMES; i++) {
        rs += MQResistanceCalculation(analogRead(mq_pin));
        delay(READ_SAMPLE_INTERVAL);
      }

      rs = rs / READ_SAMPLE_TIMES;

      return rs;
    }

    /***********************  MQGetGasPercentage ****************************
      Input:   rs_ro_ratio - Rs divided by Ro
      gas_id      - target gas type
      Output:  ppm of the target gas
      Remarks: This function uses different equations representing curves of
      each gas to
      calculate the ppm (parts per million) of the target gas.
    ******************************************************************/
    int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
    {
      if ( accuracy == 0 ) {

      }
      if ( gas_id == GAS_LPG ) {
        return (pow(10, ((-2.513 * (log10(rs_ro_ratio))) + 1.878)));
      }
      else if ( gas_id == GAS_CARBON_MONOXIDE ) {
        return (pow(10, ((-1.525 * (log10(rs_ro_ratio))) + 1.994)));
      }
      else if ( gas_id == GAS_HYDROGEN ) {
        return (pow(10, ((-2.568 * (log10(rs_ro_ratio))) + 0.360)));
      }
      else if ( gas_id == GAS_METHANE ) {
        return (pow(10, ((-16.16 * (log10(rs_ro_ratio))) + 1.093)));
      }
      else if ( gas_id == GAS_CARBON_DIOXIDE ) {
        return (pow(10, ((-2.890 * (log10(rs_ro_ratio))) + 2.055)));
      }
      else if ( gas_id == GAS_AMMONIUM ) {
        return (pow(10, ((-2.469 * (log10(rs_ro_ratio))) + 2.005)));

      }
      else if ( accuracy == 1 ) {
      }
      else if ( gas_id == GAS_LPG ) {
        return (pow(10, ((-2.513 * (log10(rs_ro_ratio))) + 1.878)));
      }
      else if ( gas_id == GAS_CARBON_MONOXIDE ) {
        return (pow(10, ((-1.525 * (log10(rs_ro_ratio))) + 1.994)));
      }
      else if ( gas_id == GAS_HYDROGEN ) {
        return (pow(10, ((-2.568 * (log10(rs_ro_ratio))) + 0.360)));
      }
      else if ( gas_id == GAS_METHANE ) {
        return (pow(10, (-281.3 * pow((log10(rs_ro_ratio)), 3) - 12.26 *
                         pow((log10(rs_ro_ratio)), 2) - 7.925 * (log10(rs_ro_ratio)) + 1.668)));
      }
      else if ( gas_id == GAS_CARBON_DIOXIDE ) {
        return (pow(10, ((-2.890 * (log10(rs_ro_ratio))) + 2.055)));
      }
      else if ( gas_id == GAS_AMMONIUM ) {
        return (pow(10, ((-2.469 * (log10(rs_ro_ratio))) + 2.005)));
      }
    }

body:
  First of all you only need to include once. Including anything more than once is pointless and could be bad, if the header doesn't have include guards (yours do, but still it just makes the code harder to read).

  Let's take a look at the `MQResistanceCalculation` function, well... It's simply broken.

    float MQResistanceCalculation(int raw_adc)
    {
      return ( ((float)RL_VALUE_MQ5 * (1023 - raw_adc) / raw_adc));
      return ( ((float)RL_VALUE_MQ7 * (1023 - raw_adc) / raw_adc));
      return ( ((float)RL_VALUE_MQ8 * (1023 - raw_adc) / raw_adc));
      return ( ((float)RL_VALUE_MQ135 * (1023 - raw_adc) / raw_adc));
    }

  I'm not sure what you expect to happen, but as soon as you reach a return statement that block of code stops and the result is returned, so basically that function executes the first return and then stops. You probably want to pass a sensor type and then use a switch to make it return for either the MQ5, MQ7, MQ8 or MQ135, because right now it only returns the MQ5 value.

  Then let's take a look at the `MQCalibration` function. So same thing as above applies, as long as you reach a return the function stops. Your `MQCalibration` function currently only does:

    float MQCalibration(int mq_pin)
    {
      int i;
      float RS_AIR_val = 0, r0;

      for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
        RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
        delay(CALIBRATION_SAMPLE_INTERVAL);
      }
      RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
      r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ5;

      return r0;
    }

  And then the `MQGetGasPercentage` function can be re-written with switch statements to be way easier to read and understand. Oh and also that `accuracy == 0` check is also pointless it has nothing in it.

  From reading this I see you've just copied code you don't understand and hoped it'll work, but as expected it didn't. And well copying code without atleast having an idea about what it does is stupid. So just read it, understand it and write it again, but by yourself. Your code has many pointless variable declarations and it just isn't well "written"(or copy-pasted should I say).

  Also I've never worked with that sensor myself, so I was looking at the code aspect mostly, just so you know.


message:
Optocoupler on Tinkercad acting weird

So, maybe it's my understanding that is at fault or maybe it's tinkercad. It's probably the former. But anyway here's my problem

I've connected it according to picture

https://i.stack.imgur.com/SJ88F.jpg

There is no power going through the anode. The cathode is going to ground.
On the upper side 5v is going to base and the emitter sends signals to an input on pin 12.

If i digitalRead pin 12 and Serial.write it. it says 1. which is weird, least for my understanding.

As i understood there needs to be power going through the anode which lights up the diode inside the optocoupler. however there is no power going through the anode yet the emitter gives off a signal.

Anyone mind helping me out in understanding why this is?

Please ignore the resistors on the image

body:
You connected 5V to the base of the transistor inside, so the transistor is turned on all the time.

Move the 5v pin one to the right (middle pin on the 4N35, i.e. the collector), and it should work.


message:
Anomalous behaviour of ADC, digitalWrite and floating point operations

I'm trying to analyse mic (A0) input, calculate certain spectral lines with Goertzel algorithm to detect a number encoded by DTFM and display it with 8x8 matrix display (max7219 driver).

The code works perfectly fine without a display sending the result to serial, however when I added a display, strange things started to happen.

- if `goertzel(..)` is called before `displayDigit` the display doesn't show anything

- if `displayDigit` is called first the output of `goertzel(..)` is a complete mess

- if I comment out 1 line in `goertzel(..)` which is `amp = sqrt(re * re + im * im); // [1]` the display works (but it doesn't make sense)

I'm using Arduino UNO, ADC in free-run mode.

The code below:

    /**
     * 8x8 LED matrix display with MAX7219 driver
     * +5V, GND, CLK (8 pin), CS (9 pin), DIN (10 pin)
     */
    #include <binary.h>
    #include <LedControl.h>

    #include "font8x8.h"

    #define N           256
    #define IX_LEN      8
    #define THRESHOLD   20

    /* Display PINs */
    #define CLK     13//8
    #define CS      12 //9
    #define DIN     8 //10

    LedControl matrix = LedControl(DIN, CLK, CS, 1);
    int8_t lastDetectedDigit = -1;
    int8_t currentDigit = -1;
    uint32_t lastDetectedMillis = 0;

    const int adc_channel = 0;

    volatile uint16_t samples[N];
    volatile uint16_t samplePos = 0;

    float spectrum[IX_LEN] = {0,0,0,0,0,0,0,0};

    // Frequences [697.0, 770.0, 852.0, 941.0, 1209.0, 1336.0, 1477.0, 1633.0]
    // Corresponding spectrum indexes [18, 20, 22, 25, 32, 35, 39, 43]

    // Calculated for 9615Hz 256 samples
    const float cos_t[IX_LEN] = {
      0.9039892931234433, 0.881921264348355, 0.8577286100002721, 0.8175848131515837,
      0.7071067811865476, 0.6531728429537769, 0.5758081914178454, 0.49289819222978415
      };

    const float sin_t[IX_LEN] = {
      0.4275550934302821, 0.47139673682599764, 0.5141027441932217, 0.5758081914178453,
      0.7071067811865475, 0.7572088465064845, 0.8175848131515837, 0.8700869911087113
      };

    const char table[4][4] = {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
    };

    const uint8_t char_indexes[4][4] = {
      {0, 1, 2, 12},
      {3, 4, 5, 13},
      {6, 7, 8, 14},
      {10, 9, 11, 15}
    };

    void initADC() {
      // Init ADC; f = ( 16MHz/prescaler ) / 13 cycles/conversion
      ADMUX  = adc_channel; // Channel sel, right-adj, use AREF pin
      ADCSRA = _BV(ADEN)  | // ADC enable
               _BV(ADSC)  | // ADC start
               _BV(ADATE) | // Auto trigger
               _BV(ADIE)  | // Interrupt enable
               _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // 128:1 / 13 = 9615 Hz
    //  ADCSRB = _BV(ADTS2) | _BV(ADTS0);              // Timer/Counter1 Compare Match B
      ADCSRB = 0; // Free-run mode
      DIDR0  = _BV(adc_channel); // Turn off digital input for ADC pin
    }

    void goertzel(volatile uint16_t *samples, float *spectrum) {
      float v[N + 2];
      float re, im, amp;

      for (uint8_t k = 0; k < IX_LEN; k++) {
        float a = 2. * cos_t[k];
        v[0] = v[1] = .0;
        for (uint16_t i = 2; i < N + 2; i++) {
          v[i] = float(samples[i - 2]) + a * v[i - 1] - v[i - 2];
        }
        re = cos_t[k] * v[N + 1] - v[N];
        im = sin_t[k] * v[N + 1];
        amp = sqrt(re * re + im * im); // [1]
        spectrum[k] = amp;
      }
    }

    float avg(float *a, uint16_t len) {
      float result = .0;
      for (uint16_t i = 0; i < len; i++) {
        result += a[i];
      }
      return result / len;
    }

    int8_t get_single_index_above_threshold(float *a, uint16_t len, float threshold) {

      if (threshold < THRESHOLD) {
        return -1;
      }

      int8_t ix = -1;
      for (uint16_t i = 0; i < len; i++) {
        if (a[i] > threshold) {
          if (ix == -1) {
            ix = i;
          } else {
            return -1;
          }
        }
      }
      return ix;
    }

    char detect_digit(float *spectrum) {
      float avg_row = avg(spectrum, 4);
      float avg_col = avg(&spectrum[4], 4);
      int8_t row = get_single_index_above_threshold(spectrum, 4, avg_row);
      int8_t col = get_single_index_above_threshold(&spectrum[4], 4, avg_col);

      if (row != -1 && col != -1) {
        return table[row][col];
      } else {
        return 0;
      }
    }

    void displayDigit(uint8_t c) {
      if (currentDigit == c) {
        return;
      }

      for (uint8_t i = 0; i < 8; i++) {
        matrix.setColumn(0, 7 - i, IMAGES[c][i]);
      }
      currentDigit = c;
    }

    void setup() {
      cli();
      initADC();
      sei();

      matrix.shutdown(0, false);
      matrix.setIntensity(0, 2);

      Serial.begin(115200);

    }

    unsigned long z = 0;

    void loop() {
      while(ADCSRA & _BV(ADIE)); // Wait for audio sampling to finish

      goertzel(samples, spectrum);
      samplePos = 0;

    //  if (z % 25 == 0) {
        displayDigit(2);

        for (int i = 0; i < IX_LEN; i++) {
          Serial.print(spectrum[i]);
          Serial.print("\t");
        }
        Serial.println();
        char digit = detect_digit(spectrum);
        Serial.println(digit);
    //  }
      z++;

      ADCSRA |= _BV(ADIE);       // Resume sampling interrupt
    }

    ISR(ADC_vect) {
      uint16_t sample = ADC;

      samples[samplePos++] = sample;

      if(samplePos >= N) {
        ADCSRA &= ~_BV(ADIE); // Buffer full, interrupt off
      }
    }

`font8x8.h`:

    const byte IMAGES[16][8] = {
    {
      B00001000,
      B00011000,
      B00001000,
      B00001000,
      B00001000,
      B00001000,
      B00001000,
      B00011100
    },{
      B00111100,
      B01000010,
      B01000010,
      B00000100,
      B00011000,
      B00100000,
      B01000000,
      B01111110
    },{
      B00111100,
      B01000010,
      B00000010,
      B00000100,
      B00000100,
      B01000010,
      B01000010,
      B00111100
    },{
      B00010100,
      B00100100,
      B00100100,
      B01000100,
      B01111110,
      B00000100,
      B00000100,
      B00000100
    },{
      B00111110,
      B01000000,
      B01000000,
      B01111100,
      B00000010,
      B00000010,
      B01000010,
      B00111100
    },{
      B00111100,
      B01000010,
      B01000000,
      B01111100,
      B01000010,
      B01000010,
      B01000010,
      B00111100
    },{
      B00111110,
      B01000010,
      B00000100,
      B00000100,
      B00001000,
      B00001000,
      B00010000,
      B00010000
    },{
      B00111100,
      B01000010,
      B01000010,
      B00111100,
      B01000010,
      B01000010,
      B01000010,
      B00111100
    },{
      B00111100,
      B01000010,
      B01000010,
      B01000010,
      B00111110,
      B00000010,
      B01000010,
      B00111100
    },{
      B00111100,
      B01000110,
      B01001010,
      B01010010,
      B01010010,
      B01010010,
      B01100010,
      B00111100
    },{
      B00000000,
      B01010100,
      B00111000,
      B01111100,
      B00111000,
      B01010100,
      B00000000,
      B00000000
    },{
      B00101000,
      B00101000,
      B11111110,
      B00101000,
      B11111110,
      B00101000,
      B00101000,
      B00000000
    },{
      B00011100,
      B00100010,
      B00100010,
      B01000010,
      B01111110,
      B01000010,
      B01000010,
      B01000010
    },{
      B01111100,
      B01000010,
      B01000010,
      B01111100,
      B01000010,
      B01000010,
      B01000010,
      B01111100
    },{
      B00111100,
      B01000010,
      B01000000,
      B01000000,
      B01000000,
      B01000000,
      B01000010,
      B00111100
    },{
      B01111000,
      B01000100,
      B01000110,
      B01000010,
      B01000010,
      B01000010,
      B01000010,
      B01111100
    }};

I use `LedControl.h` library but inside is uses only digitalWrite, no timing, interrupts.

Can somebody explain what is the problem?

**UPD**
This is what IDE tells me about the sizes:

    Sketch uses 5602 bytes (17%) of program storage space. Maximum is 32256 bytes.
    Global variables use 1048 bytes (51%) of dynamic memory, leaving 1000 bytes for local variables. Maximum is 2048 bytes.

[This is LedControl library I'm using][1]

  [1]: https://github.com/wayoda/LedControl

body:
From your recent edit:
> Global variables use 1048 bytes (51%) of dynamic memory, leaving 1000
> bytes for local variables. Maximum is 2048 bytes.

Your `goertzel()` function defines this

    float v[N + 2];

where `N` is 256. This alone takes 258×4 = 1032 bytes of
stack and you only have 1000 bytes available. Then, as I suspected,
you are smashing the stack against the [.bss section][bss], effectively
overwriting some of your global variables with the local ones.

It is hard to predict what can happen in such circumstances. The program
is corrupting its memory: you can only expect it to act erratically.

[bss]: https://en.wikipedia.org/wiki/.bss


message:
How would I go about powering addressable RGB LED light strip? [Arduino Nano]

The addressable RGB LED I have is WS2812B. I plan on controlling the LEDs via an Arduino nano. I have a total of 188 LEDs to supply power to.

Would I require anything between the addressable RGB LED strip and the 12v power supply?

Would I require a 1000uF capacitor?

body:
> Would I require anything between the addressable RGB LED strip and the 12v power supply?

A suitable 5V regulator (assuming 5V LED strip)

> Would I require a 1000uF capacitor?

For what? A suitable 5V regulator won't need one. An unsuitable one would be improved by it, but still be unsuitable.


message:
How are errors (not related to syntax) managed in arduino and in the AVR architecture in general?

I was just curious about how the AVR architecture manages errors that would cause a regular desktop program to crash. I'm talking about logical errors for example math problems that are undefined. Such as division by 0 and getting a square root of a negative number. At first I was expecting that by giving an error to the AVR chip it will just return 0. But I ran this program:

    void setup() {
    Serial.begin(9600);
    }
    void loop(){
    int x = 0;
    int p = 50;
    int result;
    result = p/x;
    Serial.println(result);
    result = sqrt(-10);
    delay(1000);
    Serial.println(result);
    delay(10000);
    }
and got this output:

    4294967295
    0
After this I got really confused. Why would the `result` variable take the maximum value of an `unsigned long`? Since I declared an `int` the micro controller must have dedicated 2 bytes of dynamic memory to this variable but apparently it somehow managed to get additional 2 bytes to store the data. Could this mean that the AVR chip can corrupt data in other memory locations while allocating new data for the variable that just was fed a undefined in to it? Okay maybe the AVR chip just sets any mathematical nonsense to 4294967295. But no in the example of getting the square root of -10 we see that the value became 0. Although this is probably a function processed by some library so maybe there is some kind of protection against these errors. Also, I tried to run the program above but with a `byte` variable for the `result` instead of `int`.

    void setup() {
    Serial.begin(9600);
    }
    void loop(){
    int x = 0;
    int p = 50;
    int result;
    result = p/x;
    Serial.println(result);
    result = sqrt(-10);
    delay(1000);
    Serial.println(result);
    delay(10000);
    }

 And the result was the same. So, is there some kind of documentation about error management in AVR since this is important to know while development.

P.S. Everything was run on a real Atmega 328p chip on an arduino nano.

body:
The simple answer is: they are not handled at all.

According to the C and C++ standards, what you are invoking is called
[_undefined behavior_][UB], meaning anything can happen. In practical
terms, it means that the compiler can do its optimizations _assuming_
you will never invoke undefined behavior, and completely disregard what
could happen if the assumption does not hold. The generated code could
be completely broken, it won't be the compiler's fault.

The AVR architecture cannot do divisions, nor floating point math. Thus
all the errors you have here happen at the software level. Note that
`sqrt(-10)` is _not_ an error (it's NaN, which is correctly handled by
the avr-libc), but converting that to an int (which you do when you
assign it to `result`) is an error.

If you really want to know the details of what happens with each of
these errors, there is only one option: you have to disassemble the
executable program and read the assembly listing.

[UB]: https://www.nayuki.io/page/undefined-behavior-in-c-and-cplusplus-programs


body:
**About the number 4294967295**

To my surprise, the sketch produces indeed the number 4294967295. That is not okay.
It turns out that the compiler knows the numbers and tries to do the math itself (instead of runtime).

At runtime, the `50 / 0` results into a signed integer of -1.
When a byte is used, the `50 / 0` results into 255.
The result of that calculation is a variable with only 1's. That is 0xFFFF for a 16-bits variable. That results into 65535 for a unsigned integer and -1 for a signed integer and 255 for a unsigned byte.

So far, that is okay. It makes sense.

However, when the compiler tries to do the math itself with `50 / 0`, it turns the result into a 32-bit variable of 0xFFFFFFFF. The compiler does not put the math into the binary result, but calls the Serial.println() directly with a 32-bit unsigned long of 0xFFFFFFFF, which is 4294967295.

The reason is not the variable type of the variable '`result`', but the division with '`p/x`'. The compiler thinks it is better to make a 32-bit integer when the math is done with two 16-bit integers.

I think that when the compiler optimizes, the result should be same as a runtime calculation.
There is an interesting discussion below this answer. @EdgarBonet calls the compiler behaviour weird but not a bug.

Below is a test sketch that produces 4294967295 with Arduino 1.8.7 for an Arduino Uno:

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

    void loop(){
      int x = 0;
      int p = 50;
      int result;
      result = p/x;
      Serial.println(result);
      delay(5000);
    }

The code outputs normal results when 'x' or 'p' is calculated, for example the result from a function, or when one of the three variables is made volatile.


message:
Wemos D1 mini fatal exception

I'm trying to flash a Wemos D1 mini ESP8266 board with the blink sketch, but get an error. The built in LED turns off when flashing starts.

    Sketch uses 247872 bytes (23%) of program storage space. Maximum is 1044464 bytes.
    Global variables use 28000 bytes (34%) of dynamic memory, leaving 53920 bytes for local variables. Maximum is 81920 bytes.
    warning: serialport_set_baudrate: baud rate 921600 may not work
    warning: espcomm_sync failed
    error: espcomm_open failed
    error: espcomm_upload_mem failed
    error: espcomm_upload_mem failed

I tried changing the programming speed to most of the other options.

If I open the serial monitor and set the baud rate to `74880`, I get the following message repeatedly.

    Fatal exception (0):
    epc1=0x400cd530, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Is the board dead, or is there a way of reflashing it without using the serial port?

body:
Flashing with the serial port is the only practical option. The flash chip can be removed, and it can be flashed off board, but that isn't practical.

Has the board ever worked? Have you used other RSP8266 boards before or is this the first you have? Do you have a different USB cable you can try? Marginal power can cause unpredictable operation.


message:
compilation error when changing variable from char to String

I have a code with these two lines:

      char handshakecode = "S"; // Capital S
      char receive;

The lines of code are placed in a separate `void`, and not `setup` or `loop`.
When i change the two variables from `char` to `String` i get a error(complete error at bottom) when compiling to the arduino or verifying the code.

      String handshakecode = "S"; // Capital S
      String receive;

When i snippes out partial code for just that particular `void`, it compiles fine, so it must be in combination with the rest of the code, which i have left out from this post at the moment.

Is this a known error or am I doing something wrong?

> In function 'global constructors keyed to 65535_0_WFS_v0.3.ino.cpp.o':
>
> lto1.exe: internal compiler error: Segmentation fault
>
> Please submit a full bug report,
>
> with preprocessed source if appropriate.
>
> See <http://gcc.gnu.org/bugs.html> for instructions.
>
> lto-wrapper.exe: fatal error: C:\Program
> Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.15.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avr-gcc
> returned 1 exit status
>
> compilation terminated.
>
> c:/program
> files/windowsapps/arduinollc.arduinoide_1.8.15.0_x86__mdqgnx93n4wtt/hardware/tools/avr/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld.exe:
> error: lto-wrapper failed
>
> collect2.exe: error: ld returned 1 exit status
>
> exit status 1 Error compiling for board Arduino/Genuino Mega or Mega
> 2560.

body:
This bug is specific to the 5.4.0-atmel3.6.1-arduino2 version of avr-gcc used by Arduino AVR Boards 1.6.22 and newer. It has been reported here:

https://github.com/arduino/Arduino/issues/7949

Here's the workaround:

1. Tools > Board > Boards Manager
2. Wait for downloads to finish.
3. When you move the mouse pointer over "Arduino AVR Boards", you will see a "Select version" dropdown menu appear. Select "1.6.21".
4. Click "Install".
5. Wait for installation to finish.
6. Click "Close".

Due to a [bug](https://github.com/arduino/Arduino/issues/7973), this workaround doesn't work with Arduino IDE 1.8.6, but it will work with any other version of the Arduino IDE.

If you have **File > Preferences > Check for updates on startup** checked, the Arduino IDE may occasionally notify you that a new version of Arduino AVR Boards is available, you'll need to refrain from updating back to the new Arduino AVR Boards version, otherwise you'll be back to seeing the segmentation fault error again.