message:
Infinite Loop on Pin Input (Teensy 3.1)?

I have an infinite loop issue that keeps persisting in this code on my Teensy 3.1. This program is intended to take an input on Pin 0 and press the Enter key on the computer it is hooked into.

It is connected to a wire with no current but once a switch is flipped it should send a 5v Digital Signal blip to the Teensy and trigger it to run. It does function but it keeps getting caught in an infinite loop for some reason. Any help would be greatly appreciated!

    // Global Variable
    int signal_receiving_pin = 0;

    void setup() {
      // Outputting for error checking
      Serial.begin(38400);

      // Readying the pin for input
      pinMode(signal_receiving_pin, INPUT);
    }

    void loop()
    {
    // If statement to check whether an input has been received
    if (digitalRead(signal_receiving_pin) == HIGH)
    {
      // If the signal has been detected..
      Serial.println("The signal has been received \n");
      Serial.println("Now sending the ENTER signal \n");

      // .. The ENTER key is sent to the computer
      //Keyboard.press(KEY_ENTER);
      //Keyboard.release(KEY_ENTER);

      // Waiting 1 minute before allowing more input
      //delay(60000); // Pause
    }
    else
    {
      // If the signal is not detected..
      // it will let you know it isn't there
      Serial.println("Input not detected \n");
    }
    }

body:
Try using the internal Pullup/Pulldown resistor to control the input when the pin is not connected to anything.  If you do not have a pullup/pulldown, then the input capacitance on the input pin circuitry can sample and hold the 5V unreliably.

    ...
    void setup() {
      // Outputting for error checking
      Serial.begin(38400);

      // Readying the pin for input
      pinMode(signal_receiving_pin, INPUT_PULLDOWN);
    }
    ...

You may want to uncomment the delay() or add some state logic trigger only one activation per each cycle of `signal_receiving_pin`


sender: user

message:
NeoPixel library performance: Adafruit vs. FastLED

I'm new to these addressable LED things – I just received a 149-LED WS2812B strip today, and I'm experimenting with various approaches. Adafruit's own tutorial says the FastLED library is faster than their Adafruit_NeoPixel library, so I wanted to test their performance.

I'm running this code on a Nano clone:

    // Adafruit
    #include <Adafruit_NeoPixel.h>
    // FastLED
    #include <FastLED.h>
    // Common
    #define NUM_LEDS 149
    #define DATA_PIN 6

    // Adafruit initialization
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
    const uint32_t adaBlack = strip.Color(0, 0, 0);
    const uint32_t adaWhite = strip.Color(255, 255, 255);

    // FastLED initialization
    CRGB leds[NUM_LEDS];

    void setup() {
      // Common
      delay(2000);

      // Adafruit setup
      strip.begin();

      // FastLED setup
      FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);

      // Common
      Serial.begin(57600);
    }

    void loop() {
      unsigned int adafruitMillis = adafruitLoop();
      unsigned int fastLedMillis = fastLedLoop();
      // Yes, this is ugly -- but it works every time
      Serial.print(adafruitMillis);
      Serial.print(",");
      Serial.println(fastLedMillis);
    }

    unsigned int adafruitLoop()
    {
      long unsigned startMillis = millis();
      for (int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++) {
        strip.setPixelColor(whiteLed, adaWhite);
        strip.show();
        strip.setPixelColor(whiteLed, adaBlack);
      }
      return (unsigned int) millis() - startMillis;
    }

    unsigned int fastLedLoop()
    {
      long unsigned startMillis = millis();
      for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++) {
        leds[whiteLed] = CRGB::White;
        FastLED.show();
        leds[whiteLed] = CRGB::Black;
      }
      return (unsigned int) millis() - startMillis;
    }

