body:
I have a 5x8 Neopixel shield for my Arduino. I want to display text on it, while it is in "landscape mode", i.e. a only 5pt high text. The default font that is used by the `print`command is 8pt high. How can I load a font with 5pt height into my code?

I understand that the Neopixel library depends on `Adafruit GFX`, which allows for different fonts. But changing the font according to the Adafruit tutorial on GFX to one of the supplied fonts does not return any readable text (only a moving line of dots). I found this [font converter][1] and used it to produce a 5pt font, but again only a moving dot appears.

This is my code (basically the Neomatrix example with modified orientation of the matrix):

    // Adafruit_NeoMatrix example for single NeoPixel Shield.
    // Scrolls 'Howdy' across the matrix in a portrait (vertical) orientation.

    #include <Adafruit_GFX.h>
    #include <Adafruit_NeoMatrix.h>
    #include <Adafruit_NeoPixel.h>
    #include <Fonts/Dialog_plain_5.h>
    #ifndef PSTR
     #define PSTR // Make Arduino Due happy
    #endif

    #define PIN 6

    Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 5, PIN,
      NEO_MATRIX_TOP     + NEO_MATRIX_LEFT+
      NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
      NEO_GRBW  + NEO_KHZ800);

    const uint16_t colors[] = {
      matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255) };

    void setup() {
      matrix.setFont(&Dialog_plain_5);
      matrix.begin();
      matrix.setTextWrap(false);
      matrix.setBrightness(30);
      matrix.setTextColor(colors[0]);
    }

    int x    = matrix.width();
    int pass = 0;

    void loop() {
      matrix.fillScreen(0);
      matrix.setCursor(x, 0);
      matrix.print(F("Howdy"));
      if(--x < -36) {
        x = matrix.width();
        if(++pass >= 3) pass = 0;
        matrix.setTextColor(colors[pass]);
      }
      matrix.show();
      delay(100);
    }

and this is the content of the font file:

    // Created by http://oleddisplay.squix.ch/ Consider a donation
    // In case of problems make sure that you are using the font file with the correct version!
    const uint8_t Dialog_plain_5Bitmaps[] PROGMEM = {

     // Bitmap Data:
     0x00, // ' '
     0xF0, // '!'
     0xC0, // '"'
     0x07,0xF2, // '#'
     0x79,0xF4, // '$'
     0xD1,0x10,0xB0, // '%'
     0x88,0xCA, // '&'
     0x80, // '''
     0x2A,0x00, // '('
     0x15,0x00, // ')'
     0x08,0x00, // '*'
     0x01,0x1C,0x40, // '+'
     0x00, // ','
     0xC0, // '-'
     0x00, // '.'
     0x6A,0x00, // '/'
     0xD6,0xE0, // '0'
     0xC9,0x20, // '1'
     0x62,0x48, // '2'
     0xE8,0xE0, // '3'
     0x26,0x62, // '4'
     0x08,0x90, // '5'
     0x7A,0xE0, // '6'
     0x25,0x20, // '7'
     0xEA,0xE0, // '8'
     0xD5,0xE0, // '9'
     0x00, // ':'
     0x00, // ';'
     0x02,0xC6, // '<'
     0x77, // '='
     0x06,0x16, // '>'
     0xD0, // '?'
     0x27,0xB7,0x66,0x00, // '@'
     0x4A,0x68, // 'A'
     0xFA,0xD0, // 'B'
     0x68,0x86, // 'C'
     0xE9,0x9A, // 'D'
     0xDA,0x40, // 'E'
     0x9A,0x40, // 'F'
     0x78,0xB5, // 'G'
     0xBE,0xD0, // 'H'
     0xF0, // 'I'
     0x55,0x40, // 'J'
     0xAC,0xCA, // 'K'
     0x92,0x40, // 'L'
     0x9F,0xF9, // 'M'
     0xBF,0xD0, // 'N'
     0x69,0x96, // 'O'
     0xF7,0x40, // 'P'
     0x69,0x96,0x00, // 'Q'
     0xEA,0xCA, // 'R'
     0x91,0x60, // 'S'
     0x21,0x08,0x40, // 'T'
     0xB6,0xE0, // 'U'
     0xAA,0xA4, // 'V'
     0xAF,0xBC,0xA0, // 'W'
     0xA4,0x4A, // 'X'
     0x53,0x08,0x40, // 'Y'
     0x64,0x88, // 'Z'
     0xAA,0x80, // '['
     0xAA,0x40, // '\'
     0x55,0x40, // ']'
     0x61, // '^'
     0x70, // '_'
     0x00, // '`'
     0xDE,0x80, // 'a'
     0x9A,0xE0, // 'b'
     0x92,0x00, // 'c'
     0x3E,0xD0, // 'd'
     0xDE,0x00, // 'e'
     0x49,0x20, // 'f'
     0xF6,0xA0, // 'g'
     0x9E,0xD0, // 'h'
     0xF0, // 'i'
     0x55,0x40, // 'j'
     0x9A,0x60, // 'k'
     0xF0, // 'l'
     0xFD,0x6A, // 'm'
     0xF6,0x80, // 'n'
     0xD7,0x00, // 'o'
     0xD7,0x40, // 'p'
     0xF6,0xB0, // 'q'
     0x2A, // 'r'
     0x4C,0x80, // 's'
     0x49,0x20, // 't'
     0x16,0xD0, // 'u'
     0xB9,0x00, // 'v'
     0xD7,0x60, // 'w'
     0xCB,0x00, // 'x'
     0xB9,0x40, // 'y'
     0x68, // 'z'
     0x4A,0x24, // '{'
     0xF8, // '|'
     0x48,0xA4 // '}'
    };
    const GFXglyph Dialog_plain_5Glyphs[] PROGMEM = {
    // bitmapOffset, width, height, xAdvance, xOffset, yOffset
       {     0,   1,   1,   3,    0,    0 }, // ' '
       {     1,   1,   4,   3,    0,   -4 }, // '!'
       {     2,   2,   2,   3,    0,   -4 }, // '"'
       {     3,   4,   4,   5,    0,   -4 }, // '#'
       {     5,   3,   5,   4,    0,   -4 }, // '$'
       {     7,   5,   4,   6,    0,   -4 }, // '%'
       {    10,   4,   4,   5,    0,   -4 }, // '&'
       {    12,   1,   2,   2,    0,   -4 }, // '''
       {    13,   2,   5,   3,    0,   -4 }, // '('
       {    15,   2,   5,   3,    0,   -4 }, // ')'
       {    17,   3,   3,   4,    0,   -4 }, // '*'
       {    19,   5,   4,   6,    0,   -4 }, // '+'
       {    22,   2,   3,   3,    0,   -2 }, // ','
       {    23,   2,   1,   3,    0,   -2 }, // '-'
       {    24,   2,   1,   3,    0,   -1 }, // '.'
       {    25,   2,   5,   3,    0,   -4 }, // '/'
       {    27,   3,   4,   4,    0,   -4 }, // '0'
       {    29,   3,   4,   4,    0,   -4 }, // '1'
       {    31,   4,   4,   4,    0,   -4 }, // '2'
       {    33,   3,   4,   4,    0,   -4 }, // '3'
       {    35,   4,   4,   5,    0,   -4 }, // '4'
       {    37,   3,   4,   4,    0,   -4 }, // '5'
       {    39,   3,   4,   4,    0,   -4 }, // '6'
       {    41,   3,   4,   4,    0,   -4 }, // '7'
       {    43,   3,   4,   4,    0,   -4 }, // '8'
       {    45,   3,   4,   4,    0,   -4 }, // '9'
       {    47,   2,   3,   3,    0,   -3 }, // ':'
       {    48,   2,   4,   3,    0,   -3 }, // ';'
       {    49,   4,   4,   5,    1,   -4 }, // '<'
       {    51,   4,   2,   5,    0,   -3 }, // '='
       {    52,   4,   4,   5,    0,   -4 }, // '>'
       {    54,   2,   4,   4,    0,   -4 }, // '?'
       {    55,   5,   5,   6,    0,   -4 }, // '@'
       {    59,   4,   4,   4,    0,   -4 }, // 'A'
       {    61,   3,   4,   4,    0,   -4 }, // 'B'
       {    63,   4,   4,   4,    0,   -4 }, // 'C'
       {    65,   4,   4,   5,    0,   -4 }, // 'D'
       {    67,   3,   4,   4,    0,   -4 }, // 'E'
       {    69,   3,   4,   4,    0,   -4 }, // 'F'
       {    71,   4,   4,   5,    0,   -4 }, // 'G'
       {    73,   3,   4,   4,    0,   -4 }, // 'H'
       {    75,   1,   4,   2,    0,   -4 }, // 'I'
       {    76,   2,   5,   2,   -1,   -4 }, // 'J'
       {    78,   4,   4,   4,    0,   -4 }, // 'K'
       {    80,   3,   4,   4,    0,   -4 }, // 'L'
       {    82,   4,   4,   5,    0,   -4 }, // 'M'
       {    84,   3,   4,   4,    0,   -4 }, // 'N'
       {    86,   4,   4,   5,    0,   -4 }, // 'O'
       {    88,   3,   4,   4,    0,   -4 }, // 'P'
       {    90,   4,   5,   5,    0,   -4 }, // 'Q'
       {    93,   4,   4,   4,    0,   -4 }, // 'R'
       {    95,   3,   4,   5,    1,   -4 }, // 'S'
       {    97,   5,   4,   4,   -1,   -4 }, // 'T'
       {   100,   3,   4,   4,    0,   -4 }, // 'U'
       {   102,   4,   4,   4,    0,   -4 }, // 'V'
       {   104,   5,   4,   6,    0,   -4 }, // 'W'
       {   107,   4,   4,   4,    0,   -4 }, // 'X'
       {   109,   5,   4,   4,   -1,   -4 }, // 'Y'
       {   112,   4,   4,   6,    1,   -4 }, // 'Z'
       {   114,   2,   5,   3,    0,   -4 }, // '['
       {   116,   2,   5,   3,    0,   -4 }, // '\'
       {   118,   2,   5,   3,    0,   -4 }, // ']'
       {   120,   4,   2,   5,    0,   -4 }, // '^'
       {   121,   4,   1,   4,   -1,    1 }, // '_'
       {   122,   2,   1,   4,    0,   -4 }, // '`'
       {   123,   3,   3,   5,    1,   -3 }, // 'a'
       {   125,   3,   4,   4,    0,   -4 }, // 'b'
       {   127,   3,   3,   4,    0,   -3 }, // 'c'
       {   129,   3,   4,   4,    0,   -4 }, // 'd'
       {   131,   3,   3,   5,    1,   -3 }, // 'e'
       {   133,   3,   4,   3,   -1,   -4 }, // 'f'
       {   135,   3,   4,   4,    0,   -3 }, // 'g'
       {   137,   3,   4,   4,    0,   -4 }, // 'h'
       {   139,   1,   4,   2,    0,   -4 }, // 'i'
       {   140,   2,   5,   2,   -1,   -4 }, // 'j'
       {   142,   3,   4,   4,    0,   -4 }, // 'k'
       {   144,   1,   4,   2,    0,   -4 }, // 'l'
       {   145,   5,   3,   6,    0,   -3 }, // 'm'
       {   147,   3,   3,   4,    0,   -3 }, // 'n'
       {   149,   3,   3,   4,    0,   -3 }, // 'o'
       {   151,   3,   4,   4,    0,   -3 }, // 'p'
       {   153,   3,   4,   4,    0,   -3 }, // 'q'
       {   155,   2,   4,   3,    0,   -4 }, // 'r'
       {   156,   3,   3,   5,    0,   -3 }, // 's'
       {   158,   3,   4,   3,   -1,   -4 }, // 't'
       {   160,   3,   4,   4,    0,   -4 }, // 'u'
       {   162,   3,   3,   4,    0,   -3 }, // 'v'
       {   164,   4,   3,   5,    0,   -3 }, // 'w'
       {   166,   3,   3,   4,    0,   -3 }, // 'x'
       {   168,   3,   4,   4,    0,   -3 }, // 'y'
       {   170,   2,   3,   5,    1,   -3 }, // 'z'
       {   171,   3,   5,   4,    0,   -4 }, // '{'
       {   173,   1,   6,   2,    0,   -4 }, // '|'
       {   174,   3,   5,   4,    0,   -4 } // '}'
    };
    const GFXfont Dialog_plain_5 PROGMEM = {
    (uint8_t  *)Dialog_plain_5Bitmaps,(GFXglyph *)Dialog_plain_5Glyphs,0x20, 0x7E, 7};