The results are totally disastrous for FastLED (shown in red):
[![FastLED is red, Adafruit's library in blue][1]][1]

Am I doing something wrong, or is FastLED winning on features, rather than on speed?

For the record, I did check whether the performance hit comes from setting the pixel values or from sending the data – FastLED is faster at setting the pixel values than Adafruit's library, but that doesn't matter because setting *two* pixel values takes 3 ms or less for the entire strip, regardless of the library. Sending the data to the strip takes most of the time, and that's where FastLED lags behind big time (900 ms compared to Adafruit's 200 ms).

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

sender: assistant

body:
As I understand it, the *Fast* in *FastLED* isn't for sending the data, but for manipulating the array/data that holds the colors. The FastLED library contains many functions optimized for dealing with 8-bit unsigned integers for holding color values, including color addition, 8-bit scaling, partially-defined color palettes (for example, you define 8 waypoints in the palette, but can grab a color from the full 8-bit range and it interpolates on the fly using the fast 8-bit math.

Not just math, but also conversion to/from RGB and HSV realms, etc.

It supports pushing multiple strips at the same time (parallel) by writing to the whole `PORT` instead of just one pin of the 8-pin port, so if you split your strip into multiples, you can really make speed gains in writing to the LEDs.


body:
You can't rely on the timing reported by millis when comparing FastLED and Adafruit's neopixel library.  Writing out Neopixel data involves disabling interrupts, which is what the clock uses to advance.  FastLED accounts for this and attempts to update the system clock time after writing out led data to account for the amount of time that interrupts were disabled, but the adafruit NeoPixel library doesn't.  You need to use something else to compare timing.

(WS2812 data has a pretty strict data rate - 800khz, or about 30µs per rgb led)

(I should know, I wrote FastLED :)


message:
Can't burn bootloader through Arduino Nano clone ISP to atmega328p

I'm trying to use a Nano v3 as ISP to program an atmega328p on a board with ISP headers:

I followed the instructions under
https://www.arduino.cc/en/Tutorial/ArduinoISP which I think have been recently updated. I'm simply connecting ISP headers together except for D10 from programmer to reset on the target AVR.

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

The ISP sketch seems to be working fine as far as I can see the heartbeat pulsing a led. But when trying to burn bootloader with settings:

    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x15
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x15

    avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x14

    avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x01
    avrdude: stk500_initialize(): (a) protocol error, expect=0x14, resp=0x10
    avrdude: initialization failed, rc=-1
             Double check connections and try again, or use -F to override
             this check.

    avrdude: stk500_disable(): unknown response=0x12
    Error while burning bootloader.

<s>I noticed something weird though, the 5V and GND on the ISP header on the programmer nano only has around 0.4V. This even without anything external but the usb connected. Is my nano broken or is the usb connection not able to deliver enough power?</s>

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

body:
Your slave micro isnt resetting when your master wants it to reset.

Ie: master sends a reset signal before initiating further communication, and it seems that your slave not being reset.

So its not responding.

Once cross check your isp signal lines.


body:
Try adding the 10µF capacitor connected to `RESET` and `GND` on the board you are using as programmer (in this case, your Nano). This is required according to the [Documentation][1].

> The 10µF electrolytic capacitor connected to RESET and GND of the programming board is needed only for the boards that have an interface between the microcontroller and the computer's USB, like Mega, Uno, Mini, Nano.

I just encountered the exact same error output, and the capacitor solved it.

  [1]: https://www.arduino.cc/en/Tutorial/ArduinoISP#toc3


message:
Getting stable measurements with the BNO055 IMU

I bought the BNO055 "smart" IMU from [Adafruit][1], thinking it would be a simple way to get orientation data for a small mobile robot project, but I've found the thing to be very difficult to use and nearly worthless.

It's advertised as being able to auto-calibrate, and although it does attempt to do this, I've found that the calibration doesn't hold. It continuously re-calibrates itself, and either gets stuck in an error state or find a successful calibration...but then loses it after a few seconds.

Is there anything I can do to improve its stability? Does it need to be mounted inside a special grounded housing? Is there a special incantation I should utter before powering it on?

I'm reading it from an Arduino Uno via I2C, and though the wiring and programming is relatively simple, getting it calibrated and staying calibrated I've found to be nearly impossible.

Even after the "system" flag says its fully calibrated, and I have the IMU just sitting on a table, not moving, after a minute, it loses its "system" calibration. The accelerometer, gryoscope, and magnetometer usually remain calibrated, but how can I trust them if the on-board fusion algorithm is reporting it's not ready?

If the BNO055 is a lost cause, is there anything better? I've tried several MPU-**** chips from InvenSense, but they're even worse.

  [1]: https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/overview

body:
Try a permanent calibration. From the [Adafruit forums][1]:

> You'd basically need to read and write data registers 55-6A. In both cases, you have to set the sensor in CONFIG_MODE. There's more information on page 48 of the [datasheet][2].

The magnetometer is influenced by surrounding magnetic sources like motors. You might be able to tell the extent of the effect using the [following method][1]:

> The System Calibration Status will start out at 0 and will go to 3
> when the sensor is calibrated. For example, the mag calibration status
> will go to 3 if you do some figure 8s. If you put a piece of metal
> near the sensor, the calibration status will drop to 0. But when the
> metal is moved away, it will go back to 3. You may be able to use this
> value as an indicator that calibration is lost. I have found that once
> it's calibrated, it seems to hold calibration well.

For getting solid readings out of the gyroscope, [this][3] might be helpful advice:

> I don't worry about scaling the gyro output on a per-sample basis. I simply sum the output into a 32 bit (or larger) integer register. I do subtract-out a null value at each sample, which I will talk about later. But essentially, if you sample your gyro at 1kHz, and sum the output into an accumulator, you will see that the value of that accum at any time will be directly proportional the angle of rotation. If your rate is set for 250 deg/sec, then a rotation of 180 deg will result in approximately 23330000 in the accumulator. I call that the GYRO_CAL number. So, at any given time the angle, in degrees, is deg = accum / GYRO_CAL * 180.
>
> Since the gyro output is linear, the accumulator is insensitive to
> whether the rotation is fast or slow (as long as the max deg/sec isn't
> exceeded).
>
> Here is my basic routine for each gyro reading:

`void read_FIFO(){
       sample = read_value_from_FIFO();   //read the latest z-axis sample. I use the fifo, but that isn't necessary
       accum += sample - null;           //add the sample to the sum and subtract the null
       if((accum > GYRO_CAL) -= GYRO_CAL*2;  //roll the accumulator at +180 deg.
       if((accum < -GYRO_CAL) += GYRO_CAL*2; // roll the accumulator at -180 deg.
       angle = accum/GYRO_CAL * 180;   // convert to degrees
}`

> I calculate the null at the beginning of each run. I sum 1000 readings
> and take the average. The gyro has to sit still for 3 or 4 seconds for
> this. The GYRO_CAL value can be calculated by summing the output while
> you rotate the gyro by 180 deg. Or you can sum over many turns, and
> divide by the number of 180 deg turns for a more accurate value.
>
> You could probably use a 64-bit FP for the accumulator, but since
> arduino only supports 32 bit FP, I found it absolutely necessary to
> use a 32 bit integer to avoid roundoff and other errors.
>
> If you follow that general outline, I promise you will get rock solid
> performance out of the gyro. There are a few other small optimizations
> that I make, which I can discuss later.

  [1]: https://forums.adafruit.com/viewtopic.php?f=19&t=73014
  [2]: https://cdn-shop.adafruit.com/datasheets/BST_BNO055_DS000_12.pdf
  [3]: https://groups.google.com/forum/#!topic/diyrovers/5CAeROsWLZ4


message:
Writing data to a specific address in EEPROM

I'm trying to write two strings to an Arduino Uno's EEPROM. Here, the first code block works fine: it writes string(True/False) at 'address 0'. But the second block, which writes data at 'address 5', is not working as expected.Reading data at address 5 prints a blank line. What am I missing here? Is this the correct way to write two different strings to EEPROM?

First code block:

    int state = LOW;
    char first_eeprom_value;
    if (state == LOW) {
      state = HIGH;
      char example_string[4] = "True";
      first_eeprom_value = EEPROM.read(0);
      Serial.println(first_eeprom_value);
      for (int i = 0 ; i < 5 ; i++) {
        EEPROM.update(i, example_string[i]);
      }
    } else {
      state = LOW;
      char example_string[5] = "False";
      first_eeprom_value = EEPROM.read(0);
      Serial.println(first_eeprom_value);
      for (int i = 0 ; i < 5; i++) {
        EEPROM.update(i, example_string[i]);
      }
    }
    Time = millis();

Second code block:

    char first_eeprom_value1;
    if (state1 == LOW) {
      state1 = HIGH;
      char example_string1[4] = "True";
      first_eeprom_value1 = EEPROM.read(5);
      Serial.println(first_eeprom_value1);
      for (int i = 5 ; i < 11 ; i++) {
        EEPROM.update(i, example_string1[i]);
      }
    } else {
      state1 = LOW;
      char example_string1[5] = "False";
      first_eeprom_value1 = EEPROM.read(5);
      Serial.println(first_eeprom_value1);
      for (int i = 5 ; i < 11 ; i++) {
        EEPROM.update(i, example_string1[i]);
      }
    }

    Time = millis();

    //reading data at address 5
    int addr = 5;
    char value = EEPROM.read(addr);
    Serial.println(value);// this prints blank line

body:
You are cycling outside the string, thus creating undefined behavior.

Try replacing the second block with this:

    char first_eeprom_value1;
    if (state1 == LOW) {
      state1 = HIGH;
      char example_string1[4] = "True";
      first_eeprom_value1 = EEPROM.read(5);
      Serial.println(first_eeprom_value1);
      for (int i = 0; i < sizeof(example_string1); i++) {
        EEPROM.update(i + 5, example_string1[i]);
      }
    } else {
      state1 = LOW;
      char example_string1[5] = "False";
      first_eeprom_value1 = EEPROM.read(5);
      Serial.println(first_eeprom_value1);
      for (int i = 0; i < sizeof(example_string1); i++) {
        EEPROM.update(i + 5, example_string1[i]);
      }
    }

Please note that this is not optimal; I suggest you to use fixed-length strings, and fill the unused spaces with blanks or 0s, so you can read back all the bytes you wrote in a safe way


message:
How to input text from Serial monitor into a character array?

I'm using a Mega 2560 and Uno and want to input text to the serial monitor which can be stored in character array char in[];
I want array specifically as I'll be breaking each character to trigger different code for making a morse code.

        #include<Arduino.h>
    //#include<Softwareserial.h>

    int Speaker1 = 4;
    int Speaker2 = 6;
    int LED = 2;
    int Relay = 12;
    char n = '0';
    char in[];
    //int outPins[] = { 2, 4, 6, 8 };

    void high() {

      digitalWrite(Speaker1, HIGH);
      tone(Speaker2, 800);
      digitalWrite(LED, HIGH);
      digitalWrite(Relay, HIGH);

    }

    void low() {

      digitalWrite(Speaker1, LOW);
      tone(Speaker2, 800);
      digitalWrite(LED, LOW);
      digitalWrite(Relay, LOW);

    }

    void setup() {

      Serial.begin(9600);

      pinMode(Speaker1, OUTPUT);
      pinMode(Speaker2, OUTPUT);
      pinMode(LED, OUTPUT);
      pinMode(Relay, OUTPUT);

      Serial.print("Enter your desired text: ");
      //in = Serial.readString();  /*<-------------HELP NEEDED HERE */

      for (int i = 0; i < strlen(in); i++) {

        n = in[i];

        switch (n) {

          case 'A':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'B':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'C':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'D':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'E':
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'F':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'G':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'H':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'I':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'J':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'K':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'L':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'M':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'N':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'O':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'P':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'Q':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'R':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'S':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case 'T':
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'U':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'V':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'W':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'X':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'Y':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case 'Z':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case ' ':
            delay(700);
            break;
          case '1':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case '2':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case '3':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case '4':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;
          case '5':
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case '6':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case '7':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case '8':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case '9':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(100);
            low();
            delay(300);
            break;
          case '10':
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(100);
            high();
            delay(300);
            low();
            delay(300);
            break;

        }

      }

    }

    void loop() {

    }

body:
I don't understand exactly why your signals are much different from 'real' morse code, e.g. A is .-

Instead of calling each high and low separately like the 'a' for example:

      case 'A':
        high();
        delay(100);
        low();
        delay(100);
        high();
        delay(300);
        low();
        delay(300);
        break;

call it like this:

    case 'A':
      send2(false, true); /* means .-
      break;

Than create a function send2 which sends a . and a -
Something like:

    void send2(bool b1, bool b2)
    {
       send(b1);
       send(b2);
       delay(300); /* Extra wait in between characters */
    }

For characters needing 1, 3 or 4 characters, you can make send 1, send3 and send4 accordingly.

    void send(bool b1)
    {
       digitalWrite(Speaker1, b1 ? HIGH : LOW);
       tone(Speaker2, b1 ? 800);
       digitalWrite(LED, HIGH);
       digitalWrite(Relay, HIGH);
       delay(b1 ? 300 : 100); /* Assuming HIGH needs delay of 300 and low of 100 */
    }

    void low() {

      digitalWrite(Speaker1, LOW);
      tone(Speaker2, 800); /* I would expect two different values for HIGH and LOW */
      digitalWrite(LED  , b1 ? HIGH : LOW);
      digitalWrite(Relay, b1 ? HIGH : LOW);
    }


body:
I suggested in a comment you read the blog post [Reading Serial on the
Arduino][read serial]. In this post, Majenko shows a `readline()`
function that does almost exactly what you want. This function is
non-blocking, which, in the embedded world, is most of the time a
mandatory feature. However, in one of your comments you wrote that you
want a blocking function:

> I need the program to "wait" like [...] `scanf`

Degrading a non-blocking function into a blocking one is as easy as
wrapping the non-blocking function in a loop. Here is a code snippet for
reading a CR-terminated string, which is similar to a blocking version
of Majenko's `readline()`:

    char buffer[80];
    size_t pos = 0;
    for (;;) {
        int c = Serial.read();
        if (c == -1) continue;   // no input
        if (c == '\r') {         // end of line
            buffer[pos] = '\0';  // terminate the string
            break;
        }
        if (pos < sizeof buffer - 1) {
            buffer[pos++] = c;
        }
    }

That being said, I could not resist the temptation to brutally simplify
your program. The key to the simplification is to consider the Morse
code as a _data structure_. Then, the code for keying a string is
generic: you look up each character in the code table and key it in
turn. This saves the long `switch`/`case`:

    struct code_t {
        char c;
        const char *code;
    };

    static const code_t morse_code[] = {
        {'A', ".-"   }, {'B', "-..." }, {'C', "-.-." }, {'D', "-.."  },
        {'E', "."    }, {'F', "..-." }, {'G', "--."  }, {'H', "...." },
        {'I', ".."   }, {'J', ".---" }, {'K', "-.-"  }, {'L', ".-.." },
        {'M', "--"   }, {'N', "-."   }, {'O', "---"  }, {'P', ".--." },
        {'Q', "--.-" }, {'R', ".-."  }, {'S', "..."  }, {'T', "-"    },
        {'U', "..-"  }, {'V', "...-" }, {'W', ".--"  }, {'X', "-..-" },
        {'Y', "-.--" }, {'Z', "--.." },
        {'1', ".----"}, {'2', "..---"}, {'3', "...--"}, {'4', "....-"},
        {'5', "....."}, {'6', "-...."}, {'7', "--..."}, {'8', "---.."},
        {'9', "----."}, {'0', "-----"},
        {' ', " "    }, {'\0', NULL}  // sentinel
    };

    static inline void high() { digitalWrite(LED_BUILTIN, HIGH); }
    static inline void low()  { digitalWrite(LED_BUILTIN, LOW);  }

    // Key a string in Morse.
    void key(const char *s)
    {
        for (; *s; s++) {  // *s = current letter

            // Find this letter's code.
            const code_t *p;
            for (p = morse_code; p->c; p++) {
                if (p->c == toupper(*s)) break;  // found
            }
            if (!p->c) continue;  // not found -> ignore

            // Send this code's symbols.
            for (const char *code = p->code; *code; code++) {
                if (*code != ' ')
                    high();
                switch (*code) {
                    case ' ': delay(100); break;
                    case '.': delay(100); break;
                    case '-': delay(300); break;
                }
                low();
                delay(100);
            }
            delay(200);  // inter-letter spacing = 300 ms
        }
    }

    void setup()
    {
        Serial.begin(9600);
        pinMode(LED_BUILTIN, OUTPUT);
    }

    void loop()
    {
        // Read a string.
        char buffer[80];
        size_t pos = 0;
        for (;;) {
            int c = Serial.read();
            if (c == -1) continue;   // no input
            if (c == '\r') {         // end of line
                buffer[pos] = '\0';  // terminate the string
                break;
            }
            if (pos < sizeof buffer - 1) {
                buffer[pos++] = c;
            }
        }

        // Key it in Morse.
        key(buffer);
    }

Note that this program reads CR-terminated strings from the Serial port
and keys them on the builtin LED. If you want your program to work on a
single string, you can call `exit()` at the end of `loop()` or,
alternatively, merge `loop()` into `setup()` and provide an empty
`loop()`.

[read serial]: https://hackingmajenkoblog.wordpress.com/2016/02/01/reading-serial-on-the-arduino/


message:
No ttyACM0 nor ttyUSB0

I checked several related posts but couldn't solve my problem.

I have Antergos Linux :

    # uname -a
    Linux biutitude 4.14.11-1-ARCH #1 SMP PREEMPT Wed Jan 3 07:02:42 UTC 2018 x86_64 GNU/Linux
The board is a Seeeduino Lorawan.

The problem is that the menu to select the port is greyed, and when I check in /dev I don't see any new tty when I plug the card. However the card blinks.

I tried :
- adding myself to lock + tty + uucp (and restarted my session)
- created a dialout group because I didn't have one, added myself to it
- loading cdc_acm module but got the following error :

    # modprobe cdc_acm
    modprobe: FATAL: Module cdc_acm not found in directory /lib/modules/4.14.11-1-ARCH
Thus I tried :

    [root@biutitude biu]# depmod -ae
    depmod: WARNING: -e needs -E or -F
    depmod: ERROR: could not open directory /lib/modules/4.14.11-1-ARCH: No such file or directory
    depmod: FATAL: could not search modules: No such file or directory
    [root@biutitude biu]# depmod
    depmod: ERROR: could not open directory /lib/modules/4.14.11-1-ARCH: No such file or directory
    depmod: FATAL: could not search modules: No such file or directory

I'm clearly out of ideas. The weirdest is that a few months ago, I was able to use a RFduino card without any trouble.

body:
My solution - install linux-modules-extra kernel module on ubuntu 20.04. Solved my problem which was identical.

Get OS details:

    uname -a
    Linux seeeduino-node 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Install the sudo apt install linux-modules-extra:

    sudo apt install linux-modules-extra-<kernel-version>

Example:

    sudo apt install linux-modules-extra-5.4.0-91-generic

You need to reboot the machine afterwards it should work.


message:
How do I control the buttons on an Arduino LCD keypad shield?

I have just bought a [16x2 LCD display with buttons][1]. I can get the display to work and do various basic sketches included in the Arduino IDE. However, I cannot figure out how to control the buttons.

The buttons work using analog pin 0 and from what I was able to understand from what I have read online, it is something to do with the values you receive when the buttons are pressed. I can't seem to find out what values mine gives, I have found a sketch that is supposed to map the buttons, but I cannot get it to work, as I don't really understand what it is doing, I am very new to this.

The code I am using is as follows:

<!-- language-all: lang-cpp -->

    #include <LiquidCrystal.h>

    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

    int lcd_key     = 0;
    int adc_key_in  = 0;

    #define btnRIGHT  0
    #define btnUP     1
    #define btnDOWN   2
    #define btnLEFT   3
    #define btnSELECT 4
    #define btnNONE   5

    int read_LCD_buttons() {
      adc_key_in = analogRead(0);
      if (adc_key_in > 1000) return btnNONE;
      if (adc_key_in < 50)   return btnRIGHT;
      if (adc_key_in < 250)  return btnUP;
      if (adc_key_in < 450)  return btnDOWN;
      if (adc_key_in < 600)  return btnLEFT;
      if (adc_key_in < 920)  return btnSELECT;
      return btnNONE;
    }

    void setup() {
      lcd.begin(16, 2);
      lcd.setCursor(0,0);
      lcd.print("Push the buttons");
    }

    void loop() {
      lcd.setCursor(9, 1);
      lcd.print(millis()/1000);
      lcd.setCursor(0, 1);
      lcd_key = read_LCD_buttons();
      switch (lcd_key) {
        case btnRIGHT: {
          lcd.print("RIGHT ");
          break;
        }
        case btnLEFT: {
          lcd.print("LEFT   ");
          break;
        }
        case btnUP: {
          lcd.print("UP    ");
          break;
        }
        case btnDOWN: {
          lcd.print("DOWN  ");
          break;
        }
        case btnSELECT: {
          lcd.print("SELECT");
          break;
        }
        case btnNONE: {
          lcd.print("NONE  ");
          break;
        }
      }
    }

If anyone can give me any pointers it would be greatly appreciated.

Liam

  [1]: https://www.amazon.co.uk/gp/product/B01EYW5R5M/

body:
I have found an easy way to do this, i found a tutorial [on instructables][1] that has explained in detail what to do, i then applied this to my LCD keypad shield rather than external buttons on a breadboard.

All you have to do to see what the results are for your particular buttons is to load the sketch below onto your board then open the serial mapper on the arduino ide, simply press the buttons and you should see the results.

<!-- language-all: lang-cpp -->

     /*
      Debounce

      Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
      press), the output pin is toggled from LOW to HIGH or HIGH to LOW.  There's
      a minimum delay between toggles to debounce the circuit (i.e. to ignore
      noise).

      created 28 October 2009
      by Riaan Cornelius

      */

     // constants won't change. They're used here to
     // set pin numbers:
     const int buttonPin = 0;     // the number of the pushbutton pin
     const int ledPin =  53;      // the number of the LED pin for testing

     const int BUTTON1 = 1;
     const int BUTTON2 = 2;
     const int BUTTON3 = 3;
     const int BUTTON4 = 4;
     const int BUTTON5 = 5;

     const int BUTTON1LOW = 970;
     const int BUTTON1HIGH = 1024;
     const int BUTTON2LOW = 850;
     const int BUTTON2HIGH = 950;
     const int BUTTON3LOW = 700;
     const int BUTTON3HIGH = 800;
     const int BUTTON4LOW = 400;
     const int BUTTON4HIGH = 650;
     const int BUTTON5LOW = 250;
     const int BUTTON5HIGH = 350;

     // Variables will change:
     int ledState = HIGH;         // the current state of the output pin
     int buttonState;             // the current reading from the input pin
     int lastButtonState = LOW;   // the previous reading from the input pin

     // the following variables are long's because the time, measured in miliseconds,
     // will quickly become a bigger number than can be stored in an int.
     long lastDebounceTime = 0;  // the last time the output pin was toggled
     long debounceDelay = 50;    // the debounce time; increase if the output flickers

     void setup() {
       pinMode(buttonPin, INPUT);
       pinMode(ledPin, OUTPUT);
       Serial.begin(9600);
     }

     void loop() {
       // read the state of the switch into a local variable:
       int reading = analogRead(buttonPin);
       Serial.println(reading);

       /*
       Not needed while getting the values.

       int tmpButtonState = LOW;             // the current reading from the input pin

       if(reading>BUTTON5LOW && reading<BUTTON5HIGH){
         //Read switch 5
         tmpButtonState = BUTTON5;
       }else if(reading>BUTTON4LOW && reading<BUTTON4HIGH){
         //Read switch 4
         tmpButtonState = BUTTON4;
       }else if(reading>BUTTON3LOW && reading<BUTTON3HIGH){
         //Read switch 3
         tmpButtonState = BUTTON3;
       }else if(reading>BUTTON2LOW && reading<BUTTON2HIGH){
         //Read switch 2
         tmpButtonState = BUTTON2;
       }else if(reading>BUTTON1LOW && reading<BUTTON1HIGH){
         //Read switch 1
         tmpButtonState = BUTTON1;
       }else{
         //No button is pressed;
         tmpButtonState = LOW;
       }

       // check to see if you just pressed the button
       // (i.e. the input went from LOW to a buttonState),  and you've waited
       // long enough since the last press to ignore any noise:

       // If the switch changed, due to noise or pressing:
       if (tmpButtonState != lastButtonState) {
         // reset the debouncing timer
         lastDebounceTime = millis();
       }

       if ((millis() - lastDebounceTime) > debounceDelay) {
         // whatever the reading is at, it's been there for longer
         // than the debounce delay, so take it as the actual current state:
         buttonState = tmpButtonState;
         Serial.println(buttonState);
       }

       // save the reading.  Next time through the loop,
       // it'll be the lastButtonState:
       lastButtonState = tmpButtonState;

       // set the LED using the state of the button for testing:
       switch(buttonState){
         case BUTTON1:
         digitalWrite(ledPin, buttonState>0);
         break;
         case BUTTON2:
         digitalWrite(ledPin, buttonState>0);
         break;
         case BUTTON3:
         digitalWrite(ledPin, buttonState>0);
         break;
         case BUTTON4:
         digitalWrite(ledPin, buttonState>0);
         break;
         case BUTTON5:
         digitalWrite(ledPin, buttonState>0);
         break;
       }
       */
     }