[1]: http://oleddisplay.squix.ch/#/home

title: 5pt font for Neopixel shield

Answers: 1

body:
I was having the same problem until I read the library source code. Later I found the documentation reference.

The classic font cursor position is defined as the top-left corner of the character cell. For GFX and custom fonts it is the 'y' position is relative to the baseline of the character cell.

My display is 5 by 5. The TomThumb font is 3 by 5. Instead of `matrix.setCursor(x, 0);` I needed to use `matrix.setCursor(x, 5);` so the 'y' coordinate corresponds with the bottom of the pixel matrix, not the top.

It's described in [Adafruit's docs](https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts).


body:
I am new to Arduino and I was trying to figure out how to use an interrupt. When I ran this it would read my magnet but the interrupt would never be called and I couldn't figure out if anyone can help me that would be great.

Thanks.

Here is the code

    #include <PinChangeInterrupt.h>

    //#define INTERRUPT_PIN 12
    #include <Math.h>

    #define RADIUS 3
    const int hallPin = 7; // the number of the hall effect sensor pin
    const int ledPin =  13; // the number of the LED pin
    // variables will change:
    int hallState = 0; // variable for reading the hall sensor status
    double inital_val = 0.0;
    double distance = inital_val;

    void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      pinMode(hallPin, INPUT);
      //attachInterrupt(hallPin, calc_distance, HIGH);
      // initialize the hall effect sensor pin as an input:
      attachInterrupt(digitalPinToInterrupt(hallPin), calc_distance , HIGH);
      Serial.begin(9600);
    }

    void loop() {
      //read the state of the hall effect sensor:
      hallState = digitalRead(hallPin);
      if (hallState == LOW) {
        // turn LED on:
        Serial.print("Main Loop: HallState LOW\n");
        digitalWrite(ledPin, HIGH);
        Serial.print(distance, 2);
        Serial.print("\n");
      } else {
        Serial.print("Main Loop: HallState HIGH\n");
        // turn LED off:
        digitalWrite(ledPin, LOW);
      }
    }

    void calc_distance() {
      Serial.print("INTERRUPT! \n");
      if (digitalRead(hallPin) == HIGH) {
        Serial.print("YES!\n");
        distance += PI * 2 * RADIUS;
      } else {
        Serial.print("NO!\n");
      }
    }

title: Arduino interrupt not called using PinChangeInterrupt

Answers: 1

body:
The attachInterrupt function is only for normal interrupts. Read the reference: [attachInterrupt][1]

When you need the Pin Change Interrupts, there is a library for that: [EnableInterrupt][2]

Try to keep the interrupt routine as short as possible. Do not use the Serial functions in calc_distance because the Serial functions themself use also interrupts.

The Arduino Mega does not have 'double' floating point variables, the compiler changes it into 32-bit 'float' variables. You are reading the interrupt pin for a test ? I don't understand why you do that. Please make "distance" a volatile variable. In the loop function, the interrupts should be turned off when reading "distance". Because "distance" is a 4 bytes 'float' variable and the Arduino Mega is a 8-bits microcontroller. An interrupt could occur when the "distance" is only read for a part from memory.

  [1]: https://www.arduino.cc/en/Reference/attachInterrupt
  [2]: https://github.com/GreyGnome/EnableInterrupt


body:
I'm trying to use [Uri Shaked Slackbot code][1] using an [Adafruit Feather Huzzah ESP8266 WiFi][2].

I have created the Slackbot integration and copied the API key. The code connects to the WiFi and does the time configuration but then hangs when connecting to slack with the error message in the serial monitor.

> ssl-need_bytes=16432 > 6859

    /**
       Arduino Real-Time Slack Bot
       Copyright (C) 2016, Uri Shaked.
       Licensed under the MIT License
    */

    #include <Arduino.h>
    #include <ESP8266WiFi.h>
    #include <ESP8266WiFiMulti.h>
    #include <ESP8266HTTPClient.h>
    #include <WebSocketsClient.h>
    #include <ArduinoJson.h>
    #include <Adafruit_NeoPixel.h>

    #define SLACK_SSL_FINGERPRINT "AC 95 5A 58 B8 4E 0B CD B3 97 D2 88 68 F5 CA C1 0A 81 E3 6E" // If Slack changes their SSL fingerprint, you would need to update this
    #define SLACK_BOT_TOKEN "https://slack.com/api/rtm.start?token=[MY TOKEN]" // Get token by creating new bot integration at https://my.slack.com/services/new/bot
    #define WIFI_SSID       "[My WIFI]"
    #define WIFI_PASSWORD   "[WiFi Password]"

    #define LEDS_PIN        2
    #define LEDS_NUMPIXELS  8
    #define WORD_SEPERATORS "., \"'()[]<>;:-+&?!\n\t"

    ESP8266WiFiMulti WiFiMulti;
    WebSocketsClient webSocket;

    Adafruit_NeoPixel pixels(LEDS_NUMPIXELS, LEDS_PIN, NEO_GRB + NEO_KHZ800);

    long nextCmdId = 1;
    bool connected = false;

    /**
      Sends a ping message to Slack. Call this function immediately after establishing
      the WebSocket connection, and then every 5 seconds to keep the connection alive.
    */
    void sendPing() {
      DynamicJsonBuffer jsonBuffer;
      JsonObject& root = jsonBuffer.createObject();
      root["type"] = "ping";
      root["id"] = nextCmdId++;
      String json;
      root.printTo(json);
      webSocket.sendTXT(json);
    }

    /**
      Input a value 0 to 255 to get a color value.
      The colors are a transition r - g - b - back to r.
    */
    uint32_t wheel(byte wheelPos) {
      wheelPos = 255 - wheelPos;
      if (wheelPos < 85) {
        return pixels.Color(255 - wheelPos * 3, 0, wheelPos * 3);
      }
      if (wheelPos < 170) {
        wheelPos -= 85;
        return pixels.Color(0, wheelPos * 3, 255 - wheelPos * 3);
      }
      wheelPos -= 170;
      return pixels.Color(wheelPos * 3, 255 - wheelPos * 3, 0);
    }

    /**
      Animate a NeoPixel ring color change.
      Setting `zebra` to true skips every other led.
    */
    void drawColor(uint32_t color, bool zebra) {
      int step = zebra ? 2 : 1;
      for (int i = 0; i < LEDS_NUMPIXELS; i += step) {
        pixels.setPixelColor(i, color);
        pixels.show();
        delay(30 * step);
      }
    }

    /**
      Draws a rainbow :-)
    */
    void drawRainbow(bool zebra) {
      int step = zebra ? 2 : 1;
      for (int i = 0; i < LEDS_NUMPIXELS; i += step) {
        pixels.setPixelColor(i, wheel(i * 256 / LEDS_NUMPIXELS));
        pixels.show();
        delay(30 * step);
      }
    }

    /**
      Looks for color names in the incoming slack messages and
      animates the ring accordingly. You can include several
      colors in a single message, e.g. `red blue zebra black yellow rainbow`
    */
    void processSlackMessage(char *payload) {
      char *nextWord = NULL;
      bool zebra = false;
      for (nextWord = strtok(payload, WORD_SEPERATORS); nextWord; nextWord = strtok(NULL, WORD_SEPERATORS)) {
        if (strcasecmp(nextWord, "zebra") == 0) {
          zebra = true;
        }
        if (strcasecmp(nextWord, "red") == 0) {
          drawColor(pixels.Color(255, 0, 0), zebra);
        }
        if (strcasecmp(nextWord, "green") == 0) {
          drawColor(pixels.Color(0, 255, 0), zebra);
        }
        if (strcasecmp(nextWord, "blue") == 0) {
          drawColor(pixels.Color(0, 0, 255), zebra);
        }
        if (strcasecmp(nextWord, "yellow") == 0) {
          drawColor(pixels.Color(255, 160, 0), zebra);
        }
        if (strcasecmp(nextWord, "white") == 0) {
          drawColor(pixels.Color(255, 255, 255), zebra);
        }
        if (strcasecmp(nextWord, "purple") == 0) {
          drawColor(pixels.Color(128, 0, 128), zebra);
        }
        if (strcasecmp(nextWord, "pink") == 0) {
          drawColor(pixels.Color(255, 0, 96), zebra);
        }
        if (strcasecmp(nextWord, "orange") == 0) {
          drawColor(pixels.Color(255, 64, 0), zebra);
        }
        if (strcasecmp(nextWord, "black") == 0) {
          drawColor(pixels.Color(0, 0, 0), zebra);
        }
        if (strcasecmp(nextWord, "rainbow") == 0) {
          drawRainbow(zebra);
        }
        if (nextWord[0] == '#') {
          int color = strtol(&nextWord[1], NULL, 16);
          Serial.println("Color");
          Serial.print(color);
          if (color) {
            drawColor(color, zebra);
          }
        }
      }
    }

    /**
      Called on each web socket event. Handles disconnection, and also
      incoming messages from slack.
    */
    void webSocketEvent(WStype_t type, uint8_t *payload, size_t len) {
      switch (type) {
        case WStype_DISCONNECTED:
          Serial.printf("[WebSocket] Disconnected :-( \n");
          connected = false;
          break;

        case WStype_CONNECTED:
          Serial.printf("[WebSocket] Connected to: %s\n", payload);
          sendPing();
          break;

        case WStype_TEXT:
          Serial.printf("[WebSocket] Message: %s\n", payload);
          processSlackMessage((char*)payload);
          break;
      }
    }

    /**
      Establishes a bot connection to Slack:
      1. Performs a REST call to get the WebSocket URL
      2. Conencts the WebSocket
      Returns true if the connection was established successfully.
    */
    bool connectToSlack() {
      // Step 1: Find WebSocket address via RTM API (https://api.slack.com/methods/rtm.start)
      HTTPClient http;

      Serial.printf("Connecting to\n");
      Serial.printf(SLACK_BOT_TOKEN);
      Serial.printf("\n");

      http.begin(SLACK_BOT_TOKEN, SLACK_SSL_FINGERPRINT);
      int httpCode = http.GET();

      if (httpCode != HTTP_CODE_OK) {
        Serial.printf("HTTP GET failed with code %d\n", httpCode);
        return false;
      }

      pixels.setPixelColor(3, pixels.Color(0, 2, 0));
      pixels.show();

      WiFiClient *client = http.getStreamPtr();
      client->find("wss:\\/\\/");
      String host = client->readStringUntil('\\');
      String path = client->readStringUntil('"');
      path.replace("\\/", "/");

      // Step 2: Open WebSocket connection and register event handler
      Serial.println("WebSocket Host=" + host + " Path=" + path);
      webSocket.beginSSL(host, 443, path, "", "");
      webSocket.onEvent(webSocketEvent);

      pixels.setPixelColor(4, pixels.Color(0, 2, 0));
      pixels.show();

      return true;
    }

    void setup() {
      Serial.begin(115200);
      Serial.setDebugOutput(true);

      pixels.begin();
      drawColor(pixels.Color(2, 0, 0), false);

      pixels.setPixelColor(0, pixels.Color(0, 2, 0));
      pixels.show();

      WiFiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
      while (WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
      }

      pixels.setPixelColor(1, pixels.Color(0, 2, 0));
      pixels.show();

      configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");

      pixels.setPixelColor(2, pixels.Color(0, 2, 0));
      pixels.show();
    }

    unsigned long lastPing = 0;

    /**
      Sends a ping every 5 seconds, and handles reconnections
    */
    void loop() {
      webSocket.loop();

      if (connected) {
        // Send ping every 5 seconds, to keep the connection alive
        if (millis() - lastPing > 5000) {
          sendPing();
          lastPing = millis();
        }
      } else {
        // Try to connect / reconnect to slack
        connected = connectToSlack();
        if (!connected) {
          delay(500);
        }
      }
    }

  [1]: https://github.com/urish/arduino-slack-bot
  [2]: https://www.adafruit.com/product/2821