Liam
  [1]: http://www.instructables.com/id/How-to-access-5-buttons-through-1-Arduino-input/


body:
Upload this and it will read the resistance of your buttons on the lcd screen

    /*  /*
    Arduino 2x16 LCD Detect Buttons
    resistance
    */

    #include <LiquidCrystal.h>

    //LCD pin to Arduino
    const int pin_RS = 8;
    const int pin_EN = 9;
    const int pin_d4 = 4;
    const int pin_d5 = 5;
    const int pin_d6 = 6;
    const int pin_d7 = 7;

    const int pin_BL = 10;

    LiquidCrystal lcd( pin_RS,  pin_EN,  pin_d4,  pin_d5,  pin_d6,  pin_d7);

    void setup() {

      lcd.begin(16, 2);

      lcd.setCursor(0,0);

      lcd.print("  Press Any Key ");
      lcd.setCursor(0,1);
      lcd.print("Resistance:");
    }

    void loop() {
      int x;
      x = analogRead (0);
      lcd.setCursor(12,1);
      lcd.print (analogRead (0));
      lcd.print("                ");
      delay (500);
      }


message:
Manually added boards doesn't work in 1.8.5…?

I'm trying to manually add board definitions in a boards.txt file in hardware subfolder of my sketches folder as per instructions here for instance: https://www.arduino.cc/en/Tutorial/ArduinoISP

They however do NOT show up in my board selection.

My sketches location where hardware subfolder should be placed:

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

Board defs:

    ~/D/Arduino ❯❯❯ cat ~/Documents/Arduino/hardware/boards.txt
    ##############################################################

    atmega328bb.name=ATmega328 on a breadboard (8 MHz internal clock)

    atmega328bb.upload.protocol=arduino
    atmega328bb.upload.maximum_size=30720
    atmega328bb.upload.speed=57600

    atmega328bb.bootloader.low_fuses=0xE2
    atmega328bb.bootloader.high_fuses=0xDA
    atmega328bb.bootloader.extended_fuses=0x05

    atmega328bb.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
    atmega328bb.bootloader.unlock_bits=0x3F
    atmega328bb.bootloader.lock_bits=0x0F

    atmega328bb.build.mcu=atmega328p
    atmega328bb.build.f_cpu=8000000L
    atmega328bb.build.core=arduino:arduino
    atmega328bb.build.variant=arduino:standard

    atmega328bb.bootloader.tool=arduino:avrdude
    atmega328bb.upload.tool=arduino:avrdude

BUT nothing show here:

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

I have restarted Arduino IDE.

  [1]: https://i.stack.imgur.com/mYV8B.png
  [2]: https://i.stack.imgur.com/Qd3Af.png

body:
Newer versions of the IDE (after 1.5) have a different folder structure where there is additional subfolders for maintainer and architecture.

    <Arduino sketch folder>/hardware/<custom name>/avr/boards.txt

https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification


message:
Can I power ESP8266 with more than 3.5 V?

I am concerned whether I need to use a voltage divider to power my ESP8266 module. My concerns stem from the warnings that I have heard in multiple tutorials. Everyone seems to regard the ESP8266 as being very sensitive to supply voltage.

Has anyone use the ESP8266 with an supply voltage greater than 3.5 V? What were the effects? Is it even necessary to make a voltage divider?

I am asking because my application has limited real estate.

body:
The [datasheet][1] usually is definitive on the allowable range of voltages.

Look in Section 5.1: Electrical Characteristics.

Working Voltage Value:
----------------------

 - Min: 2.5 V
 - Typical: 3.3 V
 - Max: 3.6 V

If you have to feed in signals that could go higher than 3.3 V in normal operation, you need to either clamp it with Zener diodes, or use a voltage divider.

If you are asking about powering the chip with more than 3.3 V, don't. You can get away with a 3.3 V linear regulator and 2 capacitors so that you are powering it with no more than designed supply voltage.

  [1]: http://www.espressif.com/sites/default/files/documentation/0a-esp8266ex_datasheet_en.pdf


body: The result to apply more voltage to a circuit is that the components will be burn. The same if you apply for a long time the maximum voltage. So the board works at 3.3v, your source maybe fluct between that but you will burn it if you apply 3.6 or more as a regular voltage.


body:
I have 4 pieces of ESP01-S with DHT11 that connect to the WiFi every 30 minutes and send temperature data and then go into DeepSleep.  In addition, an ESP01-S as a motion detector and one as a push button.  These two usually in DeepSleep.
 All are directly connected to a Li-Ion battery as power supply.  This has been running for over a year (except for changing the battery) and so far I haven't had any problems


body:
Usually ESP8266 **modules** have an onboard voltage regulator, USB connector and a pin labeled **5V**. This pin or the USB cable certainly tolerate resp. need a 5V power supply.

The ESP8266 controller itself will not survive 5V, neither at the Vcc nor at the signal pins.

BTW: a voltage divider (two resistors) is ok for signals, but does not help with the power supply.


message:
Wemos: 16x2 display doesn't show anything

I connected a 16x2 LCD display to a Arduino Uno. Then I tested a "Hello, Word" code and it works perfect.
Now I want to do the same with a Wemos D1 Mini but it doesn't work.

Here the Wemos is not connected to USB:

[![16x2 LCD connected to Wemos (front)][1]][1]
[![16x2 LCD connected to Wemos (rear)][2]][2]

This os the "Hello, World" code. I needed to change the name of the pins (maybe this is the problem):

    #include <LiquidCrystal.h>

    const int rs = 8, en = 7, d4 = D5, d5 = D4, d6 = D3, d7 = D2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

    void setup() {
      lcd.begin(16, 2);
      lcd.print("hello, world!");
    }

    void loop() {
      lcd.setCursor(0, 1);
      lcd.print(millis() / 1000);
    }

This is the result (potentiometer works perfect):

[![Display is on but empty][3]][3]

  [1]: https://i.stack.imgur.com/AKoz9.jpg
  [2]: https://i.stack.imgur.com/oReLJ.jpg
  [3]: https://i.stack.imgur.com/HvGDf.jpg

body:
Three possibilities (it's impossible to be more accurate from your description):

1. The display isn't wired to the pins you specified in your sketch
2. The display doesn't accept 3.3V signals when run from 5V
3. The display doesn't function when run from 3.3V

It's certainly not being initialized, which tells me that the instructions for setting it up aren't getting through, or aren't being executed when they do get through.

You can:

1. Use an oscilloscope or logic analyzer to confirm the right pins are in use,
2. Try powering the display from 3.3V if it's currently powered by 5V
3. Try powering the display from 5V if it's currently powered by 3.3V

If it's powered by 5V you may want to consider adding some logic level translation to boost the IO signals from the Wemos to 5V.


body:
You are doing it on wemos d1 mini isnt it ?

Then you dint include its header files,
Did you check the "LiquidCrystal.h" has definitions for wemos pinouts?

Your lcd is fine, n wemos too, its just your configuration is wrong.

Check those and update here.


body:
Although an old question, i just ran into the excat same issue.
The problem is that the pin numeration on the wemos D1 isn't the same as on the arduino.
I've followed the liquid crystal arduino tutorial but changed the numeration of the pins to
```
const int rs = 12, en = 13, d4 = 14, d5 = 4, d6 = 5, d7 = 16;
```
Now, at least for me, the display works as it should


message:
Char* and string conversion from an ESP8266 web server

I have the following Arduino code for configuring a wifi connection through a simple webpage:

I declare `char* ssid;`. Later I read a value from a SPIFFS config file where `q_ssid` is declared as a string and successfully populated from the file:

    strncpy(ssid, q_ssid.c_str(), 10);

In the line above, I am limiting it to exactly 10 as that is the length of my wifi AP name that this connects to. If I change the initial `char*` to `char ssid[10];`, all works well, but SSIDs can have varying names, and if I do not use 10 chars, then the trailing spaces prevent connection in the statement `WiFi.begin(ssid, password);`.

On the web client handler that reads in values from the user, I use this:

    String q_ssid = server.arg("ssid");
    strncpy(ssid, q_ssid.c_str(), 10 );

How can I dynamically assign the size of `char* ssid;` so that it can be used with the correct number of characters for the AP name that the user has stored from the webpage?

Any help is greatly appreciated.

Thanks.

body:
What you need to do is creating a fixed string, this can be done in two ways:

static:

    char ssid[100];

Where 100 is the maximum length ever possible. Note that this will always use up 100 bytes, even if less are used (e.g. your string length is 5.
dynamic:

    char* p_ssid = malloc(100);

This way a pointer is created to a dynamically created string that can hold 100 characters. Disadvantage is that using malloc in a microcontroller can cause empty memory 'holes' when freeing/mallocing a lot.

With either way you can than use a normal strncpy or strcpy (in first case use &ssid to get a pointer to the ssid).
Also don't forget to add 1 to the length because of the trailing \0 to denote the string is ended.
Thus for storing 10 characters, you need an 11 char sized array.


message:
Problem in AT+CIPSEND(CTRL-Z) GPRS GMS A6

I am using GPRS GSM A6 with arduino uno to post data to web server. After sending AT commands to module I get OK response after every command,

    AT+CIPMUX=0

    OK
    AT+CGATT=1

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

    OK
    AT+CIICR

    OK
    AT+CIFSR

    10.65.87.210

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

    CONNECT OK

    OK
    AT+CIPSEND

    > POST http://xxx.xxx.xxx.xxx/Code/ HTTP/1.1
    Host: xxx.xxx.xxx.xxx
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 18

    Data=GPS Data Sent
    AT+CIPCLOSE

    >

To terminate AT+CIPSEND you have to send CTRL-Z. I am sending CTRL-Z using this statement in code,

    Serial.write(0x1A)

But the module doesnot respond to this, and treats the next command (AT+CIPCLOSE) as data.

Please Help... Thanks in Advance!!!

body:
RTFM: https://github.com/espressif/esp8266_at/wiki/CIPSEND

You need to close the input steam with "+++" to return to command mode.


body:
To terminate AT + CIPSEND just apply the next command:

    Serial.write(26);
or

    gsm.write(26);

where gsm is the UART channel of gsm module.


message:
ISR vs state change detection on button

Hi I was wondering if a digitalRead state change detection could be saved in a variable like counter++, just like you can do with an interrupt function.

arent these two operations almost the same?

like have an external circuit with a  reed closed by a magnet, to take the place of a momentary push button,

body:
The 2 techniques described in the question are commonly referred to as "[polling][1]" and "[interrupt][2]".  Either will work.  Polling is suggested for beginner programmers and when time is not important. Such as scanning an array of human controlled buttons. Whereas interrupts are usually reserved for when time is of the essence.  Such as synchronizing a camera's release switch with a strobe flash.

Also, consider polling as a simple to understand, easy to test sequence of events that will always happen in the expected order.  While interrupts can happen at any time and all interruptible code has to be written to tolerate being interrupted.

Often, debouncing is the more difficult problem when combining mechanical switches and microprocessors.  A good fundamental exercise is to [write your own debounce program][3].  However, an [Arduino debounce library][4] is already available.

  [1]: https://en.wikipedia.org/wiki/Polling_(computer_science)
  [2]: https://en.wikipedia.org/wiki/Interrupt
  [3]: https://playground.arduino.cc/Learning/SoftwareDebounce
  [4]: https://playground.arduino.cc/Code/Bounce


body:
The fundamental difference between polling (`digitalRead()`) and interrupts is that of time. Yes, I know we discussed time and interrupts at length in [another of your questions](https://arduino.stackexchange.com/questions/48551/arduino-isr-timing-question), but I'm not talking about recording time here.

With an interrupt you know (pretty much) *when* an input changed. With polling you can only know that it changed *sometime in the past*.  An interrupt occurs at the moment an input changes state (what that change is depends on the type of interrupt). That makes it possible for your program to remember that time (by querying `millis()` for example).

With `digitalRead()` the only way you can know if an input has changed state is if you manually remember what the old state was and compare it, so all you can know is that it's changed since last time you examined the input, and if those times are far apart all you can say is "sometime in the past X milliseconds it changed state".

If your input changes *faster* than that polling time you won't know about it. For instance, if you end up polling every 10 milliseconds, and you have a pulse on your input pin that lasts 4 milliseconds (that's an eternity in microcontroller time) but occurs part way between two polls (say from 3ms to 7ms) you'll never see it.

To put it more formally, to detect a signal of frequency *f* Hz you have to sample the input at minimum *2f* Hz (or a period of *1/(2f)* seconds. This is known as the [Nyquist-Shannon theorem](https://en.wikipedia.org/wiki/Nyquist–Shannon_sampling_theorem) and applies equally to both digital and analog sampling (digital sampling is merely 1-bit analog sampling).

With interrupts, since you're not sampling based on periodic checks, but instead using a hardware trigger to detect an edge (rising, falling, or changing), and assuming you have interrupts enabled at the time an edge arrives on the pin (some code disables interrupts, and interrupts can't trigger while another interrupt routine is running), you instantly know about it regardless of whatever else you are doing.

Interrupts are said to be *asynchronous*, whilst polling is known as *synchronous*.

Which method you should choose depends on many factors: the speed of your signals (pulses from sensors, buttons pressed by humans, etc), what else your program is doing, how critical it is that you detect an input state change, etc.  For slow signals, like a button, polling is perfectly fine. For high speed signals, like a hall-effect sensor or a reed switch triggered by a bicycle wheel mounted magnet, interrupts are more suitable.

For some signals (especially things like revolution counters, frequency counters, etc) where you have a large number of brief pulses coming in over a period of time where all you want to do is count them, there are even better options than interrupts.

The internal timer peripherals of the chip can run in a number of modes that are designed just for this scenario.  You can run a timer with the clock source as an IO pin. That means that on each incoming pulse to that IO pin the timer counts up by one. That happens completely independently of your program. You just read the current count from the timer and reset it to 0 to start counting again at a period to suit you.

Another mode is *Input Compare* mode.  This combines normal interrupts with a timer. The timer runs in the background at a pre-defined rate, and as soon as a specific input changes state (each timer has specific inputs for this) the timer is frozen an interrupt is triggered.  This gives highly accurate time measurement of incoming signals since it's not subject to the time taken to service the interrupt. The timer is frozen immediately and you can query that time when the system is able to service the interrupt.

There is no native support in Arduino for either of those timer modes, though, so you would have to either find an advanced library that configures the timers in that way for you, or read and understand the datasheet and manually configure the timers in the right way.


message:
Burn bootloader to Arduino Uno using ARM-USB-OCD

I have ARM-USB-OCD created by OLIMEX. I am interested in can I use this to burn a bootloader to Arduino Uno. As I know Atmega 328P can be programmed using JTAG protocol which has also ARM-USB-ODC, so if it really can anyone give the circuit or something like this.
Here is my device [(ARM-USB-ODC) manual][1].

  [1]: https://www.olimex.com/Products/ARM/JTAG/_resources/ARM-USB-OCD_and_OCD_H_manual.pdf

body:
*Probably, but likely not easily*

To program an AVR chip you likely want to use the AVR ISP protocol, which is not JTAG, but like JTAG is a synchronous serial protocol with a clock, a data line in each direction, and one additional control pin compared to the several mode/status pins of JTAG.

According to your link, the `ARM-USB-OCD` is based on an FT2232C USB interface chip.

`avrdude` documentation indicates that this is an interface it knows how to use, though it will likely take some study to figure out how.

The final question would be wiring - you'll need to figure out which JTAG-style signal names map to which FTDI functional pins, and how those should best be connected to AVR ISP pins in a way which avrdude can use.  Additionally, you'd have to make sure that any buffering between the FTDI chip and the pins is compatible with your needs, both in terms of data direction and voltage level.

Note that you can easily use any ATmega328-based Arduino as an ISP programmer for a same-voltage target - not really production worthy, but if you just need to move your project along *today* it's a handy option.


message:
Always 255-response in I2C between ATTiny85 (8MHz) and Arduino Uno

I tried to set up an I2C conversation between ab ATTiny85 (8MHz) and an Arduino Uno. However I always get a 255 response from my I2C slave. I am using Arduino 1.8.5.

What am I doing wrong?

**ATTiny85-Slave Code:**

    #include "TinyWireS.h"  // wrapper class for I2C slave
    routines
    #define I2C_SLAVE_ADDR  0x26 // i2c slave address (38)

    byte t=10;

    void setup() {
      TinyWireS.begin(I2C_SLAVE_ADDR);  // init I2C Slave mode
      TinyWireS.onRequest(requestEvent);
    }

    void loop() {
    }

    void requestEvent() {
      TinyWireS.send(t);
    }

**Arduino Uno-Master Code:**

     #include <Wire.h>
     #define I2C_SLAVE_ADDR  0x26 // i2c slave address (38)

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

    void loop() {
      byte num;
      // read 1 byte, from address 0x26
      Wire.requestFrom(I2C_SLAVE_ADDR, 1);
      while(Wire.available()) {
        num = Wire.read();
      }
      Serial.print("num = ");
      Serial.println(num,DEC);
    }

body:
It may seem that the current commit of January 2018 from the TinyWire library is corrupt. Try using an older version from 2017, for example this one: https://github.com/rambo/TinyWire/tr...72a13504bbfc4e

This solves the problem for me as well.

Source: Teensy 3.5 - I2C - ATTiny85-20PU (TinyWireS.OnRequest not triggering!) - [Post #11][1]

  [1]: https://forum.pjrc.com/threads/48887-HELP-Teensy-3-5-I2C-ATTiny85-20PU-(TinyWireS-OnRequest-not-triggering!)?s=875dc9dc416bed5e6f87c304f0044bbd&p=164800&viewfull=1#post164800


message:
List of sketches disappears off the bottom of my screen

v 2:1.0.5

The list of sketches disappears off the bottom of my screen and there is no scroll to reach them. This renders the IDE nearly useless.

Is there a solution?

body:
That issue has been [fixed](https://github.com/arduino/Arduino/commit/49a05121d442a2af1280876887943b1a014f2adf) since the Arduino IDE 1.5.5 [release](https://github.com/arduino/Arduino/releases/tag/1.5.5), 4 years ago.

The version of the Arduino IDE you get from `apt-get install arduino` has not been able to be updated for years due to [licensing issues](https://github.com/arduino/Arduino/pull/2703). The versions available from various package managers may also be modified in ways that introduce new bugs. For this reason you should always install the official Arduino IDE version downloaded from:
https://www.arduino.cc/en/Main/Software


message:
SoftwareSerial + Serial.printlen() not working properly

I want to read a SMS message , find it's length and do some "substring();" operation on received SMS. My last two(2) statements do not work . How can I get correct answers? What are correct codes ?

    #include <SoftwareSerial.h>
    #include <string.h>
    #include <ctype.h>
    SoftwareSerial mySerial(2,3);

    String TelephoneNumberText="";

    void setup()
    {
      pinMode(13, OUTPUT);
      digitalWrite(13, LOW);

      mySerial.begin(9600);
      Serial.begin(9600);
      delay(100);

      mySerial.println("AT+CMGF=1\r");    //Sets the GSM Module in Text Mode
      delay(500);
    }

    void loop()
    {

     while(mySerial.available())
      {
       char s;
       s = mySerial.read();
       TelephoneNumberText = TelephoneNumberText + s;
       }

     Serial.println(TelephoneNumberText);           // this statement works

     Serial.println(TelephoneNumberText.length());  // this statement dose not works

     Serial.println(TelephoneNumberText.substring(0,3));// this statement dose not works

    } // end loop

body:
Are you sure a string like this can be used?

Better anyway to not each time let a dynamic string be created, but use a fixed string e.g.

    char TelephoneNumberText[16];

Set the length of the max number, and change other string functions accordingly.


message:
ESP8266: system_adc_read_fast() always give 1024 as output

I need to use `system_adc_read_fast (uint16 *adc_addr, uint16 adc_num, uint8 adc_clk_div)` to get a sampling rate close to 100ksps. And I am able to achieve that using `adc_clk_div = 32`.

However, when I print out the values stored in `adc_addr`, I always get `1024`. **Why is this?**

I have a NodeMCU v3. I have connected an electret microphone to it. +ve terminal is connected to 3.3V through 10k; GND is connected to GND. +ve terminal is connected to A0 on NodeMCU.

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

<!-- End schematic -->

It works fine when I use `system_adc_read()` (except the sampling rate is then 10ksps which is not desirable).

**Sketch**

<!-- language:lang-cpp -->

    // Expose Espressif SDK functionality - wrapped in ifdef so that it still
    // compiles on other platforms
    #ifdef ESP8266
        extern "C" {
            #include "user_interface.h"
        }
    #endif

    ADC_MODE(ADC_TOUT);

    #define num_samples 512
    uint16_t adc_addr[num_samples]; // point to the address of ADC continuously fast sampling output
    uint16_t adc_num = num_samples; // sampling number of ADC continuously fast sampling, range [1, 65535]
    uint8_t adc_clk_div = 32; // ADC working clock = 80M/adc_clk_div, range [8, 32], the recommended value is 8

    int i = 0;
    unsigned long start = 0;
    unsigned long total = 0;
    unsigned long tim = 0;

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

    void loop() {
        // put your main code here, to run repeatedly:
        #ifdef ESP8266
            // Serial.println(system_get_sdk_version());

            wifi_set_opmode(NULL_MODE);
            system_soft_wdt_stop();
            ets_intr_lock( ); //close interrupt
            noInterrupts();

            start = micros();

            // Serial.println(system_adc_read());
            system_adc_read_fast(adc_addr, adc_num, adc_clk_div);

            unsigned int tot = micros() - start;

            interrupts();
            ets_intr_unlock(); //open interrupt
            system_soft_wdt_restart();

            tim += tot;
            total += num_samples * 1000000.0 / tot;
            i++;

            for (int j=0; j<adc_num;  j++) {
                Serial.println(adc_addr[j]);
            }

            if (i == 100) {
                // Serial.print("Sampling rate: ");
                // Serial.println(total / 100);
                // Serial.print("It lasted: ");
                // Serial.println(tim / 100);

                i = 0;
                tim = 0;
                total = 0;
            }
        #endif
    }

  [1]: https://espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf

body:
I created a test circuit using an AC transformer to produce a 50 cycles / second sine wave signal and tried a number of variations on the *system_adc_read_fast* sample program in the Espressif SDK manual "**2C-ESP8266_Non_OS_SDK_API_Reference__EN**".

The ESP8266 ADC returned realistic values for *adc_clk_div* = 8 and 16, but, as you found, the values returned were always 1024 when I tried 32.

I found that the ADC unit was capable of performing ADC conversions in about 6-10 microseconds...

In a test program to collect data for a 40 millisecond period (ie two complete sine waves - I used a diode to chop off the negative halves) I called the *system_adc_read_fast* function 40 times collecting 116 samples in each call (using "number of samples" = 116).

I collected all the readings in a two-dimensional array before printing any values because the Serial.print function causes long delays between calls to the ADC converter. The "gaps" in the chart represent the changes in the sine wave signal between successive calls to the ADC read function.  [![Chart of ESP8266 ADC values over a 40 millisecond period][1]][1]

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


message:
Reading Ground/Open signal wire combonations to power specific LED's - Can it be done?

This might be a super easy question to answer. I ordered an Arduino Uno anyways for the sole purpose to understand this. Would not mind getting a jump on things before it's here.

I would like to setup the Arduino Uno to be used as a gear indicator for GM transmissions (specifically right now the GM 4l60e). Below is how it currently tells the computer/cluster what gear it's in.

This uses a range switch. Basically it's a combination of 4 wires that are grounded (low) in a specific order, the computer reads it, and displays what gear the transmission is in. There are 4 signal wires - Signal A,B,C, and P. Below is how the range switch signals it:

<!-- language: lang-none -->

    Park    - A=low,  B=open, C=open, P=low
    Reverse - A=low,  B=low,  C=open, P=open
    Neutral - A=open, B=low,  C=open, P=low
    OverDrv - A=open, B=low,  C=low,  P=open
    Drive 3 - A=low,  B=low,  C=low,  P=low
    Drive 2 - A=low,  B=open, C=low,  P=open
    Drive 1 - A=open, B=open, C=low,  P=low

I am wondering what would be the best way to go about this? The Arduino would be powered on by ignition. Display would be an LED (9-12V) output from the Arduino to each gear on a floor mount shifter. Total of 7 LEDs.

Hopefully this is easy to understand what I am trying to do. Thanks!

body:
First of all, Arduino is a 5V device, as such to drive the 9-12V LED you will need to use one or more transistors (depending on the LEDs type, number and connection, in series or in parallel).

Also, powering the Arduino from a 9-12V is not the best option: Arduino Uno has an onboard voltage regulator, but goes up to 9V maximum and, unless you go for the original one or a reputable manufacturer (Arduino is an open source project) I wouldn't go above 6V, because non-reputable manufacturers tend to use lower specs devices, like regulators which can get too hot when powered with high voltage: consider that the regulator will have to dissipate any excess energy into heat.

Said that, and knowing nothing more than what you said about the transmission you are describing, I assume the status `open` stands for _open collector_, meaning that it is not going to draw any current, so the following circuit is what you should use:

<!-- 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/5WPHv.png)

<!-- End schematic -->

The diagram assumes you are using digital pins 5 to 8 of your Arduino in `INPUT` mode and the Arduino GND is at the same voltage level as the transmission: this might be a big assumption, depending on how you power your Arduino (not from a battery pack, to be clear).

When node `A` is in `open` state, the voltage on Arduino pin `5` will be 5V, or HIGH as Arduino reports it. When node `A` is in `low` state then the voltage on Arduino pin `5` will be 0V, or LOW in Arduino lingo.

Resistors from `R1` to `R4` are there to limit current drawn when the gearbox is in state `low`.

UPDATE: I'm assuming the gearbox shares the same ground and operates at 5V,a s the Arduino does. If that's not he case and the gearbox operates at an higher voltage or does not share the same ground, the circuit will not work and you risk damaging the Arduino and/or the gearbox.

You can find a simulation of the above circuit where you can play with the different pins [here][1].

The same occurs for the other pins, so your code will have to scan the 4 pins for their state and update your display accordingly, like:

    #define PIN_A 5
    #define PIN_B 6
    #define PIN_C 7
    #define PIN_P 8

    void setup() {
      pinMode(PIN_A, INPUT);
      pinMode(PIN_B, INPUT);
      pinMode(PIN_C, INPUT);
      pinMode(PIN_P, INPUT);
    }

    #define PARK 0;
    #define DRIVE_1 1;
    #define DRIVE_2 2;
    #define DRIVE_3 3;
    #define OVER_DRIVE 4;
    #define REVERSE 5;
    #define NEUTRAL 99;
    #define UNDEFINED 255;

    unsigned int gear = UNDEFINED;
    void loop() {
        bool A = digitalRead(PIN_A);
        bool B = digitalRead(PIN_B);
        bool C = digitalRead(PIN_C);
        bool P = digitalRead(PIN_P);

        if (!A && B && C && !P) {
          // Park - A=low, B=open, C=open, P=low
          gear = PARK;
        } else if (!A && !B && C && P) {
          // Reverse - A=low, B=low, C=open, P=open
          gear = REVERSE;
        } else if (A && !B && C && !P) {
          // Neutral - A=open, B=low, C=open, P=low
          gear = NEUTRAL;
        } else if (A && !B && !C && P) {
          // OverDrv - A=open, B=low, C=low, P=open
          gear = OVER_DRIVE;
        } else if (!A && !B && !C && !P) {
          // Drive 3 - A=low, B=low, C=low, P=low
          gear = DRIVE_3;
        } else if (!A && B && !C && P) {
          // Drive 2 - A=low, B=open, C=low, P=open
          gear = DRIVE_2;
        } else if (A && B && !C && !P) {
          // Drive 1 - A=open, B=open, C=low, P=low
          gear = DRIVE_1;
        } else {
          // none of the above
          gear = UNDEFINED;
        }
        // update your display here
    }

Please note the above code is NOT the most efficient, but I believe it's easier to read and understand than a version using bitwise operations to identify the possible combinations.

  [1]: http://tinyurl.com/ycxrp4q9


message:
Problem with PCB running an Arduino program to manage a GY-521 MPU6050 accelerometer

I'm working on a project based on MPU6050 GY-521 board connected to my PCB (running with an ATMega328P). The code was developed in Arduino.

The PCB is the second version. The first one works fine with the same accelerometer.

But with the second version I'm facing problems because it doesn't work and I can't understand the cause.

I did the following tests:

 1. Run the code in an Arduino Nano board connected to the GY-521 MPU6050 board. Works fine.
 2. Use other PCB to dismiss possible problem while soldering process. Doesn't work.
 3. Probe with other GY-521 MPU6050 board. Doesn't work.

Finally I decided to cut some parts of the code trying to understand what part of this crash. My final test makes an LED blink while the rest part of the code ran.

    void setup() {
      Serial.begin(115200);
      Wire.begin();
    #if ARDUINO >= 157
      Wire.setClock(400000UL);
    #else
      TWBR = ((F_CPU / 400000UL) - 16) / 2;
    #endif

      i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
      i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
      i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
      i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
      while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once

      //line commented in the last test
      //while (i2cWrite(0x6B, 0x01, true));

      //line commented in the last test
      //while (i2cRead(0x75, i2cData, 1));
      if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
        Serial.print(F("Error reading sensor"));
        while (1);
      }

      delay(100); // Wait for sensor to stabilize

      //line commented in the last test
      //while (i2cRead(0x3B, i2cData, 6));
      accX = (int16_t)((i2cData[0] << 8) | i2cData[1]);
      accY = (int16_t)((i2cData[2] << 8) | i2cData[3]);
      accZ = (int16_t)((i2cData[4] << 8) | i2cData[5]);

      // It is then converted from radians to degrees
    #ifdef RESTRICT_PITCH // Eq. 25 and 26
      double roll  = atan2(accY, accZ) * RAD_TO_DEG;
      double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
    #else // Eq. 28 and 29
      double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
      double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
    #endif

      pinMode(7, OUTPUT);
      pinMode(6, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(4, OUTPUT);

    }

    void loop() {
      /* Update all the values */
      //line commented in the last test
      //while (i2cRead(0x3B, i2cData, 14));
      accX = (int16_t)((i2cData[0] << 8) | i2cData[1]);
      accY = (int16_t)((i2cData[2] << 8) | i2cData[3]);
      accZ = (int16_t)((i2cData[4] << 8) | i2cData[5]);
      tempRaw = (int16_t)((i2cData[6] << 8) | i2cData[7]);
      gyroX = (int16_t)((i2cData[8] << 8) | i2cData[9]);
      gyroY = (int16_t)((i2cData[10] << 8) | i2cData[11]);
      gyroZ = (int16_t)((i2cData[12] << 8) | i2cData[13]);;

      double dt = (double)(micros() - timer) / 1000000; // Calculate delta time
      timer = micros();

      // It is then converted from radians to degrees
    #ifdef RESTRICT_PITCH // Eq. 25 and 26
      double roll  = atan2(accY, accZ) * RAD_TO_DEG;
      double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
    #else // Eq. 28 and 29
      double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
      double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
    #endif

      double gyroXrate = gyroX / 131.0; // Convert to deg/s
      double gyroYrate = gyroY / 131.0; // Convert to deg/s
      double gyroZrate = gyroZ / 131.0; // Convert to deg/s

    #ifdef RESTRICT_PITCH
      // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
      if ((roll < -90 && kalAngleX > 90) || (roll > 90 && kalAngleX < -90)) {
        kalmanX.setAngle(roll);
        compAngleX = roll;
        kalAngleX = roll;
        gyroXangle = roll;
      } else
        kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter

      if (abs(kalAngleX) > 90)
        gyroYrate = -gyroYrate; // Invert rate, so it fits the restriced accelerometer reading
      kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt);
    #else
      // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
      if ((pitch < -90 && kalAngleY > 90) || (pitch > 90 && kalAngleY < -90)) {
        kalmanY.setAngle(pitch);
        compAngleY = pitch;
        kalAngleY = pitch;
        gyroYangle = pitch;
      } else
        kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt); // Calculate the angle using a Kalman filter

      if (abs(kalAngleY) > 90)
        gyroXrate = -gyroXrate; // Invert rate, so it fits the restriced accelerometer reading
      kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter
    #endif

      gyroXangle += gyroXrate * dt; // Calculate gyro angle without any filter
      gyroYangle += gyroYrate * dt;
      //  gyroXangle += kalmanX.getRate() * dt; // Calculate gyro angle using the unbiased rate
      //  gyroYangle += kalmanY.getRate() * dt;

      compAngleX = 0.93 * (compAngleX + gyroXrate * dt) + 0.07 * roll; // Calculate the angle using a Complimentary filter
      compAngleY = 0.93 * (compAngleY + gyroYrate * dt) + 0.07 * pitch;

      // Reset the gyro angle when it has drifted too much
      if (gyroXangle < -180 || gyroXangle > 180)
        gyroXangle = kalAngleX;
      if (gyroYangle < -180 || gyroYangle > 180)
        gyroYangle = kalAngleY;

      // leer el valor analogo que entra
      // filtrarlo
      // determinar si se enciende el led
      sensorValue = analogRead(sensorPin);
      filBattery = myFilterBattery.getFilteredValue(sensorValue);
      if (filBattery < 750) // hacer la prueba con este nuevo valor
      {
        digitalWrite(3, HIGH);
      }
      else
      {
        digitalWrite(3, LOW);
      }
      digitalWrite(5, HIGH);
      delay(500);
      digitalWrite(5, LOW);
      delay(500);
    }

With this code the LED blinks fine, but the commented lines are critical to MPU6050 setup and operation.

If someone can help me to understand what happen to my PCB, I'll be grateful.

Thanks in advance

body:
You have explained that PCB v1 works, and PCB v2 does not work. Therefore, it seems likely the problem is in your PCB design and not in the code.

In your code sample which blinks an LED on PCB v2, but does not communicate with the MPU6050, it seems that you have removed the I²C function calls. Therefore *if* removing those function calls is what allows your code to run, and *if* the "working" code used on PCB v1 does not run successfully on PCB v2, then it's logical that you have somehow broken your I²C bus on PCB v2.

I suggest you start by comparing your PCB v1 and v2 designs *carefully*, focussing especially on the I²C bus and the connections to the MPU6050.


message:
using pull-up resistors with A-star 32u4 on putput pins?

Okay probably not the first time this has been asked, but really, I search all over the internet and was not able to find this.
I want to drive LEDs on the output on some of my pins. Is it required to put a pull-up resistor or current limiter resistor on these? or can I just plug the LED into the output, and the other end of the LED to +vcc? Are there example schematics someplace that will show this?
thoughts? suggestions?
thanks.

body:
You always should use a resistor.

Simply the following schematic should be used.

The resistor value can be calculated as follows:

(V + Vfwd = I * R) => R = (V + Vfwd) / I

V is 5.0 V
Vfwd is the forward voltage of the LED (this differs per type/color/brand)
I is normally max. around 20 mA (but can be briefly more if the LED does not continuously lights)

Normally R is between 100 and 500 R, but can differ if you want to add multiple LEDs.

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

<!-- End schematic -->


message:
ESP8266 on WiFi without password, possible?

Is it possible to connect to an SSID that does not require a password?
My project using ESP8266-01 modules will sometimes be used in non-password protected guest networks.

body:
Yes, it works! You can use:

    WiFi.begin(ssid, NULL)

or even leave the passphrase empty, because it is optional:

    WiFi.begin(ssid)

Reference: https://www.arduino.cc/en/Reference/WiFiBegin


message:
Errors trying to set fuses on bare Atmega328p

I have an Atmega328p on a board that I want to program using an Arduino programmer. I've got the programmer working to program other Arduino's over ICSP header, but when trying to use the same settings to avrdude to read/set the fuses of the bare MCU with oscillator I get the following:

    ❯❯❯ avrdude -v -p atmega328p -b 19200 -P /dev/cu.wchusbserial213240 -c stk500v1                                                                                ⏎ master

    avrdude: Version 6.3, compiled on Sep 18 2017 at 20:31:51
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "/usr/local/Cellar/avrdude/6.3/etc/avrdude.conf"
             User configuration file is "/Users/viktor/.avrduderc"
             User configuration file does not exist or is not a regular file, skipping

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

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

             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.08s

    avrdude: Device signature = 0x000000 (retrying)

    Reading | ################################################## | 100% 0.08s

    avrdude: Device signature = 0x000000 (retrying)

    Reading | ################################################## | 100% 0.08s

    avrdude: Device signature = 0x000000
    avrdude: Yikes!  Invalid device signature.
             Double check connections and try again, or use -F to override
             this check.

    avrdude done.  Thank you.

I've checked the soldering as good as I can and it seems to be right. I have a 10K pullup on reset, an oscillator with caps. I'm suspecting I might have fried the MCU when soldering or something - is there anything simple I can check?

* All PWR connections check out
* I've checked the oscillator with a scope and it isn't oscillating, but I'm thinking that is normal since it's a bare chip that I'm trying to set the fuses to use the external crystal? The oscillator is at least connected correctly.

body: It turned out it was a bit of bad soldering on the MCU. This same msg you'll get if just leaving the ICSP floating.


message:
Arduino Voltage Divider

So am doing a project which involves the reading of voltage and current generated by Solar Panel. Now I learnt that Arduino cant Read Voltage directly above 5V. To read above that you need to add a voltage divider circuit in between. But that's the great solution for a solar panel around 20W.
Now what if i want to read voltages of n number of solar panels which are in a farm in which each solar panel generated around 300-400 W .
1)Will adding voltage divider help?
2) What is the limit of Arduino of Voltage Divider?
3) What registers i would have to use for such big voltage divider?