title: Slackbot integration using ESP8266 gets "ssl->need_bytes=16432 > 6859"

Answers: 1

body:
@mach @Axel

I replaced use `rtm.start` with `rtm.connect` as per April 2017 Slack Recent Updates https://api.slack.com/changelog
and this got rid of the error on my Wemos.

    http.begin("https://slack.com/api/rtm.connect?token=" + SLACK_BOT_TOKEN, SLACK_SSL_FINGERPRINT);


body: I have a circuit in which I'm using an Arduino Pro Mini to interface with an RF69 radio via SPI. The SCK pin on the Pro Mini is pin 13, which also happens to be the LED pin. Is it possible to write pin 13 high and low in the same sketch that I'm interfacing with the radio? I don't need to do SPI communication simultaneously with the LED. I can put the radio to sleep then use the LED. I'm wondering if this will some how mess up the SPI communication or if everything will be OK.

title: Can regular Arduino pins be used during SPI?

Answers: 1

body:
I did not check the datasheet of the RF69, but it is customary for SPI devices to have a “slave select” input pin. When such a device is _not_ selected, it will leave its MISO pin in high impedance and completely ignore whatever may happen on the MOSI and SCK pins. This effectively disconnects the device from the SPI bus. In this situation you show be able to play with the LED without disturbing the device.

Beware that the slave select pin is usually active low: write it to `HIGH` to _deselect_ the device.


body:
I was hoping to design my own Arduino board for a recent project of mine, a portable project that was powered by a 3.7 LiPo battery. Most ideally, I wanted to replace the USB B port with a single USB Micro port that implements the following features:

1. Provides power to the Arduino while it is plugged in (just like a regular Arduino does).
2. Connect the D+ and D- pins of the USB to the Arduino somehow to allow for on-board programming (however the Arduino accomplishes this already, I'll refer to this as the "onboard usb/serial converter"). I want it to keep it programmable on-the-go.
3. Charges an on-board 3.7V LiPo Battery. I was hoping to use [Adafruit's PowerBoost 500 Shield][1] as a reference for my schematic.

However, I haven't been able to find a schematic or example that implements **all 3 features** above at the same time **from the same USB port**. I don't have much experience with charging circuits, so the following questions might sound dumb. Below are some solutions I was thinking of that probably won't work, but I wanted to make sure:

1. Connect the Output Voltage of the LiPo Battery to the V+/GND supply of the USB cable (probably not safe to connect all V+ sources together).
2. Just connect the D+/- data cables to the "onboard usb/serial converter" without connecting the Vbat/Vusb somehow, have the USB V+/GND connect to the LiPo charging circuit, and the Battery Voltage power the Arduino.

I know some devices have this charging/data-transfer functionality (e.g. my phone can transfer photos to my computer while being powered on and charging at the same time), but I'm wondering how it's possible to have similar functionality for an Arduino board. Any advice?

Absolute worst case, I'll just have 2 USB ports, one for charging the LiPo and one for Serial Communication/Programming

**EDIT:** The idea of using an ATMega32U4 seems appealing (despite the 3.3V vs 5V operating voltage), mainly because it has a pin for VBUS for USB and Vcc for main power. But I was wondering how to do this on say an ATMega328P that doesn't have a pin for VBUS.

  [1]: https://www.adafruit.com/product/2078

title: USB and Arduino: Power Arduino, charge LiPo, and transfer data at the same time

Answers: 3

body:
I'd recommend using the Arduino Leonardo as a reference for your circuit. Its pretty much the same as an Arduino UNO but has a built in USB interface so you don't need the USB-Serial converter.

I'd also recommend running the chip at 3.3V. That way you can use a linear regulator to regulate the 3.7V battery voltage down. Otherwise you'd need a boost converter to bump the voltage up to 5V which needs more parts.

If you follow those recommendations then all you will need is a LiPo charging IC to handle the charging. You'll need to add an ISCP header to flash the initial Leonardo bootloader, but after that you can use USB and the Arduino IDE to program it.

I did exactly this for a school project a while back. You can find the schematics here: https://github.com/seanwatson/ece4416-project/blob/master/hardware/rev2/sw-4416-project-v2-sch.pdf

body:
Following on from Sean Watson's answer, I would probably use the Bare Conductive Touch Board as your reference. It's a Leonardo derivative with all the features you're asking for. Full disclosure - I work at Bare Conductive and worked on the design of the board.

Eagle schematic and board file are [here][1]. Also, since this board successfully passed CE and FCC radiated emissions and immunity testing, you know that the reference design is sound for this if you want to create a product to sell.

The design uses a boost converter to allow for 5V operation - if you run the Atmega32u4 (or Atmega328) at 3.3V, you don't get guaranteed correct operation with a 16 MHz clock (check the data sheet). Since the Arduino bootloader for the Leonardo is written for a 16 MHz clocked MCU, this saves you the task of modifying the bootloader - and gives you the full 16 MIPS maximum performance.

  [1]: https://github.com/BareConductive/touch-board-ks-edition

body:
Use a TP4056 1A LiPo charger board (it has overdischarge protection) and a boost converter, like the XL6009. It will run you at most 5$ if you are prudent. Overdischarge protection is important.

If you want a port for programming, add a micro-USB breakout board, and if necessary a pushbutton for bringing RST down to GND. I prefer just having GND, TX, RX pins on a 3 pin header, and plugging my cable into that.


body: How can I compile my code via terminal? I am working on a Chrome app that allows you to write, compile, and upload code to an Arduino, and I need to know this so I can use the command line compiler on my Linux server. Mac or Linux terminal, it doesn't matter.

title: Compiling code via terminal

Answers: 3

body: Check out platformio.org it's the best solution out there for command line compiling.

body:
Assuming an AVR-based Arduino, you would need the avr-gcc compiler, the
avr-libc and the Arduino libraries. Also avrdude if you want to upload.
The only issue is that the commands used for the build process are quite
long (lots of options). You can see them by enabling verbose compilation
in the IDE. Thus you will probably want some way to automate the whole
thing.

There are several options for this. The most straightforward seems to be
the [arduino-builder][] command-line tool. This is part of the Arduino
project and should ensure maximum compatibility. Otherwise you could use
a plain old Makefile. I personally use [Sudar Muthu' Makefile][]. It can
be installed on a Debian-based Linux distribution by:

    sudo apt install arduino-mk

It is not fully compatible with the classic Arduino build process
though: it _does_ automatically include `<Arduino.h>` into your sketch,
but it does _not_ add forward declarations. Some prefer it this way, as
the automatic inclusion of forward declarations is somewhat buggy and
does not play well with some C++ features.

[arduino-builder]: https://github.com/arduino/arduino-builder
[Sudar Muthu' Makefile]: https://github.com/sudar/Arduino-Makefile

body:
There is an Arduino CLI (command line interface):

https://github.com/arduino/arduino-cli

You use commands such as to access Arduino IDE functions:

`arduino-cli compile --fqbn arduino:avr:leonardo sketch`

and

`arduino-cli upload -pCOM14 --fqbn arduino:avr:leonardo sketch`

(obviously port will be different under Linux)


body:
Today I learned about Vf for leds, after founding out that 3 leds in series driven by 5 V did not make them light up while 2 did.

However, I also read that it is quite bad for a power source to use more volts (like 3 times 2V) this way than the power source (5V for the Uno).

Can the Arduino be hurt this way?

title: Can the Arduino be hurt by connecting too many LEDs in serial?

Answers: 2

body:
The forward voltage of an LED or diode is the *applied* voltage of the "knee" in the exponential characteristic at which it starts to substantially conduct, and in the case of an LED, produce light.

It is not, under ordinary circumstances of indicator-type LEDs, a voltage that would be produced internally to the LEDs, at least not with any substantial current capability.

As long as you are supplying the LEDs from a voltage within the Arduino's I/O range, it should not be hurt by a series strings of *too many* LEDs.  However, in theory (if rarely in practice) a series string of *too few* LEDs that did not include a `current limiting resistor` would stress the Arduino beyond its ratings - and possibly (and more commonly) also the LED(s) beyond their current limits.

body:
Placing 3 "typical" LEDs in series and then driving them with the Arduino will not produce any light because the Arduino can only output 5V on any pin.  It would require approx 6 volts to drive current through the LEDs when connected in series.  This is for typical green, yellow, red type LEDs that have a 2 volt or so forward voltage drop. Note: some other colors require more forward voltage.

When you place two of these LEDs in series the forward voltage drop required to light them is only about 4 volts, that's why they light up when 3 in series didn't.  However, since the Arduino outputs 5 volts on its pin and the LEDs only require 4 volts the extra 1 volt can cause more current to flow which, if excessive, can damage the output pin.  Thats why when driving LEDs in this way its usually a good practice to place a current limiting resistor in series with the LED(s).  This resistor limits the current induced by any driving voltage which is over the voltage needed to drive the LEDs to conduction.


body:
I bought a BMP280 and it looks like this:

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

How can I connect BMP280 to Arduino Uno?
I tried the following examples on the web, but they didn't work.
I used  [this library][2], connecting the PINS in this way:

    VCC  ->  3.3V
    GND  ->  GND
    SCL  -> 13
    SDA  -> 12
    SDO  -> 11

But the sensor did not initialize.

  [1]: https://i.stack.imgur.com/c0zuX.jpg
  [2]: https://github.com/adafruit/Adafruit_Sensor

title: Wiring BMP280 to Arduino Uno

Answers: 2

body:
Eventually [as reported here][1], it worked using this pinout:

    VCC --> 3.3V
    GND --> GND
    SCK --> A5
    SDI --> A4

And this code:

    #include <Wire.h>

    #define BME280_ADDRESS 0x76
    unsigned long int hum_raw,temp_raw,pres_raw;
    signed long int t_fine;

    uint16_t dig_T1;
     int16_t dig_T2;
     int16_t dig_T3;
    uint16_t dig_P1;
     int16_t dig_P2;
     int16_t dig_P3;
     int16_t dig_P4;
     int16_t dig_P5;
     int16_t dig_P6;
     int16_t dig_P7;
     int16_t dig_P8;
     int16_t dig_P9;
     int8_t  dig_H1;
     int16_t dig_H2;
     int8_t  dig_H3;
     int16_t dig_H4;
     int16_t dig_H5;
     int8_t  dig_H6;

    void setup()
    {
        uint8_t osrs_t = 1;             //Temperature oversampling x 1
        uint8_t osrs_p = 1;             //Pressure oversampling x 1
        uint8_t osrs_h = 1;             //Humidity oversampling x 1
        uint8_t mode = 3;               //Normal mode
        uint8_t t_sb = 5;               //Tstandby 1000ms
        uint8_t filter = 0;             //Filter off
        uint8_t spi3w_en = 0;           //3-wire SPI Disable

        uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
        uint8_t config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en;
        uint8_t ctrl_hum_reg  = osrs_h;

        Serial.begin(9600);
        Wire.begin();

        writeReg(0xF2,ctrl_hum_reg);
        writeReg(0xF4,ctrl_meas_reg);
        writeReg(0xF5,config_reg);
        readTrim();                    //
    }

    void loop()
    {
        double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
        signed long int temp_cal;
        unsigned long int press_cal,hum_cal;

        readData();

        temp_cal = calibration_T(temp_raw);
        press_cal = calibration_P(pres_raw);
        hum_cal = calibration_H(hum_raw);
        temp_act = (double)temp_cal / 100.0;
        press_act = (double)press_cal / 100.0;
        hum_act = (double)hum_cal / 1024.0;
        Serial.print("TEMP : ");
        Serial.print(temp_act);
        Serial.print(" DegC  PRESS : ");
        Serial.print(press_act);
        Serial.print(" hPa  HUM : ");
        Serial.print(hum_act);
        Serial.println(" %");

        delay(1000);
    }
    void readTrim()
    {
        uint8_t data[32],i=0;                      // Fix 2014/04/06
        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(0x88);
        Wire.endTransmission();
        Wire.requestFrom(BME280_ADDRESS,24);       // Fix 2014/04/06
        while(Wire.available()){
            data[i] = Wire.read();
            i++;
        }

        Wire.beginTransmission(BME280_ADDRESS);    // Add 2014/04/06
        Wire.write(0xA1);                          // Add 2014/04/06
        Wire.endTransmission();                    // Add 2014/04/06
        Wire.requestFrom(BME280_ADDRESS,1);        // Add 2014/04/06
        data[i] = Wire.read();                     // Add 2014/04/06
        i++;                                       // Add 2014/04/06

        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(0xE1);
        Wire.endTransmission();
        Wire.requestFrom(BME280_ADDRESS,7);        // Fix 2014/04/06
        while(Wire.available()){
            data[i] = Wire.read();
            i++;
        }
        dig_T1 = (data[1] << 8) | data[0];
        dig_T2 = (data[3] << 8) | data[2];
        dig_T3 = (data[5] << 8) | data[4];
        dig_P1 = (data[7] << 8) | data[6];
        dig_P2 = (data[9] << 8) | data[8];
        dig_P3 = (data[11]<< 8) | data[10];
        dig_P4 = (data[13]<< 8) | data[12];
        dig_P5 = (data[15]<< 8) | data[14];
        dig_P6 = (data[17]<< 8) | data[16];
        dig_P7 = (data[19]<< 8) | data[18];
        dig_P8 = (data[21]<< 8) | data[20];
        dig_P9 = (data[23]<< 8) | data[22];
        dig_H1 = data[24];
        dig_H2 = (data[26]<< 8) | data[25];
        dig_H3 = data[27];
        dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
        dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F); // Fix 2014/04/06
        dig_H6 = data[31];                                   // Fix 2014/04/06
    }
    void writeReg(uint8_t reg_address, uint8_t data)
    {
        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(reg_address);
        Wire.write(data);
        Wire.endTransmission();
    }

    void readData()
    {
        int i = 0;
        uint32_t data[8];
        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(0xF7);
        Wire.endTransmission();
        Wire.requestFrom(BME280_ADDRESS,8);
        while(Wire.available()){
            data[i] = Wire.read();
            i++;
        }
        pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
        temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
        hum_raw  = (data[6] << 8) | data[7];
    }

    signed long int calibration_T(signed long int adc_T)
    {

        signed long int var1, var2, T;
        var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
        var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;

        t_fine = var1 + var2;
        T = (t_fine * 5 + 128) >> 8;
        return T;
    }

    unsigned long int calibration_P(signed long int adc_P)
    {
        signed long int var1, var2;
        unsigned long int P;
        var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
        var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
        var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
        var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
        var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
        var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
        if (var1 == 0)
        {
            return 0;
        }
        P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
        if(P<0x80000000)
        {
           P = (P << 1) / ((unsigned long int) var1);
        }
        else
        {
            P = (P / (unsigned long int)var1) * 2;
        }
        var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
        var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
        P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
        return P;
    }

    unsigned long int calibration_H(signed long int adc_H)
    {
        signed long int v_x1;

        v_x1 = (t_fine - ((signed long int)76800));
        v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +
                  ((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
                  (((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
                  ((signed long int) dig_H2) + 8192) >> 14));
       v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
       v_x1 = (v_x1 < 0 ? 0 : v_x1);
       v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
       return (unsigned long int)(v_x1 >> 12);
    }

Actually, BMP280 doesn't monitor relative humidity so you can delete the part related to the humidity control.

    #include <Wire.h>

    #define BME280_ADDRESS 0x76
    unsigned long int temp_raw,pres_raw;
    signed long int t_fine;

    uint16_t dig_T1;
     int16_t dig_T2;
     int16_t dig_T3;
    uint16_t dig_P1;
     int16_t dig_P2;
     int16_t dig_P3;
     int16_t dig_P4;
     int16_t dig_P5;
     int16_t dig_P6;
     int16_t dig_P7;
     int16_t dig_P8;
     int16_t dig_P9;

    void setup()
    {
        uint8_t osrs_t = 1;             //Temperature oversampling x 1
        uint8_t osrs_p = 1;             //Pressure oversampling x 1
        uint8_t mode = 3;               //Normal mode
        uint8_t t_sb = 5;               //Tstandby 1000ms
        uint8_t filter = 0;             //Filter off
        uint8_t spi3w_en = 0;           //3-wire SPI Disable

        uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
        uint8_t config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en;

        Serial.begin(9600);
        Wire.begin();

        writeReg(0xF4,ctrl_meas_reg);
        writeReg(0xF5,config_reg);
        readTrim();                    //
    }

    void loop()
    {
        double temp_act = 0.0, press_act = 0.0;
        signed long int temp_cal;
        unsigned long int press_cal;

        readData();

        temp_cal = calibration_T(temp_raw);
        press_cal = calibration_P(pres_raw);
        temp_act = (double)temp_cal / 100.0;
        press_act = (double)press_cal / 100.0;
        Serial.print("TEMP : ");
        Serial.print(temp_act);
        Serial.print(" DegC  PRESS : ");
        Serial.println(press_act);
        delay(1000);
    }
    void readTrim()
    {
        uint8_t data[32],i=0;                      // Fix 2014/04/06
        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(0x88);
        Wire.endTransmission();
        Wire.requestFrom(BME280_ADDRESS,24);       // Fix 2014/04/06
        while(Wire.available()){
            data[i] = Wire.read();
            i++;
        }

        Wire.beginTransmission(BME280_ADDRESS);    // Add 2014/04/06
        Wire.write(0xA1);                          // Add 2014/04/06
        Wire.endTransmission();                    // Add 2014/04/06
        Wire.requestFrom(BME280_ADDRESS,1);        // Add 2014/04/06
        data[i] = Wire.read();                     // Add 2014/04/06
        i++;                                       // Add 2014/04/06

        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(0xE1);
        Wire.endTransmission();
        Wire.requestFrom(BME280_ADDRESS,7);        // Fix 2014/04/06
        while(Wire.available()){
            data[i] = Wire.read();
            i++;
        }
        dig_T1 = (data[1] << 8) | data[0];
        dig_T2 = (data[3] << 8) | data[2];
        dig_T3 = (data[5] << 8) | data[4];
        dig_P1 = (data[7] << 8) | data[6];
        dig_P2 = (data[9] << 8) | data[8];
        dig_P3 = (data[11]<< 8) | data[10];
        dig_P4 = (data[13]<< 8) | data[12];
        dig_P5 = (data[15]<< 8) | data[14];
        dig_P6 = (data[17]<< 8) | data[16];
        dig_P7 = (data[19]<< 8) | data[18];
        dig_P8 = (data[21]<< 8) | data[20];
        dig_P9 = (data[23]<< 8) | data[22];

    }
    void writeReg(uint8_t reg_address, uint8_t data)
    {
        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(reg_address);
        Wire.write(data);
        Wire.endTransmission();
    }

    void readData()
    {
        int i = 0;
        uint32_t data[8];
        Wire.beginTransmission(BME280_ADDRESS);
        Wire.write(0xF7);
        Wire.endTransmission();
        Wire.requestFrom(BME280_ADDRESS,8);
        while(Wire.available()){
            data[i] = Wire.read();
            i++;
        }
        pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
        temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
    }

    signed long int calibration_T(signed long int adc_T)
    {

        signed long int var1, var2, T;
        var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
        var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;

        t_fine = var1 + var2;
        T = (t_fine * 5 + 128) >> 8;
        return T;
    }

    unsigned long int calibration_P(signed long int adc_P)
    {
        signed long int var1, var2;
        unsigned long int P;
        var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
        var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
        var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
        var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
        var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
        var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
        if (var1 == 0)
        {
            return 0;
        }
        P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
        if(P<0x80000000)
        {
           P = (P << 1) / ((unsigned long int) var1);
        }
        else
        {
            P = (P / (unsigned long int)var1) * 2;
        }
        var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
        var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
        P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
        return P;
    }

  [1]: https://forum.arduino.cc/index.php?topic=451402.0

body:
The BMP280 is a sensor that can be used at 3.3V, but not at 5V. The datasheet tells that the interface pins may be maximum 3.6V (when the sensor is powered with 3.3V). That means you may not connect the sensor to an Arduino Uno. Not to the SPI interface and not to the I2C interface. The sensor might already be damaged. This is not a joke. When sensor is still working, the results might be noisy or the values could drift too much.

The easiest solution is a level shifter module for I2C. Another option is to add two extra pullup resistors of 10k from SDA to 3.3V and from SCL to 3.3V and connect the SDA and SCL directly to the Arduino Uno. It will not be reliable, but with some luck it will work. You need some luck, because it will not be okay according to the datasheet of the ATmega328P.

You could also buy a 3.3V Arduino board (Arduino Due, Arduino Zero, Arduino M0, and so on), or buy a BMP280 module that is compatible with 3.3V and 5V signals: [Adafruit BMP280][1]

  [1]: https://www.adafruit.com/product/2651


body:
In my recent project, I have RPM Square wave from vehicle. Now, based on that I want square wave based on falling edge but only alternative pulse of RPM square wave.

I think below image clear more properly.

[![Pulse][2]][2]

Upper yellowish square wave which I need. And below pinkish square wave is RPM square wave.

I made a code for that and it's working fine but when RPM is stable. But when RPM change rapidly then it's not working fine.

    const int kPinRPM = 3;        // RPM / Digital Pin 3
    const int RPMInterrupt = 1;   // RPM's interrrupt pin
    byte engineCylinders = 2;         // Engine cylinders = 4;
    byte engineCycles = 4;            // Engine cycle = 2
    int refreshInterval = 750;        // Milliseconds between sensor updates
    unsigned long previousMillis = 0;
    volatile int RPMpulses = 0;
    int RPM, Final_RPM;

    const int kPinInj = 12;

    volatile uint32_t kInjTime = 0;

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

      pinMode(kPinRPM, INPUT_PULLUP); // Enable internal pullup
      attachInterrupt(RPMInterrupt, countRPM, FALLING); //Interrupt for RPM

      pinMode(kPinInj, OUTPUT);
    }

    void loop()
    {
      if(millis() - previousMillis > refreshInterval)
      {
        previousMillis = millis();
        RPM =  getRPM();
      }

      Serial.println(RPM);

      if((kInjTime > 0) && ((millis() - kInjTime) >= 10))
      {
        kInjTime = 0;
        digitalWrite(kPinInj, LOW);
      }
    }

    void countRPM()
    {
      RPMpulses++;

      if(RPMpulses % 2 == 0)           // Skip alternative pulse
      {
        kInjTime = millis();
        digitalWrite(kPinInj, HIGH);
      }
    }

    int getRPM()
    {
      Final_RPM = int(RPMpulses * (60000.0 / float(refreshInterval)) * engineCycles / engineCylinders / 2.0);
      RPMpulses = 0;
      Final_RPM = min(99999, Final_RPM);
    }

After SUGGESTION, updating my codes. But it output waveform has some problem. In white circle, you can see that problem.

[![Waveforms][1]][1]

  [1]: https://i.stack.imgur.com/8tEuN.jpg
  [2]: https://i.stack.imgur.com/d3iXZ.jpg

title: Square wave based on falling edge of alternative pulse of upcoming RPM square wave

Answers: 2

body:
There are some things you shouldn't be doing within an interrupt service routine (ISR) like `countRPM()`:

 1. Don't call the `millis()` function. It depends on other interrupts which will be disabled during the execution of your ISR.

 2. Don't call `digitalWrite` or any other functions

 3. Don't use execution cycles hungry operators like `%` (modulo). To obtain modulo 2, just use a bit mask for the LSB.

What you should actually be doing within the ISR is just setting/resetting a flag or variable. Then, do all your stuff in the `loop()` function according the value of the flag or variable.

body:
Rather than saying

    if(RPMpulses % 2 == 0)           // Skip alternative pulse
      {
        kInjTime = millis();
        digitalWrite(kPinInj, HIGH);
      }

and later setting `kPinInj` in the main loop, you could act as follows:

    digitalWrite(kPinInj, RPMpulses & 1); // Set or clear kPinInj
    if(RPMpulses & 1)
      kInjTime = millis();  // Store alternate times

This would ensure that your trace 1 toggles properly.  If you want a shorter up-time on that trace, you could treat `CHANGE` interrupts rather than `FALLING`, and maintain `RPMpulses` as a number twice as big as now, ie use 120000 instead of 60000 in the RPM calculation, and could say:

    digitalWrite(kPinInj, (RPMpulses & 3)==1); // Set or clear kPinInj
    if((RPMpulses & 3)==1)
      kInjTime = millis();  // Store alternate fall times

Note, the floating point arithmetic in `getRPM()` is slow.  At a 750 ms refresh interval, that may not matter much.  But you probably can get good enough results rather more quickly using just integer arithmetic, if you parenthesize the expression somewhat as follows:

    Final_RPM = ((RPMpulses * (60000UL / 2) * (engineCycles/engineCylinders)) / refreshInterval;

That is, do any remainderless divisions early; multiply all the remaining numerator terms together into a large number; then divide by the comparatively small `refreshInterval`, ending up with numerous significant digits without the use of floating point arithmetic, which takes many milliseconds on typical Arduino systems.

*Edit 2:* If your modified code still says `RPMpulses = 0;` within `getRPM()`, you may get a glitch at the end or beginning of each   refresh interval.  You may instead need to say `RPMpulses = 1;`, or `RPMpulses &= 1;`, or some such.  Also, to avoid an extra count when the latter expression is 1 instead of 0, say `RPM0 = RPMpulses &= 1;` and use `(RPMpulses-RPM0)` instead of `RPMpulses` in calculating `Final_RPM`.


body:
Here's the system I want to work on:

 1. The weight controller device detects weight which can transfer data via RS232 serial connection
 2. I used [RS232 converter to TTL serial module][1] to connect the weight controller device to Arduino
 3. The TTL connections were made to respective pins of Arduino UNO Board (GND-GND, VCC-5V, RX-0, TX-1)

**The serial print from serial connection should produce 17 character length string : ST,GS    1.58,kg**

Why am I getting strange results at times?
---

    // Read Serial (RS232) data from Weight Controller Device via RS232 to TTL Converter Module

    // Ignore the include statement, the editor does not allow pasting certain characters

    include SoftwareSerial.h

    int RX_PIN = 2;
    int TX_PIN = 3;
    int BAUD_IDE = 9600;
    int BAUD_WEIGHT_SENSOR = 9600;

    // serial port from weight controller
    SoftwareSerial mySerial = SoftwareSerial(RX_PIN, TX_PIN);

    void setup() {
      mySerial.begin(BAUD_WEIGHT_SENSOR);
      Serial.begin(BAUD_IDE);
    }

    void loop() {
      while (mySerial.available()) {
        int inChar = mySerial.read();
        if (inChar != '\n') {
          serialData += (char)inChar;
        }
        else {
          int dataSize = serialData.length();
          Serial.print(serialData);
          Serial.print(" length:  ");
          Serial.print(dataSize);
          Serial.print("\n");
          delay(3000);
          serialData = "";
        }
      }
      serialData = "";

    }

    // this one works perfectly but i want to store as string to
    process
    // information and use for other functions
    /*void loop() {
    if (mySerial.available()){
      Serial.print((char)mySerial.read());

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

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

title: Arduino to read from RS232 converter to TTL serial module (updated)

Answers: 2

body: You need to disconnect the Arduino`s RX and TX pins from any device before trying to upload a sketch via USB, because the Serial data is directly wired from the USB chip to these pins. It's as if you're trying to flash the thing behind your RS232 adapter.

body:
You are attempting to talk to your peripheral via a second serial UART implemented in software on arbitrary pins, which should leave the hardware UART free for uploading and debug or other runtime communication between the Arduino and a PC.

However, the "arbitrary pins" you choose to use to connect the peripheral are *the same* pins as used by the hardware UART.

**Move your peripheral to two other pins**, for example

    int RX_PIN = 2;
    int TX_PIN = 3;

and move the connections accordingly

Also consider if you really want `Serial.println()` which will add a line break after every character in the output, and will also print the received characters as their numeric ASCII codes, one per line, rather than printing the characters themselves.  You probably want `Serial.write()`.


body:
Why does this throw the error: "void value not ignored as it ought to be

returning = printTemperature(returnLine);"

    void printTemperature(DeviceAddress deviceAddress)
    {
      float tempC = sensors.getTempC(deviceAddress);
      if (tempC == -127.00) {
        Serial.print("Error getting temperature");
      return 0;
      } else {
        return tempC;
      }
    }

    void loop(){

       delay(2000);
       feeding = printTemperature(feedLine);
       returning = printTemperature(returnLine);
     mySql;
     feeding = 0;
     returning = 0;
    }
Both 'feeding' and 'returning' are declared as a float too.

title: Void value not ignored

Answers: 2

body: printTemperature() is declared void (i.e., nothing returned) but it contains a return statement, and you've attempted to assign the (void) value. You probably meant to declare the function as 'float'.

body:
First of all: In C/C++ world void means "empty" as in "no value".

As the method is declared void it is saying that it does not return a value.
But the code sets the value and also assigns the return value to a variable.
Logically that does not make sense.

In the old days a void method returned an int (I'm not sure whether that is still the case) but it has never been a good idea to make a value returning method a void returning method.
So technically in the old days it made sense but it still was "not a good idea"

Nowadays compilers will return an error when you return a value in a void method. This can be turned off by using the -fpermissive compiler directive.
This directive might be useful in some template cases. I advice not to use it.


body:
What reasons could there be for a joystick to return 0 when using analogRead?

X-pin is connected to AO and y-pin is connected to A1.

VCC is connected to 5V and GRND is connected to GRND.

By default (as in when not using the joystick) the value should be approximately 500, right? Well why is the value then 0? Can this only be a wiring issue?

title: analogRead returning 0 constantly when connected to joystick

Answers: 2

body:
Adding an answer after clarification:-

Moving the joystick also failed to produce a valid reading which indicated a wiring issue or incorrect configuration of the Analog `pin` in the Arduino code.

Proven to be a wiring problem

body:
Follow these steps to identify the problem.

1. Disconnect A0/A1 from Arduino and use a multimeter to check the voltage coming from the joystick X and Y. If it swings from 0 to 5V....the problem is in the Arduino. Check your code and connections. Maybe your wires are damaged?

2. If the voltage is not changing at X and Y pins, disconnect power from the joystick and use a multimeter to check the joystick potentiometer. Check all three terminals in each axis of the joystick. If R is the measured resistance between the two outer pins, then the resistance between the central pin and each of the outer pins should vary from 0 to R depending on the position of the joystick.

3. If there is no problem at all with the joystick readings by potentiometer then the problem has to be on the Arduino side.


body:
I am new to programming and Arduinos but I've decided to give a go for a project. I'm after a code that will read PWM signals from a RC receiver (Specifically aileron and throttle) and output this as 4 PWM signals to drive two H Bridges (Right motor forward/reverse and left motor forward/reverse).

This is my code that isn't working.

    unsigned long timer[3];
    byte last_channel[2];
    int throttle;
    int aileron;

    void setup() {
    pinMode(8, OUTPUT);//Right motor fowards
    pinMode(9, OUTPUT);//Right motor reverse
    pinMode(10, OUTPUT);//left motor fowards
    pinMode(11, OUTPUT);//left motor reverse

    PCICR |= (1 << PCIE0);  //This enables pin change intterupt enabler

    PCMSK0 |= (1 << PCINT0); // This tells the mask register
    which pins will cause an intterupt (Pin 2)

    PCMSK0 |= (1 << PCINT1); // (Pin 3)

    Serial.begin(9600); //Sets the data rate in bits per second
    }

    void loop() {

    }
    ISR(PCINT0_vect) {

    timer[0] = micros(); // registers intterupt time

    //Throttle_Channel----------------------------------------------------------

    if(last_channel[0] == 0 && PINB & B00000001 ) { // This checks if pin has
    changed from low to high

    last_channel[0] = 1;

    timer[1] = timer[0];
    }

    else if(last_channel[0] == 1 && !(PINB & B00000001)){

    last_channel[0] = 0;

    throttle = timer[0] - timer[1]; //calculates the change in time and sets to

    input[0]
    //--------------------------------------------------------------------------
    }
    //Aileron_Channel-----------------------------------------------------------

    if(last_channel[1] == 0 && PINB & B00000010 ) { // This checks if pin has

    changed from low to high

    last_channel[1] = 1;

    timer[2] = timer[0];
    }

    else if(last_channel[0] == 1 && !(PINB & B00000010)){ //This checks if pin  has

    changed from high to low

    last_channel[1] = 0;

    aileron = timer[0] - timer[2]; //calculates the change in time and sets to i

    input[0]
    //--------------------------------------------------------------------------
    }

    //Calculations to put output in correct form--------------------------------
    int throttle_pwm = (throttle - 1500) / 1000;

    int aileron_pwm = (aileron - 1500) / 1000;

    int v = (0.5 - abs(aileron_pwm)) * (throttle_pwm / 0.5) + throttle_pwm;

    int w = (0.5 - abs(throttle_pwm)) * (aileron_pwm / 0.5) + aileron_pwm;

    int lm = v + (w/2) * 255;

    int rm = v - (w/2) * 255;
    //--------------------------------------------------------------------------

    if (lm > 0 && rm > 0){

    analogWrite(8,rm);

    analogWrite(9,0);

    analogWrite(10,lm);

    analogWrite(11,0);
    }

    else if (lm > 0 && rm <= 0){

    analogWrite(8,0);

    analogWrite(9,abs(rm));

    analogWrite(10,lm);

    analogWrite(11,0);
    }

    else if (lm <= 0 && rm > 0){

    analogWrite(8,rm);

    analogWrite(9,0);

    analogWrite(10,0);

    analogWrite(11,abs(lm));

    }

    else if (lm <= 0 && rm <= 0){

    analogWrite(8,0);

    analogWrite(9,abs(rm));

    analogWrite(10,0);

    analogWrite(11,abs(lm));

    //--------------------------------------------------------------------------
    }
    }

It compiles fine but I've tried measure PWM at the four output and it doesn't work. If anyone could offer advice or guidance it would be greatly appreciated.

title: How can I alter my program to read PWM signals from Arduino Mega?

Answers: 3

body:
See [my page about interrupts](http://www.gammon.com.au/interrupts). Data to be shared between an ISR and the main code should be declared `volatile` which yours isn't.

---

Also see:

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

> Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

It's not really clear from your post which pins you are using for the encoder, but you mention pins 2 and 3:

>     PCMSK0 |= (1 << PCINT0); // (Pin 2)
>     PCMSK0 |= (1 << PCINT1); // (Pin 3)

Pins 2 and 3 on the board are not PCINT0 and PCINT1. Also they are not in the list of supported pin-change interrupt pins.

You might be better off using **external** interrupts (see my page above). External interrupts are supported on pin 2 and 3. However your code needs to change a bit.

body:
It looks like the code in the ISR is slow and it may compute incorrect results.

It is slow because of using floating point arithmetic in `throttle_pwm` and `aileron_pwm` calculations.  It may be so slow that the trailing edge of a PWM pulse occurs while the leading edge still is being processed.  This will delay trailing edge processing, and mis-measurement of pulse lengths.

The main thing to do to reduce the amount of code executed in the ISR is separate the input measuring phase from the output actuating phase.  You could compute pulse widths and store them in volatile variables for a loop in main to pick up and use in `analogWrite()` statements there.

---

Note, in 16-bit `int` arithmetic, the value of expression `(t-1500)/1000` is 0 for 500 < t < 2500.   Because `throttle` and `aileron` are supposed to be RC pulse lengths in the range 1000 to 2000 μs, your  `throttle_pwm` and `aileron_pwm` will be zero.  That means you can replace the following code,

    int throttle_pwm = (throttle - 1500) / 1000;
    int aileron_pwm = (aileron - 1500) / 1000;
    int v = (0.5 - abs(aileron_pwm)) * (throttle_pwm / 0.5) + throttle_pwm;
    int w = (0.5 - abs(throttle_pwm)) * (aileron_pwm / 0.5) + aileron_pwm;
    int lm = v + (w/2) * 255;
    int rm = v - (w/2) * 255;

with this code:

    int throttle_pwm=0, aileron_pwm=0, v=0, w=0, lm=0, rm=0;

which should save you several milliseconds of computation!  Also, having `lm` and `rm` as constant zeroes means that you don't need all those lengthy and laborious `if` and `else` blocks.   You can replace those 24 lines of stuff with just the following:

    analogWrite(8,0);
    analogWrite(9,0);
    analogWrite(10,0);
    analogWrite(11,0);

---

Slightly more seriously, it looks like you intended for your arithmetic like `(throttle - 1500) / 1000`, etc. to determine whether to raise or lower the throttle, etc.   Instead of doing that time-consuming division, just say:

    int throttle_pwm = throttle > 1500 ? 1 : -1;  // or whatever values you meant to have
    int aileron_pwm = aileron > 1500 ? 1 : -1;    // ditto

Instead of all those 24 lines of stuff, just say:

    analogWrite(8,  (rm>0) * Level);
    analogWrite(9,  (rm<=0)* Level);
    analogWrite(10, (lm>0) * Level);
    analogWrite(11, (lm<=0)* Level);

where `Level` is some level you want to set the control to.  Note, an expression like `(rm>0)` has a value 1 when it is true and and 0 when it is false.  So when `rm>0`, you have, in effect, `analogWrite(8,Level);` and `analogWrite(9,0);`.

If instead you end up with a calculation where `lm` and `rm` are actually usable PWM levels, ie numbers from 0 to 255, you could instead say:

    analogWrite(8,   (rm>0) * rm);
    analogWrite(9,  -(rm<=0)* rm);
    analogWrite(10,  (lm>0) * lm);
    analogWrite(11, -(lm<=0)* lm);

or could say:

    analogWrite(8,  rm>0  ?  rm : 0);
    analogWrite(9,  rm<=0 ? -rm : 0);
    analogWrite(10, lm>0  ?  lm : 0);
    analogWrite(11, lm<=0 ? -lm : 0);

---

Also see [my answer to](https://arduino.stackexchange.com/a/18221/3917) the question  [Read RC receiver channels using Interrupt instead of PulseIn](https://arduino.stackexchange.com/q/18183/read-rc-receiver-channels-using-interrupt-instead-of-pulsein) and see [my answer to](https://arduino.stackexchange.com/a/33707/3917) the question  [Arduino read PWM duty cycle value with input (analog / digital)](https://arduino.stackexchange.com/q/33689/arduino-read-pwm-duty-cycle-value-with-input-analog-digital).

body:
If you are trying to read a PWM signal, you should try using the [pulseIn][1] function, which reads the length of a pulse signal.

  [1]: https://www.arduino.cc/en/Reference/PulseIn


body:
I work with cameras in the film and TV industry. A project I have just started tinkering around with is building an Arduino Uno-based box that would automatically collect the metadata (settings, etc.) via the camera's built-in web server (over Ethernet, at least at the moment). Specifically the Arri Alexa camera.

Like I said, this camera already has a web server and the functionality built in for somebody to hook their computer directly up to the camera with an Ethernet cord (it actually uses an RJ45 - Lemo proprietary cable system in order to support some accessories that draw more power than RJ45 is capable of). Then when you navigate to the camera's IP address in a web browser it serves up a web page to you with all the camera settings and other things displayed.

I found that my test computer connected perfectly to the camera without fiddling with any network settings as the manufacturer's documentation seemed to indicate. Here are the basic network settings my computer had when connected directly to the camera over ethernet (no Arduino yet):

[![IPConfig Settings][2]][2]

Notice the IP Address and subnet mask: 169.254.106.46 and 255.255.0.0 respectively.

Just to note, these are the manufacturer recommended settings I found in some literature:

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

Since that was working I tested the Arduino using the same settings. I am using an Arduino Uno combined with a Seeed Ethernet Shield (v2.0) which utilizes a Wiznet 5200 processor (not the 5100 normally used). Because of this you have to use the Ethernetv2_0 library that Seeed provides rather than the normal Ethernet library.

Here is my code, basically an adapted version of the WebClientRepeating example. I got this code working when I was just connecting to say arduino.cc and was going through the hub of my router (auto-assigned IP address). However when I attempt to connect to the camera with the Arduino sans Hub / Switch with a manually assigned IP address and subnet mask and all that I can never make the client (object) to connect. Basically this code is printing out "connection failed" to the serial monitor indicating and connection was never established.

    #include <SPI.h>
    #include <EthernetV2_0.h>

    // assign a MAC address for the ethernet controller.
    // fill in your address here:
    byte mac[] = {
      0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
    };

    // fill in an available IP address on your network here,
    // for manual configuration:
    //IPAddress ip(169, 254, 106, 46); //Address that worked on my computer
    IPAddress ip(169, 254, 1, 2); //Manufacturer recommended address

    // fill in your Domain Name Server address here:
    IPAddress myDns(1, 1, 1, 1); //Random, not sure if I need to do anything specific here

    // subnet mask that manufacturer recommends and what worked on my computer
    IPAddress subnet(255, 255, 0, 0);

    // initialize the library instance:
    EthernetClient client;

    //IPAddress server(64,131,82,241); //arduino.cc IPAddress
    IPAddress server(169, 254, 184, 143); //Arri Alexa (Camera) IPAddress

    unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
    const unsigned long postingInterval = 10L * 1000L; // delay between updates, in milliseconds
    // the "L" is needed to use long type numbers

    #define W5200_CS  10
    #define SDCARD_CS 4

    void setup() {
      // start serial port:
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }
      pinMode(SDCARD_CS,OUTPUT);
      digitalWrite(SDCARD_CS,HIGH);//Deselect the SD card
      // give the ethernet module time to boot up:
      delay(1000);
      // start the Ethernet connection using a fixed IP address and DNS server:
      Ethernet.begin(mac, ip, myDns, subnet);
      // print the Ethernet board/shield's IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
    }

    void loop() {
      // if there's incoming data from the net connection.
      // send it out the serial port.  This is for debugging
      // purposes only:
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
      }
      // if ten seconds have passed since your last connection,
      // then connect again and send data:
      if (millis() - lastConnectionTime > postingInterval) {
        httpRequest();
      }
    }

    // this method makes a HTTP connection to the server:
    void httpRequest() {
      // close any connection before send a new request.
      // This will free the socket on the WiFi shield
      client.stop();
      // if there's a successful connection:
      if (client.connect(server, 80)) {
        Serial.println("connecting...");
        // send the HTTP GET request:
        client.println("GET /webremote/index.html HTTP/1.1");
        client.println("Host: 169.254.184.143");
        client.println("User-Agent: arduino-ethernet");
        client.println("Connection: close");
        client.println();
        // note the time that the connection was made:
        lastConnectionTime = millis();
      } else {
        // if you couldn't make a connection:
        Serial.println("connection failed");
      }
    }

I guess my question is, if I'm using the exact same network settings that worked for my computer connecting to the camera, why aren't they working for the Arduino? I know this is somewhat of an obscure situation but I'll appreciate any ideas you can give me. Thanks!

  [2]: https://i.stack.imgur.com/kT4cr.png
  [3]: https://i.stack.imgur.com/bODPX.jpg

title: Connect Arduino Uno to video camera's web Server via Ethernet (not working)

Answers: 2

body:
I agree with Mark that your code all looks sensible, apart from the line defining myDNS. I have no experience of the board/library you are using, but recently I saw an industrial board suffer from a similar problem that turned out to be it was trying to resolve an IP address to a name using reverse DNS and because the DNS server wasn't set properly it failed to connect. So it might be that by setting the address in the myDNS line to a valid DNS server (the one your test PC uses?) then the problem will go away.

If that doesn't work then can you read the manual and see if the Client object can be persuaded to give you an error code or message that would give you a hint as to why it isn't working?

I understand that 169.254.1.2 is the manufacturer recommended address, but why did you use 169.254.106.49 for the test PC? It's very unlikely to be anything, but...

Also (I'm sure this was your first check), is the connection between the Arduino and the camera a straight connection, there are no firewall, routers, switches or bridges in the way doing NAT or PAT or blocking certain connections etc?

(DNS = Domain Name Service, converts names like google.com into meaningful addresses like 1.2.3.4)

body:
In the spirit of "Use the Source, Luke," I've had a look at the [code on GitHub](https://github.com/Seeed-Studio/Ethernet_Shield_W5200/blob/master/EthernetV2_0.cpp#L54), which is I hope the same code that you're using or very similar to it.

There the four-parameter version of `Ethernet.begin()` takes the gateway, not the subnet mask, as the fourth parameter. The subnet mask, when passed in explicitly, is the fifth parameter of the five-parameter version.

This shouldn't actually make any difference since the gateway ought not be used for anything on the same subnet, and the default subnet for [class B addresses](https://en.wikipedia.org/wiki/Classful_network#Classful_addressing_definition)  (from `128.0.0.0` through `191.255.255.255`), in which range your address falls, is 16 bits, `255.255.0.0`.

The problem is, the code linked has what I would [argue is a bug](https://github.com/Seeed-Studio/Ethernet_Shield_W5200/issues/9):

    void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
    {
      IPAddress subnet(255, 255, 255, 0);
      begin(mac_address, local_ip, dns_server, gateway, subnet);
    }

The subnet mask is _always_ set to 24 bits (`255.255.255.0`), in this call that you're using.

`169.254.1.2` and `16.254.184.143` don't have the same 24-bit prefix, so the software (I assume, I've not followed it through) will try to contact the gateway you inadvertently supplied, which isn't even on the same network (not to mention nonexistent), and so fail.

Try calling the 5-argument `Ethernet.begin()` (passing in `0.0.0.0` for the gateway should be fine) and see if that fixes your problem.

I checked the [WebClientRepeating example](https://github.com/Seeed-Studio/Ethernet_Shield_W5200/blob/master/examples/WebClientRepeating/WebClientRepeating.ino#L55) in that repo and they use the three-parameter version. Perhaps you switched to the four-parameter version, or perhaps you got your example from another library. (This example hasn't been modified since the start of the repo in April 2014.)


body:
I'm trying to measure the temperature using a DS18B20 sensor. I'm using the DallasTemperature and OneWire Libraries. The sensor is connect in Pin 10 with a 4k7 resistor between VDD and DQ (actually I'm using 4x 1k and 2x 330 ohms) as so:

[![layout][1]][1]

Here's the code I'm using:

    #include <OneWire.h>
    #include <DallasTemperature.h>

    #define ONE_WIRE_BUS 10

    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);

    float celsius;

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

      sensors.setResolution(12);

      sensors.begin();
    }

    void loop(void) {
      sensors.requestTemperatures();
      celsius = sensors.getTempCByIndex(0);

      Serial.println(celsius);
    }

The sensor is outputing values close to the actual temperature (measure with a mercury thermometer), but a bit off.

Example:

    Sensor Temperaute: 34.44°C
    Thermometer Temperature: ~32°C

Why is that? And how can I fix it?

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

title: DS18B20 - Temperature a bit off?

Answers: 1

body:
When the wires to the DS18B20 are short, you can use a 10k resistor as well.

The DS18B20 is accurate. If you have connected it wrong and it became very hot, then it might be damaged. But normally it is always accurate.

Many report that the DS18B20 returns a high temperature, and the cause is often something nearby that makes the DS18B20 warmer. For example an Arduino board (with a hot voltage regulator) or a computer screen or a certain air flow of warm air or even very dim sunlight. A normal thermometer does not do that, but the DS18B20 is highly influenced by warm things nearby.

Some temperature sensors have a problem with self-heating. You could add a delay of 5 seconds in the loop function, to see if that makes a difference.

To be sure you can put it in distilled water at sea level at 0°C (water and ice cubes) and 100°C (boiling water).

The picture uses pin 2 and the sketch uses pin 10. I assume that is a mistake.


body:
I've attached my LCD Display (AV1624YRB-SJ) to my Arduino Nano on the following pins:

    #define LCD_RS 7
    #define LCD_ENABLE 8
    #define LCD_D4 9
    #define LCD_D5 10
    #define LCD_D6 11
    #define LCD_D7 12
    #define LCD_CONTRAST 6 //PWM Wave with capacitor for contrast

and im initializing it this way:

    LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_D4, LCD_D5, LCD_D6, LCD_D7);

    byte arrow[8] = {
        B00000, B00100, B00010, B11111, B00010, B00100, B00000,
    };

    void setup() {
      pinMode(LCD_CONTRAST, OUTPUT);
      pinMode(LCD_D4, OUTPUT);
      pinMode(LCD_D5, OUTPUT);
      pinMode(LCD_D6, OUTPUT);
      pinMode(LCD_D7, OUTPUT);
      analogWrite(LCD_CONTRAST, STARTCONTRAST); // Set LCD Contrast

      lcd.begin(16, 2);
      lcd.createChar(CHAR_ARROW, arrow);
      lcd.setCursor(3, 0);
      lcd.print("Welcome To");
      lcd.setCursor(1, 1);
      lcd.print("My Test");
      delay(2000);
    }

The Problem is, that there is nothing to see on the display.
If i crank up the contrast slightly you can see something like a rolling shutter effect.

http://i.imgur.com/FOIEwVj.gif

The display worked just fine 3 days ago.
Where could be a mistake. I don't remember changing something, but i tried rewiring.

title: Serial LCD has like a "rolling shutter"

Answers: 1

body:
As I noted in a comment to the question  [Arduino LCD is displaying gibberish, sometimes](https://arduino.stackexchange.com/q/33578),  a PWM's sharp-cornered waveform might introduce a lot of noise into the LCD.  If you have to use PWM, you probably should put a good low-pass filter between PWM and LCD pin 3.

Check whether using a fixed voltage (from a voltage divider or pot) fixes the problem.  That fixed the problem in the case of the linked question.

If you need programmable control of contrast, and can't get PWM to work without heroic measures involving op-amp based filters, you could use a digital pot or a DAC.


body:
I have a simple photoresistor displaying values on a serial monitor every second so I can establish a value that I want to use to have it activate a relay.

It has worked fine for a few weeks, with bright sunlight values about 1000, total dark is 0. I soldered only the headers on a protoshield, and stacked it on the Arduino. I have nothing else on the protoshield and I am still using jumper wires to a breadboard, which I have not changed.

Why would the photoresistor values drop to approximately 40 (from 900's) when I stack the second board on the Arduino?

title: Photoresistor value drops when board stacked on Arduino Uno

Answers: 2

body:
It should not happen.

I have changed this answer, because at first I read that the resulting value was changed by -40, but I think it drops from 900 to 40.

The shield is doing something, so it is not empty. Perhaps it shortcuts the AREF to GND. Perhaps you are reading an open input, and the sensor is at another analog pin. Perhaps the shield does something to the voltage pins.

A breadboard can have bad contacts. The shield can have bad contacts.

Be sure that the sensor is connected to the channel that you are reading. Measure the voltage at that analog input with a multimeter with and without the shield. Check the 5V, 3.3V and AREF pins with and without the shield.

body:
Does the proto-shield have any LEDs on it?

You were probably connected to a pin unknowingly.

How is resistance being measured? A voltage divider with an `analogRead()`?
Using a cheapo multimeter can cause problems.

Possibly, his proto-shield has some trace "wires" etched into it that were unseen, and he was connected to a floating pin or ground.

Or maybe the shield was shifted over one pin, and he wasn't connected to the pins he thought.


body:
So this is my basic circuit. Three voltage dividers: one 10k pot, 2 thermistors. Fan driver circuit using TIP120 (currently just driving an LED from the 3.3v source). Board is a Leonardo clone, circuits.io only had the Uno in their library. Edit: circuit is now more simplified.

Schematic:

[![bbw temp controller][1]][1]

reality:

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

When I adjust the pot, the ADC value of `airPinValue` changes, regardless of which analog input it is connected to. `meatPinValue` does not change. Swapping the inputs that `airTempPin` and `meatTempPin` are assigned to has no effect, `airTempPin` changes the same. Physically swapping the thermistors has no effect, nor does switching which input they connect to.

Code:

    #define potPin A0
    #define airTempPin A5

    int potValue = 0;
    int airPinValue = 0;
    int i = 0;

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

    void loop() {
      i++;
      potValue = analogRead(potPin);
      airPinValue = analogRead(airTempPin);
      if (i == 2000) {
        Serial.print(potValue);
        Serial.print(",");
        Serial.println(airPinValue);
        i = 0;
      }
    }

EDIT: much simplified code

EDIT v2.0 : I have now swapped out the board for an official Uno, as well as swapped everything to a different breadboard and a different Leonardo, with no change in behavior.

EDIT v3 : Corrected code sample. I have also dropped my DMM onto this, reading from the 5v rail to the voltage going to A2. With the pot set to 0 I see 2.401v from the divider, pot to max, same voltage, 2.401v.

EDIT v4: with only the pot and airTemp hooked up, still happens. Further DMM probing actually shows that this only happens when the pot and thermistor are both hooked up to the arduino. If either one is disconnected, the voltage being read by `airTempPin` is stable/correct. Once both are hooked up to the analog pins on the arduino, that's when the voltage at `airTempPin` goes off...

Also update diagram, pic, and code to match what I'm currently testing with.

EDIT v5 : This is some sort of analog bleed between the analog input ports. Not really sure how I can combat this :\

  [1]: https://i.stack.imgur.com/5hCqO.png
  [2]: https://i.stack.imgur.com/9HUqs.jpg

title: unexpected change of ADC value with multiple voltage dividers (thermistors and pot)

Answers: 4

body:
https://www.arduino.cc/en/main/arduinoBoardUno
> Vin. The input voltage to the Arduino/Genuino board when it's using an
> external power source (as opposed to 5 volts from the USB connection
> or other regulated power source). You can supply voltage through this
> pin, or, if supplying voltage via the power jack, access it through
> this pin.

Thisi not to be used as powersource for motor/LED whatever, this is input.

Use 5V instead, maybe this would solve the problem.

body:
    #define meatTempPin A0
    #define airTempPin A1

Your code says A0,A1 but the circuit and picture of the wires say A0,A2.

Since A1 doesn't appear to be connected, as you scan things, the ADC could be sampling and holding some voltage from the prior conversion of potPin.

Try this instead:

    #define meatTempPin A0
    #define airTempPin A2

body:
Moral of the story, the multiplexer was not switching between inputs quickly enough causing the odd reading, looking very much like bleed between the pins. By simply reading each analog input twice and only storing the value of the second reading, I was able to get a valid, stable, reading as expected.

    #define potPin A4
    #define airTempPin A0

    int potValue = 0;
    int airPinValue = 0;
    int i = 0;

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

    void loop() {
      i++;
      analogRead(potPin);
      potValue = analogRead(potPin);
      analogRead(airTempPin);
      airPinValue = analogRead(airTempPin);
      delay(10);
      if (i == 50) {
        Serial.print(potValue);
        Serial.print(",");
        Serial.println(airPinValue);
        i = 0;
      }
    }

body: You need to have a reference voltage for ADC the problem is that you are not setting the reference voltage for ADC.Change the code in setup where you add a analog reference voltage as internal or default according to your requirement.


body: I want Calculate the time since arduino started working for a period of one year using arduino uno and when the period is over flip a light on

title: Calculate the time since arduino started working for a year

Answers: 3

body:
The function millis counts up to about 50 days. However, you can make a software timer with millis of, for example, 1Hz. With a unsigned long that counts the seconds, it is easy to count a year.

It will not be reliable. When the power is off, it starts again. A RTC (Real Time Clock) with its own battery is better.

Are you a good software engineer ? How can you be sure that it will work ?

body:
Simplest solution would be to use `millis()`, but you will need to
somehow take care of the periodic rollover. Creating a lower frequency
software timer, as explained by Jot, is one solution. Another option is
to extend `millis()` to 64 bits:

    uint64_t millis64()
    {
        static uint32_t low32, high32;
        uint32_t new_low32 = millis();
        if (new_low32 < low32) high32++;
        low32 = new_low32;
        return (uint64_t) high32 << 32 | low32;
    }

You must call this function at least once every 49.7 days, otherwise it
will loose time. I would just call it on every loop iteration, like
this:

    const uint64_t ONE_YEAR = 365.25 * 86.4e6;  // Julian year

    void loop()
    {
        if (millis64() >= ONE_YEAR) {
            // do some stuff...
        }
    }

Besides the issue of a possible power failure, there is another caveat:
the Arduino Uno is clocked off a ceramic resonator. These are not very
accurate, and are typically specified to be within 0.5% of their nominal
frequency. This means that your “year” can be off by as much as
1.8 days. RTCs are clocked off a quartz crystal and are then far
more accurate. Ultimate accuracy could be achieved with a GPS receiver.

body: I would use a network card to talk to an NTP server. In setup(), fetch the time and save it to EEPROM if there's not one already saved. You can then ping the NTP server every day or every boot, comparing the saved date and responding as appropriate. This strategy avoids MCU timer slew, power-out milis() resets, and extra hardware (other than networking, which more and more projects have already anyway).


body:
I have a problem with the [Arduino Motor Shield R3][1] on an Arduino Uno. I Have a DC Motor on the A Channel and the Shield is connected to an external power source. When I reset the Arduino card the motor starts running by default until the pins are initialized.

This is really problematic for me because the motor is on a rail delimited by 2 switches, when a switch is reached the motor stops. When the motor moves during reset the value of the switches are not read yet, which causes the motor to go beyond the switch and be blocked afterwards.

When I reset the card I read the value of the 3 digital pins used to drive the motor :

 - pin 12 : Direction (DirA), HIGH motor foward, LOW motor running backward
 - pin 3 : Power (PwmA), HIGH motor running, LOW motor not running
 - pin 9 : Brake (BrakeA), HIGH brake is on, motor can't run, LOW brake is off, motor can run

Before reseting I put the 3 pins at HIGH, At reset, pin 12 == HIGH, pin 9 == LOW, pin 3 == HIGH
which means that the brake is disengaged but the Power is still here, so the motor starts running again until the pinMode function is reached. During that reset time of approximately 2 seconds, the motor has the time to go beyond the switches which causes the system to break.

**Is this normal ? Is there a way to force the pin 3 to be at LOW when the Arduino resets ?** I put my code at the bottom.

**Naïve solution** : is to put PwmA at LOW when a switch is reached, so I'm sure it will stay that way until the next reset. But if the arduino is reseted while the motor is running I still have the problem.

    int closeSwitch = A3;
    int openSwitch = A2;
    int DirA = 12;
    int PwmA = 3;
    int BrakeA = 9;

    int OpeningDirection = LOW;
    int ClosingDirection = HIGH;

    bool motorRunning = false;
    bool motorOpening = false;
    bool openSwitchReached = false;
    bool closeSwitchReached = false;

    void setup() {

      Serial.begin(9600);

      sendToPC("Init\n"); //This is just to read the init state of the pins
      Serial.print(digitalRead(DirA));
      Serial.print(digitalRead(BrakeA));
      Serial.print(digitalRead(PwmA));

      pinMode(openSwitch, INPUT);//is High when Hublot opened
      pinMode(closeSwitch, INPUT); //is HIGH when hublot closed
      pinMode(DirA, OUTPUT); //Initiates Motor Channel A pin
      pinMode(BrakeA, OUTPUT); //Initiates Brake Channel A pin
      pinMode(PwmA, OUTPUT); //Initiates Brake Channel A pin

      sendToPC("\nAfter\nA:"); //After init all is LOW
      Serial.print(digitalRead(DirA));
      Serial.print(digitalRead(BrakeA));
      Serial.print(digitalRead(PwmA));

      //Stopping the motor
      setMotorSpeed(0);
      if (digitalRead(BrakeA) == LOW) {
        brakeMotor();
      }

      //Is the first switch on
      openSwitchReached = (digitalRead(openSwitch) == HIGH);
      //Second switch state
      closeSwitchReached = (digitalRead(closeSwitch) == HIGH);

      handleSerialInput(-3); //Send ping return
      handleSerialInput(-2); //Send status
    }

    void sendToPC(const char * str) {
      Serial.write(str);
      delay(215); //Delay to avoid answers being read as one
    }

    void setMotorSpeed(int speed) {
      if (speed > 0)
        digitalWrite(BrakeA, LOW);   //Disengage the Brake for Channel A
      digitalWrite(PwmA, HIGH);   //Spins the motor on Channel A at full speed
    }

    void setMotorDirection(int direction) {
      digitalWrite(DirA, direction); //Establishes direction of Channel A
    }

    void brakeMotor() {
      digitalWrite(BrakeA, HIGH);
      //digitalWrite(PwmA, LOW); -> this is my naïve solution
    }

    void handleSerialInput(int input) {
      Serial.print(input);
      if (input == 1 && !openSwitchReached) { //open
        brakeMotor(); // stop motor
        delay(100);
        setMotorDirection(OpeningDirection);
        setMotorSpeed(255); // set motor max speed
        motorRunning = true;
        motorOpening = true;
        sendToPC("HublotOpening");
      }
      else if (input == 2 && !closeSwitchReached) { //close
        brakeMotor(); // stop motor
        delay(100);
        setMotorDirection(ClosingDirection);
        setMotorSpeed(255); // set motor max speed
        motorRunning = true;
        motorOpening = false;
        sendToPC("HublotClosing");
      }
      else if (input == -2) { //get status
        if (openSwitchReached)
          sendToPC("HublotOpened");
        else if (closeSwitchReached)
          sendToPC("HublotClosed");
        else if (motorRunning && motorOpening)
          sendToPC("HublotOpening");
        else if (motorRunning && !motorOpening)
          sendToPC("HublotClosing");
        else if (!motorRunning)
          sendToPC("HublotNotMoving");
      }
      else if (input == -3) //Ping
        sendToPC("ArduinoHublot");
      else if (input == 0) { //Stop
        brakeMotor(); // set motor max speed
        motorRunning = false;
      }
      else {
        sendToPC("WTF");
        Serial.print(input);
      }
    }

    void loop() {

      openSwitchReached = (digitalRead(openSwitch) == HIGH);
      closeSwitchReached = (digitalRead(closeSwitch) == HIGH);

      if (openSwitchReached && motorRunning && motorOpening) {
        sendToPC("HublotOpened");
        brakeMotor();
        motorRunning = false;
        delay(200);
      }
      else if (closeSwitchReached && motorRunning && !motorOpening) {
        sendToPC("HublotClosed");
        brakeMotor();
        motorRunning = false;
      }

      if (Serial.available()) {
        int read = (Serial.readStringUntil(':')).toInt();
        handleSerialInput(read);
      }

    }

  [1]: https://www.arduino.cc/en/Main/ArduinoMotorShieldR3

title: Motor running during Motor Shield R3 reset

Answers: 1

body:
Add pulldown resistors (10KΩ) to any pins you want to force to be low at reset.

(Quite frankly I'm amazed they don't exist on all inputs to the board by default - it seems a bit of a fatal omission).


body:
I am using a piezo buzzer and fiddling around with it a little bit. I currently have different tones with delays in between and I have to do a lot of trial and error for the piezo buzzer to play sounds like I want it to. Is there a better way to do this? because at this rate I will be stuck for a while.

I am trying to get the piezo buzzer to make the sound of an alarm. Any suggestion on how I can get it to sound exactly like an alarm or is trial and error the only way?

title: How do I make specific tones with a piezo buzzer?

Answers: 1

body:
It's very hard to know from your question what you are having trouble with.  I have a piano and I can hit the keys, but it takes me a long time to hit them in the right order and with the right timings to create a new symphony.

Anyway, if creating the sounds is the problem, have you looked at the [Tone library][1]?

Different alarms have different sounds.  I once heard an alarm which sounded like the start of [Fuer Elise][2], so probably the [notes][3] were `E` and `D#`.  That would make their [frequencies][4] about 330Hz and 311Hz:

    void loop()
    {
        tone(pin, 330, 250);
        delay(300);
        tone(pin, 311, 250);
        delay(300);
    }

The sound you [linked to][5] sounds to me like it starts on a C, and slides up gradually one octave.  One octave higher is double the frequency, so this code should do that:

    void loop()
    {
        const int startFreq = 523;  // C5 is 523Hz

        // Start at the given freqency, and increase gradually by
        // one octave (double the frequency)
        for (int freq=startFreq ; freq<= (startFreq*2) ; ++freq)
        {
            tone(pin, freq, 10);
            delay(3);
        }
    }

  [1]: https://www.arduino.cc/en/Reference/Tone
  [2]: https://www.youtube.com/watch?v=_mVW8tgGY_w
  [3]: http://makingmusicfun.net/images/thumbs/fur-elise.jpg
  [4]: http://www.phy.mtu.edu/~suits/notefreqs.html
  [5]: https://www.youtube.com/watch?v=lo4yJbjkMWA


body:
Please check the arduino program given below and help me to find out error. The program is for following hardware. GSM 800 module Arduino Uno board Limit switch(2)

We place two limit switch at main door & back door as main door is open the message will be send that is Main door is open & when it closed it will send message Main door is closed. This is same for Back door also.

We run this program & it run but it sends the massage repeatedly after some time. Please help me to find out error..

        const int Main = 7;
        const int Store = 8;
        const int Main_led =  13;
        const int Store_led =  14;
        bool i = false;
        bool j = false;
        bool k = false;
        bool l = false;
        int buttonState1 = 0;
        int buttonState2 = 0;
        void setup() {

          Serial.begin(9600);
          pinMode(Main_led, OUTPUT);
          pinMode(Store_led, OUTPUT);
          pinMode(Main, INPUT);
          pinMode(Store, INPUT);
        }

        void loop() {
          buttonState1 = digitalRead(Main);
          if (buttonState1 == HIGH && i == false ) {
            digitalWrite(Main_led, HIGH);
            Serial.println("OK");
            delay(1000);
            Serial.print("AT+CMGF=1\r\n");
            delay(500);
            Serial.print("AT+CMGS=\"+91-------------");
            Serial.print("\"\r\n");
            delay(5000);
            Serial.print("Main Door is closed");
            Serial.write(0x1A);
            delay(5000);
            i = true;
            j = false;
          }
          else
          { if (buttonState1 == LOW && j == false )

            { digitalWrite(Main_led, LOW);
              Serial.println("OK");
              delay(1000);
              Serial.print("AT+CMGF=1\r\n");
              delay(500);
              Serial.print("AT+CMGS=\"");
              Serial.print("+91---------------");
              Serial.print("\"\r\n");
              delay(5000);
              Serial.print("Main Door is open");
              Serial.write(0x1A);
              delay(5000);
              i = false;
              j = true;
            }
          }

          buttonState2 = digitalRead(Store);
          if (buttonState2 == HIGH && k == false) {

            digitalWrite(Store_led, HIGH);
            Serial.println("OK");
            delay(1000);
            Serial.print("AT+CMGF=1\r\n");
            delay(500);
            Serial.print("AT+CMGS=\"");
            Serial.print("+91-------------");
            Serial.print("\"\r\n");
            delay(5000);
            Serial.print("Store room is Closed");
            Serial.write(0x1A);
            delay(5000);
            k = true;
            l = false;
          }
          else
          { if (buttonState2 == LOW && l == false)
            {
              digitalWrite(Store_led, LOW);
              Serial.println("OK");
              delay(1000);
              Serial.print("AT+CMGF=1\r\n");
              delay(500);
              Serial.print("AT+CMGS=\"");
              Serial.print("+91------------------");
              Serial.print("\"\r\n");
              delay(5000);
              Serial.print("Store room is Open");
              Serial.write(0x1A);
              delay(5000);
              k = false;
              l = true;
            }
          }
        }

title: door protector using arduino uno and GSM sim800 module

Answers: 0


body:
    const int pingPin = A0;

    void loop() {
      long duration, inches, cm;
      pinMode(pingpin, OUTPUT);
      digitalWrite(pingPin, LOW);
      delayMicroseconds(2);
      digitalWrite(pingPin, HIGH);
      delayMicroseconds(5);
      digitalWrite(pingPin, LOW);
      pinMode(pingPin, INPUT);
      duration = pulseIn(pingPin, HIGH);
      inches = microsecondsToInches(duration);
      cm = microsecondsToCentimeters(duration);
      Serial.print(inches);
      Serial.print("in, ");
      Serial.print(cm);
      Serial.print("cm");
      Serial.println();
    }

How to change this code for a 4-pin ultrasonic sensor?

title: How to use a 4-pin ultrasonic sensor as a 3-pin ping sensor?

Answers: 1

body:
The four pin `Echo)))` module is basically the same as three pin ones, except for triggering is done by another pin. So you don't have to care about setting pin to the output mode and switching it back to the input mode after the trigger pulse. You can read about it for example [here][1].

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

    const int8_t pingPin = A0;
    const int8_t trigPin = A1;

    void setup()
    {
      pinMode(pingPin, INPUT);
      pinMode(trigPin, OUTPUT);
    }

    void loop()
    {
      // pulse on trigger pin:
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10); // 10us is minimum trigger pulse duration
      digitalWrite(trigPin, LOW);

      // measure HIGH pulse duration:
      long duration = pulseIn(pingPin, HIGH);

      // and rest of the code:
      long   inches = microsecondsToInches(duration);
      long       cm = microsecondsToCentimeters(duration);

      Serial.print(inches);
      Serial.print("in, ");
      Serial.print(cm);
      Serial.print("cm");
      Serial.println();
    }

  [1]: https://alselectro.wordpress.com/tag/ultrasonic-sensors/