body:
> 1) Will adding voltage divider help?

Yes.

> 2) What is the limit of Arduino of Voltage Divider?

The Arduino has no relevance here. You can build voltage dividers to convert thousands or millions of volts down to 5V if you need to.

> 3) What registers i would have to use for such big voltage divider?

I guess you mean "resistors" here, not "registers"...

Resistors that give no more than 5V out at the peak voltage of the solar panels, and have a high enough voltage tolerance for the maximum voltage across any one resistor.


body:
> 1)Will adding voltage divider help?

You will need _n_ voltage dividers, one for each solar panel.

> 2) What is the limit of Arduino of Voltage Divider?

There is a limit on the equivalent Thévenin resistance of the voltage
source connected to the Arduino analog inputs. It should be no larger
that 10 kΩ, otherwise you risk cross-talk between the channels.

If the solar panels have a low output resistance, then the equivalent
Thévenin resistance is the resistance resulting from setting the two
resistors of the divider _in parallel_. Setting the smallest resistance
to 10 kΩ will ensure you meet the condition while at the same time
keeping the consumed current quite low.

There is also a limit on the number of solar panels that you can
independently monitor: 16, which is the number of analog inputs on the
Mega.

> [...] each solar panel generate[s] around 300-400 W

The power generated is irrelevant: only the voltage is a concern. Your
dividers must output no more than 5 V.


message:
#include<ESP8266WiFi.h> showing error message

i was trying to send some data to a webpage via esp8266wifi module connected to arduino uno. My sketch contains a header file <ESP8266WiFi.h>.After searching online I could get the library Arduino-master.zip from github. I extracted the files and put it in inside the directory arduino->hardware->arduino->avr->libraries.but even then it was showing me the error message like this:

 fatal error: ESP8266WiFi.h: No such file or directory

 #include <ESP8266WiFi.h>

                         ^

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Uno.

How can I remove this error. please refrain from technical words as i am new to this language. Thank you.

**EDIT**: After adding esp8266WiFi.h in the library i got out from that error message .But it showed me a new one

C:\Program Files (x86)\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFiType.h:26:19: fatal error: queue.h: No such file or directory

 #include <queue.h>

                   ^

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Uno.

I dont know how to come out of this error. some websites give a solution but it didn't worked for me.

body: That library is part of the ESP8266 core. It's not for the Arduino, but for programming the ESP8266 as a standalone unit without an Arduino connected to it.


body:
ESP8266WiFi part of the project Arduino Core here: https://github.com/esp8266/Arduino Arduino Core provides support for the ESP8266 to be used with Arduino IDE through the boards manager facility. So its libraries are for the ESP8266 not the Uno.

If you are interested in communicating with the ESP8266 over serial using its AT+ command firmware then you just send them as strings over serial.

    Serial1.println("AT+GMR");
    while(Serial1.available() == 0) {
      delay(1);
    }
    while(Serial1.available() > 0) {
      Serial.write(Serial1.read());
    }


message:
Is there any way for one Arduino board to communicate with multiple sensors?

Say a home IoT application to monitor water levels in basement at 4 or 5 different places and transmit that data back to a single Arduino board to be then interfaced with a GUI to do home monitoring?

body:
Yes you can ... however, how you transmit the sensor data? If wireless, you need some RF communication, and possibly a microcontroller like Arduino (or ESP) within each sensor module.

With nRF24L01 (2.4GHz) you can use 6 'slaves' (sensor modules in your case) to send data to the master (monitoring module).

Do things one by one:

- First make one sensor module
- Than make the master to receive data
- Than make the GUI screen
- Than make the other five sensor modules


body: Yes this could be done using SPI (with separate slave select wires), i2c or daisy chained UART providing a wired solution.


message:
How does one get the correct serial port?

I don't have a correct serial port from the resource I'm working from - Getting Started with Arduino by Massimo Banzi and Micheal Shiloh. I'm using the Arduino Uno. I'm a complete noob to Arduino. In this image below, from the resource I'm working from, it specifies to use either of the ports: `/dev/cu.usbmodemfa141` or `/dev/tty.usbmodem`.

*Getting started with Arduino by Massimo Banzi and Michael Shiloh* - Figure 3-2 shows a list of available serial ports.

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

I only have two available: `/dev/cu.SSDC` and `/dev/cu.Bluetooth-Incoming-port`.

How do I get the 'correct' serial port? Correct being: `/dev/cu.usbmodemfa141` or `/dev/tty.usbmodem`.

Here's some possibly useful information:

I'm using Mac OS - which I'm new to - Sierra version 10.13.2.

I only have two ports on the computer a USB type - C and a headphone jack. So I have an 'adapter' that allows me to 'daisy chain' the USB - B and USB - A for the Arduino cable into the port of my computer. If any additional information is required, feel free to ask for it and I'll try and get back to you ASAP. Thanks.

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

body:
I had the same problem and had even fewer options under my Tools > Port menu. Looked at the user forums but most answers did not work for me. After watching a [YouTube video][1], I fixed the problem by following its suggestion of installing the CH34X driver. There are some other suggested drivers if you search for some other related StackOverflow and StackExchange posts, but I did not test them (once the Mac-Arduino communication worked, I did not want to spend more time on this) and nor can I explain why this solution works.

I wrote [a short article on this][2] for myself. If you are interested, please take a quick look.

Best luck! :)

  [1]: https://www.youtube.com/watch?v=wyocdvAKo64&list=PLDSK_xvHetGobwkRPhNYEDzo7bdKa17lL
  [2]: https://medium.com/@shandou/a-chronicle-of-my-getting-started-with-arduino-journey-b9a2f7f20712


body: Sorry guys I solved it. It was really simple I just needed to plug the device in and it then detected the device and port name.


message:
Is output pin set to LOW grounded

If I do following:

    pinMode(MYPIN, OUTPUT)
    digitalWrite(MYPIN, LOW)

What will happen? Will this effectively ground _MYPIN_ or output some low voltage?

body:
This will effectively connect the pin to ground. Note that the connection is
made by a transistor that has a finite resistance. This output resistance is
not really specified, but from the curves on the “typical characteristics”
section of the datasheet you can infer that the _typical_ value is about
26 Ω.

The only hard specification states that the `OUTPUT` `LOW` voltage
should be no larger than 0.9 V, as long as the pin is not sinking
more than 20 mA. C.f. the table “DC characteristics” of the
[ATmega2560
datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf#page=355).