body:
Using the WebServer example file I have been able to confirm that my arduino is connected to my local network and I can open the page in my browser. However any attempt at contacting addresses outside my own network fails. For example this simple script:

```c

    #include <SPI.h>
    #include <Ethernet.h>

    EthernetClient client;

    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    IPAddress ip(192, 168, 1, 25);
    IPAddress gateway(192, 168, 1, 1);
    IPAddress dns(8, 8, 8, 8);
    byte server[] = { 64, 233, 187, 99 }; // Google

    void setup() {
      Ethernet.begin(mac, ip, dns, gateway);
      Serial.begin(9600);
      delay(1000);
      Serial.println(Ethernet.localIP());
    }

    void loop() {
      if (client.connect(server, 80)) {
        Serial.println("connected");
        client.println("GET /search?q=arduino HTTP/1.0");
        client.println();
      } else {
        Serial.println("connection failed");
      }
    }
```

This consistently returns `connection failed`. The ethernet cable in the arduino has an active internet connection, albeit via a switch. My board is an arduino uno.

title: Ethernet shield connected to local network, not to internet

Answers: 1

body:
Find a server that doesn't automatically switch modes to https as google does.  If you put 64.233.187.99/search?q=arduino HTTP/1.0   in your browser you'll see that it switches to https.

If make the same request via the wget terminal app it fails.
```$ wget '64.233.187.99/search?q=arduino HTTP/1.0'
--2020-01-17 11:42:26--  http://64.233.187.99/search?q=arduino HTTP/1.0
Connecting to 64.233.187.99:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://www.google.com/search?q=arduino HTTP/1.0 [following]
--2020-01-17 11:42:26--  http://www.google.com/search?q=arduino HTTP/1.0
Resolving www.google.com... 172.217.4.132, 2607:f8b0:4007:80c::2004
Connecting to www.google.com|172.217.4.132|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2020-01-17 11:42:28 ERROR 403: Forbidden.
```

There should also be an error returned to the client object which you can print out for debugging the conection.

Change your code to print out the return value of the client.connect call like so
```
void loop() {
      int result = client.connect(server, 80);
      if (x) {
        Serial.println("connected");
        client.println("GET /search?q=arduino HTTP/1.0");
        client.println();
      } else {
        Serial.println("connection failed");
        Serial.println(x);  // print out the error
      }
    }
```
One last thing, you set your dns server to 8.8.8.8 which should generally be set to your gateway / router of 192.168.1.1.


body:
I have a weird problem. When I power an rc car motor through the 5v or the 3.3V arduino's outputs everything goes fine, while powering it through digitalPins does not work.
I'm testing digitalPins with a simple led Blink example. Leds work, the motor does not move. Shouldn't digitalWrite(pinNumber, HIGH) output 5volts? What is the difference between digitalWrite voltage and 5v board output voltage? It seems crazy to me that leds light up without problems but the motor remains motionless...

title: Powering an rc car motor with arduino

Answers: 1

body:
Never ever power a motor or anything, that needs that much power, through a digital output pin. The maximum rating is 40mA, though you should not draw more than 20mA continuously from it. Also there is an overall limit of 100mA over all digital pins together. If you are drawing more from the pins, first the voltage will drop immediately, since the pin cannot provide what you ask for. Then you can easily destroy the pins output hardware or the whole Arduino. For an LED you normally use a current limiting resistor, so that it does not draw too much current from the pin.

For anything with more current demands, you need some kind of driver, which will take the big current load of the microcontroller. The easiest driver is a transistor or MOSFET (to switch the motor on and off or to have different speeds). If you want the motor to spin in both directions, you need an H-bridge driver (effectively 4 transistors/MOSFETs).

Note: I'm talking about simple DC motors here. Other types of motors need other types of drivers.


body:
I have ordered a starter kit and received RFID reader is

> RFID-RC522

module with one card and tag now I need more RFID card for my project and I can't find the supported card type for my project please can any one tell me supported card types and if this card supports my device this is the card type

> tk4100 chip protocol ISO18000-2C 10 digital ID number

title: Does RFID-RC522 supoort tk4100 chip protocol ISO18000-2C 10 digital ID card?

Answers: 1

body:
The MFRC522 on your kit is designed to communicate with ISO/IEC 14443 A/MIFARE and NTAG cards.

Search for `Mifare Classic` or `Mifare Ultralight` or `NTAG213`, `NTAG216` ... cards.


body:
The gist of my issue is in the title. I have a cheap ebay SSD1306 128x64 display which I hooked up to my arduino, and checked the wiring at least 50 times and the address is correct, the display has the jumper set to 0x78 and the arduino (Nano with ATmega168) sees it on an i2c scanner as 0x3C which is expected.

Now I installed Adafruit's SSD1306 and GFX libraries and an OLED i2c library I found somewhere (can't find it, sorry. In the IDE it's called OLED_I2C) and ran both example codes (shortened Adafruit's to fit on a 168) and I can't get it to show anything. I've tried many things including trying the 128x32 code with no luck, not even missing every other line. I think the display works since it shows up in the scanner, does anyone have any idea what could be wrong? Thanks in advance

My shortened Adafruit code:

    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>

    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels

    // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
    #define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

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

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
        Serial.println(F("SSD1306 allocation failed"));
        for(;;); // Don't proceed, loop forever
      }

      // Show initial display buffer contents on the screen --
      // the library initializes this with an Adafruit splash screen.
      display.display();
      delay(2000); // Pause for 2 seconds

      // Clear the buffer
      display.clearDisplay();

      // Draw a single pixel in white
      display.drawPixel(10, 10, SSD1306_WHITE);

      // Show the display buffer on the screen. You MUST call display() after
      // drawing commands to make them visible on screen!
      display.display();
      delay(2000);
      // display.display() is NOT necessary after every single drawing command,
      // unless that's what you want...rather, you can batch up a bunch of
      // drawing operations and then update the screen all at once by calling
      // display.display(). These examples demonstrate both approaches...

      testdrawline();      // Draw many lines

      testdrawrect();      // Draw rectangles (outlines)
    }

    void loop() {
    }

    void testdrawline() {
      int16_t i;

      display.clearDisplay(); // Clear display buffer

      for(i=0; i<display.width(); i+=4) {
        display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);
        display.display(); // Update screen with each newly-drawn line
        delay(1);
      }
      for(i=0; i<display.height(); i+=4) {
        display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);
        display.display();
        delay(1);
      }
      delay(250);

      display.clearDisplay();

      for(i=0; i<display.width(); i+=4) {
        display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);
        display.display();
        delay(1);
      }
      for(i=display.height()-1; i>=0; i-=4) {
        display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);
        display.display();
        delay(1);
      }
      delay(250);

      display.clearDisplay();

      for(i=display.width()-1; i>=0; i-=4) {
        display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);
        display.display();
        delay(1);
      }
      for(i=display.height()-1; i>=0; i-=4) {
        display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);
        display.display();
        delay(1);
      }
      delay(250);

      display.clearDisplay();

      for(i=0; i<display.height(); i+=4) {
        display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);
        display.display();
        delay(1);
      }
      for(i=0; i<display.width(); i+=4) {
        display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);
        display.display();
        delay(1);
      }

      delay(2000); // Pause for 2 seconds
    }

    void testdrawrect(void) {
      display.clearDisplay();

      for(int16_t i=0; i<display.height()/2; i+=2) {
        display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE);
        display.display(); // Update screen with each newly-drawn rectangle
        delay(1);
      }

      delay(2000);
    }

title: SSD1306 recognized in I2C scaner, can't get it to display

Answers: 4

body:
I have some experience with the the screen you are using and I hope these tips can solve your problem.

 - Changing the Address in the code

The OLED display you are using uses what is called I2c or IIC protocol which is the abbreviation of "Inter Intergrated Circuit", here is it's Wikipedia page to read about [it][1].

The IIC communication has 7 bit address space, that means there is 127 distinctive address for example 0x3C,0x3D,0x38 etc....

Your display might have either the address 0x3C or 0x3D so you might try changing theses values until anything would show up.

 - Unhooking any other IIC device

Although you can hook many IIC devices but as was said in the comments it's better to unhook everything except it, to troubleshoot.

 - Correct voltage ?

You might know that some displays uses 3.3v or some uses 5v, but as it showed in the IIC scanner, I don't think  that is the problem in your case but you should consider it.

 - Try using other sketches

Well, I think that 99% of the problem lays in your code (sometimes happens to me), so I suggest using other library examples or completely other libraries, or if you would like to take the challenge open the datasheet for the ssd1306 and make your own library and codes.

I hope these tips will help you or any other viewer.

As a side note I am a student, so I completely will appreciate anybody editing the answer to make better or more clear.

  [1]: https://en.wikipedia.org/wiki/I²C?wprov=sfla1

body:
I copied your code and load to my display. It doesn't show anything. Here is the code that I had run successfully.

    #include <Adafruit_SSD1306.h>
    Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);

    void setup() {

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32

      display.display();
      delay(2000);

      display.clearDisplay();      //this line to clear previous logo
      display.setTextColor(WHITE); //without this no display
      display.print("Hello World!");//your TEXT here
      display.display();            //to shows or update your TEXT
    }

    void loop() {

     }

Good Luck,
Aung Myo Oo

body:
I tried researching a while after asking this question. Turns out changing OLED_RESET to -1 fixed it.

[![Photo][1]][1]

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

body:
The confusion about I2C address really comes from whether it's treated as a byte or 7-bit (MSB).

For example, on the OLED PCB, it's stated address I2C =  0x78, which is 0b_0111_1000 (I2C address write).

In the Adafruit Arduino SSD1306 library, it uses 7-bit I2C address, that 0x78 becomes 011_1100 (taking the 7-bit MSB) = 0x3C


body:
The [SevSeg][1] library by Dean Reading seems to have a keyword to control individual segments on SSD's. I am using four common cathode, single digit displays. Does anyone know how to program individual segments?

    #include "SevSeg.h";

    SevSeg sevseg;

    void setup() {
      // put your setup code here, to run once:

      byte numDigits = 4;
      byte digitPins[] = {2, 3, 4, 5};
      byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
      bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
      byte hardwareConfig = COMMON_CATHODE; // See README.md for options
      bool updateWithDelays = false; // Default 'false' is Recommended
      bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
      bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected. Then, you only need to specify 7 segmentPins[]

      sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins,
        resistorsOnSegments,
        updateWithDelays, leadingZeros, disableDecPoint);

    }

    void loop() {
      // put your main code here, to run repeatedly:

      sevseg.setSegments();
      //sevseg.setNumber(1234,0);
      //sevseg.setChars("");
      //sevseg.blank();
      sevseg.refreshDisplay();

    }

  [1]: https://github.com/DeanIsMe/SevSeg

title: How to control segments with SevSeg library

Answers: 1

body:
You can't with that library. The author has not provided any public methods that will do the job.

There are private methods (`segmentOn` and `segmentOff`) that might be usable, but you would have to modify the library to be able to access them.


body:
The task, in char, I get some data that I have to parse into parts.

In this case, I use strtok_r, which finds identifiers like

> "=", " ", "&"

**Code:**

    char payload[70] = "GET /wifi?ssid=MyWiFi&pass=123456789 HTTP 11";
    char *p;
    char *i;

    void setup() {
      Serial.begin(15200);
      Serial.println("Load");

      p = strtok_r(payload, "=", &i);
      // Get SSID
      p = strtok_r(NULL, "&", &i);
      Serial.println(p);

      p = strtok_r(NULL, "=", &i);
      // Get PASS
      p = strtok_r(NULL, " ", &i);
      Serial.println(p);
    }

    void loop() {}

**Result:**

> Load MyWiFi 123456789

This works, but as soon as I add the characters strtok_r works on to the ssid = or pass = value, it stops working, outputting the cropped data.

These characters can be in the name of any WiFi network or the generated password.

Tell me, are there strtok_r analogues, where instead of a single character I can insert a whole phrase?

For example, so that he finds the beginning of ssid by the tag "ssid=", and finishes before "pass=".

**Resolved.**

Thank you all for your help!

I studied both options from @Majenko and @user7761803. All of them came in handy in various parts of the code.

Perhaps someone will use the Regexp library to parse such data. Here is example:

        #include <Regexp.h>

        char payload[60] = "ssid=MyWifi&pass=ukLPm&I*uwlm HTTP";
        char ssid[25], pass[25];

        void setup() {
          ms.Target(payload);
          char match_result = ms.Match("ssid=(.*)&pass=(.*) H", 0);
          if(match_result == 1) {
           // Get SSID
           ssid = ms.GetCapture(regexp_var.buffer, 0);
           // Get PASS
           pass = ms.GetCapture(regexp_var.buffer, 1);
          }
        }

        void loop() {}

title: Is there an alternative to strtok_r in extracting words from char?

Answers: 2

body:
The normal way of parsing such complex strings in any language is to use *Regular Expressions*.

Normally these are pretty heavy-weight to use, but thankfully Nick Gammon has written [an Arduino implementation of regexp](https://github.com/nickgammon/Regexp).

body:
The function you are looking for is [`strstr()`](https://linux.die.net/man/3/strstr), which takes two strings, and returns a pointer to where the second string appears in the first (or `NULL` if it doesn't appear).

You could use it something like this:

```
void setup() {

    Serial.begin(15200);
    Serial.println("Load");

    char *p = strstr(payload, "ssid=");
    char *q = strstr(payload, "pass=");
    char *r = strstr(payload, " HTTP");

    char *ssid = NULL;
    char *pass = NULL;

    if (p == NULL || q == NULL || r == NULL) {
        // One or other (or both) missing - what to do?
    } else {
        *r = '\0'; // Terminate the last string

        // If this really is an HTTP query string, we don't know
        // if ssid or pass will be first
        if (p < q) { // Terminate the first string
            *(q - 1) = '\0';
        } else {
            *(p - 1) = '\0';
        }

        ssid = p + 5;
        pass = q + 5;

        Serial.println(ssid);
        Serial.println(pass);
    }
}
```

Note, however, that your `payload` string looks like an [HTTP query string](https://en.wikipedia.org/wiki/Query_string).

These are *defined* so that they are split at the `&` characters, and if a `&` needs to appear in one of the values, it should be *percent encoded* (where the `&` would appear as `&`, and would need to be decoded afterwards).

However, that wasn't your question...


body:
I am a beginner with Arduino. I wanted to make an Arduino obstacle avoiding. So I ordered last week an L293D Shield Motor Driver and I don't know if what I receive is a good item. The first picture is how it looks on the site and the second picture is what I got.

[![][1]][1]

[![][2]][2]

I saw that if you search for this motor you get results for both motors, but they are not the same. And I saw in this tutorial, this person using a motor like mine https://www.youtube.com/watch?v=ydDvoknlJ9M and then he switched to the motor in the first picture.

Questions: Are these motors the same? Should I request a return? If they are the same, how can I add the pins (as shown in the third picture?

[![][3]][3]

  [1]: https://i.stack.imgur.com/UWW0O.jpg
  [2]: https://i.stack.imgur.com/XfQ38.jpg
  [3]: https://i.stack.imgur.com/yTMUw.jpg

Again, I am a beginner and I would appreciate if someone can help me.

title: Arduino Obstacle Avoiding Shield controlor motor L293D

Answers: 1

body:
To complete @chrisl answer: Yes you need these pins to make the same robot as in the video. You can order them online and solder them (if you know how to solder and if you have the soldering material). Be careful with soldering ;)

For your information, the pins you circled in red are used to communicate with the Arduino pins A0 to A5, and provide +5V and GND. In the video, they are connected to the ultrasound sensor.

And please clarify what is your `motor`??? Do you mean the `Shield motor driver`? It is not the same. A `shield` is an eletronic board that you plug to your Arduino to do a specific task (control a motor, connect to wifi...). A `motor driver` is the electronic to control the motor. On your pictures, they are mainly the 3 components with 16 legs each.


body:
I'm using ESP32 to read an analog value of a liPo battery (3.7v-4.2v).

Since ESP32 DAC's is 3.3v I'm using a voltage divider ( 2x10K resistors ), to split bat's voltage into ESP's `GPIO36`. So far nothing new or not well documented on the web.

Using the voltage divider, splits the 4.0v into 1.97v (measured using a volt-meter). Battery's negative pole is connected to ESP's `Gnd` to get a common ground. `GPIO36` is connected to the 1.97v line ( and this value is tested using a volt-meter also on ESP's pin to make sure ).

I was expecting to get a digital value of 1.97 (2444 )

**BUT NO!**,

when using `analogRead(36)` I'm getting a digital value of `2180` which correlates to `2180/4095*3.3` = 1.75v.

1) I tried to make a 100 samples over time - to make sure it is not a power up issue. No change.

2) I tried to read its value during `loop()` and not `setup()`. No change.

Is DAC's resolution is that poor ( roughly 12% off ), or am I doing something wrong ?

title: Using ESP32 to measure vbat

Answers: 0


body:
I have an HM-10 BLE module connected to Arduino Leonardo. It forwards UART from my computer:

    #define btSerial Serial1

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

        while (!Serial) {
            delay(50);
        }

        Serial.println("Initialized on 9600");

        btSerial.begin(9600);
        while (!btSerial) {
            delay(50);
        }

        Serial.println("BT initialized on 9600");
    }

    void loop() {
        if (btSerial.available()) {
            Serial.write(btSerial.read());
        }

        if (Serial.available()) {
            btSerial.write(Serial.read());
        }
    }

In general, it works fine, but I've decided to flash it and sent `AT+SBLUP` command to it, and it's in flash mode now.

Later I've realized that I can't flash it because Parallels Desktop's COM forwarding does not work fine (I work on macOS).

And now I can't quit from the flash mode — it just does not respond to AT commands (however, `btSerial` is alive).

I've tried to reset the Arduino, disconnect BT for several minutes — it's still in flash mode. How to quit this mode?

title: How to quit flash mode on HM-10?

Answers: 0


body:
I've set up an ISR to trigger on the `RISING` edge of pin #2, but I find that if pin 2 is held high, the ISR triggers repeatedly.

Here's a trace of the voltage measured right at the pin:

[![Scope trace of voltage at pin 2][1]][1]

I can see a little bit of noise, but it shouldn't be enough to trigger multiple pulses. I've tried both `INPUT` and `INPUT_PULLUP` modes for the pin; behavior is the same.

```c++
constexpr byte kClockPin = 2;
constexpr byte kReadWritePin = 3;
constexpr byte kLedPin = 13;
constexpr int kNumAddressPins = 16;
constexpr byte kAddressPins[] = {/* MSB */52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22};
constexpr int kNumDataPins = 8;
constexpr byte kDataPins[] = {/* MSB */45, 43, 41, 39, 37, 35, 33, 31};

volatile bool dirty = false;
volatile uint8_t data = 0;
volatile uint16_t address = 0;
volatile bool read = false;

void setup() {
  // put your setup code here, to run once:
  pinMode(kClockPin, INPUT_PULLUP);
  pinMode(kReadWritePin, INPUT);
  for (byte pin : kAddressPins) {
    pinMode(pin, INPUT);
  }
  for (byte pin : kDataPins) {
    pinMode(pin, INPUT);
  }
  pinMode(kLedPin, OUTPUT);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(kClockPin), OnClock, RISING);
}

void loop() {
  // digitalWrite(kLedPin, digitalRead(kClockPin));
  if (!dirty) return;
  char output[15];
  sprintf(output, "x %c x", address, read ? 'r' : 'w', data);
  Serial.println(output);
  dirty = false;
  // digitalWrite(kLedPin, digitalRead(kClockPin));
}

void OnClock() {
  read = digitalRead(kReadWritePin);
  data = 0;
  for (byte pin : kDataPins) {
    data = (data << 1) + (digitalRead(pin) ? 1 : 0);
  }
  address = 0;
  for (byte pin : kAddressPins) {
    address = (address << 1) + (digitalRead(pin) ? 1 : 0);
  }
  dirty = true;
}

```

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

title: Why is this RISING interrupt repeatedly triggering?

Answers: 1

body:
Turns out the short answer is that I'm still not great at using an oscilloscope.

Longer version is that the noise was *very* visible at smaller time scales. A filter capacitor had come disconnected from the breadboard in a way that was hard to see, and that was causing a whole bunch of noise. Replacing it fixed the problem.


body:
I use a LCD display to display a not known size of text ( changes over time ). I wish to display it at the center of LCD ( 2X16 ).

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

      char t[16];
      char h[16];
      sprintf(t, "%.1f� %.0f%%", temperature,223, humidity);

Now, since I want to add additional data on a specific line and center it, I need to know it size. When using:

    sizeof(t)/(sizeof(t[0])

I get `16` which is the size determined and not its actual size.

How can I get the exact number of chars **used**?

title: How to get char array's length

Answers: 1

body:
The function I think you are looking for is `strlen` - STRing LENgth.

It counts the number of characters in a string up until it finds the "NULL" end of string marker.

    Serial.println(strlen(t));


body:
[Here's a post][1] which explained the communication standard.

I need to establish communication between multiple Arduino nano board. I have used SPI bus on one of the Arduino board for wireless communication and I2C bus for another device. It appeared that both I2C bus and SPI bus support multiple device. However, since I have used both I2C and SPI for different purpose, establish parallel communication with RX TX pins seemed to be the preferable choice.

**Question 1:**
[This post][2] provided a nice set up for I2C bus as master and slave. However, can one adjust the code in step 2 of master device with

     Wire.begin(n);
and change all the Arduino boards as master&slave devices, thus achieve parallel communication?

**Question 2:** I read [this post][3] where people mentioned RS 485. However, can one achieve parallel communication with RX and TX pin like the one used in Question 1, without using RS 485?

  [1]: https://electronics.stackexchange.com/questions/37814/usart-uart-rs232-usb-spi-i2c-ttl-etc-what-are-all-of-these-and-how-do-th
  [2]: https://www.instructables.com/id/I2C-between-Arduinos/
  [3]: https://arduino.stackexchange.com/questions/9709/how-to-have-an-arduino-communicate-with-3-other-arduinos

title: Parallel communication between multiple Arduino

Answers: 1

body:
parallel communication is possible using arduino you need to use the ports for example port A and then a rx tx pins.
``` lang-cpp
#include <Wire.h>
#include <Arduino.h>

byte i = 0;
int intpin = 44;
int rcv_ready = 45;

void setup() {
  DDRA = B11111111; // Output
  DDRC = B11111111; // Output
  pinMode(intpin, OUTPUT);
  pinMode(rcv_ready, INPUT);
}

void loop() {
  transmit();
}

void transmit() {
  PORTA = i++
  PORTC = i;
  digitalWrite(intpin, HIGH);
  while (rcv_ready == LOW) {}
  digitalWrite(intpin, LOW);

  delay(299);
}
```
Here we set up the two ports DDRA and DDRC to be output ports by using the   mask B11111111; We set the interrupt pin to port 44 and set it is an output and we set the receive pin to be 45 and an input.
Then we call transmit in the loop. Where we then set port A and port C to equal i++ and i respectively. And then toggle the signal to say we have transmitted a new message. This will get picked up by the Slave-input.

Slave input
``` lang-cpp
#include <Arduino.h>

byte x = 0;
byte y = 0;
int rcv_ready = 45;

void setup() {
  DDRA = B00000000; // Input
  DDRC = B00000000; // Input
  Serial.begin(19200);
  attachInterrupt(5, blink, RISING);
  pinMode(rcv_ready, OUTPUT);
  digitalWrite(rcv_ready, LOW);
}

void loop() {}

void blink() {
  x = PINA;
  y = PINC;
  delay(100);
  digitalWrite(rcv_ready, HIGH);
  delay(100);
  digitalWrite(rcv_ready, LOW);
  Serial.print(x);
  Serial.print(" , ");
  Serial.println(y);
}
```
Here we set up the two ports DDRA and DDRC to be input ports by using the   mask B00000000;
 We then set the baud rate as 19200 which matches the rate set by the master

 Here we set the interrupt to be 5 which is pin 18 and tell it to call blink on an interrupt.
 We then read the values from PORTA and PORTC and then we output it to the serial monitor screen. We also send back the acknowledgement of receipt to the master using pin 45


body:
I want to know what's the default or recommended arithmetic to draw a circle on the LCD128x64 using ST7920 driver.

I've done the following functions:

 1. drawing a pixel at any point on the LCD
 2. sending an image
 3. drawing a vertical, diagonal and horizontal lines
 4. send CGRAM chars

But I can't draw a circle.

Here's my code:

    /* Project name:  lcd128x64
  Author:    r1s8k
  Date:    22/12/2019, 12:25 AM

  Project specs:  This is the source file of the lcd128x64 driver that uses
       MCP23017 as the lcd driver using SPI interface

 */

 #include <avr/io.h>
 #include <Arduino.h>
 #include <SPI.h>
 #include <avr/pgmspace.h>
 #include <math.h>
 #include "lcd128x64_spi.h"

 ////////////////////////////////////////////////////////////////////////////////////////////
 // global variables
 static uint8_t graphics, horizontal,y_pre,p_dr_act,block_pre;
 //static uint16_t p_buf;
 static uint16_t p_pre;
 uint8_t p_hi,p_lo,p_block,p_pos,p_bit;

 ////////////////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////////////////
 // control functions

 // init
 void lcd128x64_init(void){
  pinMode(CS_PIN, OUTPUT);
  pinMode(CLK_PIN, OUTPUT);
  pinMode(MOSI_PIN, OUTPUT);
  digitalWrite(CS_PIN, LOW);       // disable CS_PIN
  SPI.begin();
  _delay_ms(100);          // trying initial delay
  digitalWrite(CS_PIN, HIGH);       // enable CS_PIN

  _delay_ms(50);          // datasheet says > 40ms
  lcd128x64_cmd(FUNCTION_SET_BASIC); //_delay_us(28);// datasheet says > 100us - 72 = 28us
  lcd128x64_cmd(FUNCTION_SET_BASIC); //_delay_us(28);// important for going to / coming back from graph mode
  lcd128x64_cmd(DISABLE_V_SCROLL);     // if you have extended list to scroll
  lcd128x64_cmd(DISPLAY_CONTROL);  //_delay_us(28);// display = 1, cursor = 0, blink = 0
  lcd128x64_cmd(ENTERY_MODE);       // cursor = right, display shift = 0

  lcd128x64_cmd(DISPLAY_CLEAR);
  lcd128x64_cmd(RETURN_HOME);
  graphics = 0;
  horizontal = 0;
 }
 // command tx
 void lcd128x64_cmd(uint8_t cmd){
  SPI.transfer(CMD_MSK);
  SPI.transfer(cmd & 0xf0);
  SPI.transfer(cmd << 4);
  if(cmd == 0x01)_delay_us(1600); else _delay_us(72);
 }
 // data tx
 void lcd128x64_data(uint8_t data){
  SPI.transfer(DATA_MSK);
  SPI.transfer(data & 0xf0);
  SPI.transfer(data << 4);_delay_us(72);
 }
 // move cursor
 void lcd128x64_move_cursor(uint8_t row, uint8_t col){
  if  (row == 1)lcd128x64_cmd(0x80 + (col - 1));
  else if (row == 2)lcd128x64_cmd(0x90 + (col - 1));
  else if (row == 3)lcd128x64_cmd(0x88 + (col - 1));
  else if (row == 4)lcd128x64_cmd(0x98 + (col - 1));
 }
 // clear lcd
 void lcd128x64_clr(void){
  uint8_t y,x;
  lcd128x64_graphics_set_mode(1);
  for(y=0;y<32;y++){
   for(x=0;x<8;x++){
    lcd128x64_cmd(0x80+y);lcd128x64_cmd(0x80+x);
    lcd128x64_data(0x00);lcd128x64_data(0x00);
   }
  }
  for(y=32;y<64;y++){
   for(x=0;x<8;x++){
    lcd128x64_cmd(0x80+y-32);lcd128x64_cmd(0x88+x);
    lcd128x64_data(0x00);lcd128x64_data(0x00);
   }
  }
 }
 // graphics mode
 void lcd128x64_graphics_set_mode(uint8_t mode){
  lcd128x64_cmd(FUNCTION_SET_EXTENDED);
  if(mode){
   lcd128x64_cmd(GRAPHICS_ON1);
   lcd128x64_cmd(GRAPHICS_ON2);
   graphics = GRAPH;
  }
  else{
   lcd128x64_cmd(GRAPHICS_OFF1);
   lcd128x64_cmd(GRAPHICS_OFF2);
   graphics = TEXT;
  }
 }
 // write chars
 void lcd128x64_write_chars(uint8_t row, uint8_t col, uint8_t *str, uint8_t w){
 // row1: 80H~8FH // row2: 90H~9FH // row3: 88H~AFH // row4: 98H~BFH
  if(graphics){lcd128x64_graphics_set_mode(0);}

  if  (row == 1)lcd128x64_cmd(0x80 + (col - 1));
  else if (row == 2)lcd128x64_cmd(0x90 + (col - 1));
  else if (row == 3)lcd128x64_cmd(0x88 + (col - 1));
  else if (row == 4)lcd128x64_cmd(0x98 + (col - 1));

  uint8_t i;
  for(i=0; i<w; i++){lcd128x64_data(str[i]);}
 }

 ////////////////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////////////////
 // draw functions

 // pixel set
 void lcd128x64_pixel_set(uint8_t y_axis, uint8_t x_axis){
  uint16_t p_buf;
  if(!graphics){lcd128x64_graphics_set_mode(1);}

  p_block = x_axis / 16;    // calculate x_axis block
  x_axis ^= 127;
  p_pos = (x_axis % 16);    // calculate the position of pixel in 16-bit
  p_buf = (1 << p_pos);    // set the bit

  if(!p_dr_act){
   p_dr_act = 1;     // set pixel draw activate flag
   y_pre = y_axis;     // copy y_axis current position
   block_pre = p_block;   // store the first block
  }

  if(block_pre != p_block){   // if block changed
   p_pre = 0;      // clear global pixel buffer
   block_pre = p_block;   // store new block,
  }         // to disable triggering this check

  if(y_axis == y_pre){
   p_pre |= p_buf;     // put current pixel in global buffer
   p_buf |= p_pre;     // put previous pixels in local buffer
  }
  else{        // when changing the row,
   y_pre = y_axis;     // copy new row position
   p_pre = 0;      // clear global buffer
   p_pre = p_buf;     // store the last pixel position
  }

  if(y_axis<32){
   lcd128x64_cmd(0x80+y_axis);
   lcd128x64_cmd(0x80+p_block);
   lcd128x64_data(p_buf>>8);
   lcd128x64_data(p_buf);
  }
  else{
   lcd128x64_cmd((0x80+y_axis)-32);
   lcd128x64_cmd(0x88+p_block);
   lcd128x64_data(p_buf>>8);
   lcd128x64_data(p_buf);
  }
 }
 // pixel clear
 void lcd128x64_pixel_clear(uint8_t y_axis, uint8_t x_axis){
  uint16_t p_msk;
  if(!graphics){lcd128x64_graphics_set_mode(1);}
  p_block = x_axis / 16;
  x_axis ^= 127;
  p_pos = (x_axis % 16);
  p_msk &= ~(1 << p_pos);

  if(y_axis<32){
   lcd128x64_cmd(0x80+y_axis);
   lcd128x64_cmd(0x80+p_block);
   lcd128x64_data(p_msk>>8);
   lcd128x64_data(p_msk);
  }
  else{
   lcd128x64_cmd((0x80+y_axis)-32);
   lcd128x64_cmd(0x88+p_block);
   lcd128x64_data(p_msk>>8);
   lcd128x64_data(p_msk);
  }
 }
 // draw image
 void lcd128x64_img(unsigned char *img){
  uint8_t y,x;
  if(!graphics){lcd128x64_graphics_set_mode(1);}

  for(y=0;y<32;y++){
   for(x=0;x<8;x++){
    lcd128x64_cmd(0x80+y);
    lcd128x64_cmd(0x80+x);
    lcd128x64_data(pgm_read_byte_near(&img[(y*16)+(x*2)]));
    lcd128x64_data(pgm_read_byte_near(&img[(y*16)+((x*2)+1)]));
   }
  }
  for(y=32;y<64;y++){
   for(x=0;x<8;x++){
    lcd128x64_cmd((0x80+y)-32);
    lcd128x64_cmd(0x88+x);
    lcd128x64_data(pgm_read_byte_near(&img[(y*16)+(x*2)]));
    lcd128x64_data(pgm_read_byte_near(&img[(y*16)+((x*2)+1)]));
   }
  }
 }

 // draw line
 void lcd128x64_line(uint8_t y0, uint8_t y1, uint8_t x0, uint8_t x1){
  uint8_t ih,iw,j,h,w,div;
  h = y1 - y0;
  w = x1 - x0;
  if(w>h){
   div = w/h;
   for(ih=y0,iw=x0;iw<x1;iw++){
    lcd128x64_pixel_set(ih,iw);
    if((iw%div)==(div-1)){ih++;}
   }
  }
  else{
   div = h/w;
   for(ih=y0,iw=x0;ih<y1;ih++){
    lcd128x64_pixel_set(ih,iw);
    if((ih%div)==(div-1)){iw++;}
   }
  }
 }

 // draw circle
 void lcd128x64_circle(uint8_t y, uint8_t x, uint8_t r){
  uint8_t py,px,d,f;
  if(y>x){
   //d = y/x;
   f=1;
   for(px=x,py=y-r;px<x+r;px++){
    lcd128x64_pixel_set(py,px);
    if(((px%f))==(r%f)){py++;f++;}
    //if((py%(d%f))==1){px++;f++;}
   }
  }
  else{
   d = x/y;
   for(py=y-r,px=x;px<x+r;px++){
    lcd128x64_pixel_set(py,px);
    if(((px%d))==(d-1)){py++;}
   }
  }
 }

title: Topic: How to draw a circle on LCD128x64?

Answers: 0


body:
    #include <SPI.h>
    #include <Ethernet.h>

    // Enter a MAC address for your controller below.
    // Newer Ethernet shields have a MAC address printed on a sticker on the shield
    byte mac[] = {my mac };
    char serverName[] = "api.weather.gov";

    // Initialize the Ethernet client library
    // with the IP address and port of the server
    // that you want to connect to (port 80 is default for HTTP):
    EthernetClient client;

    void setup() {
     // Open serial communications and wait for port to open:
      Serial.begin(9600);
       while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
      }

      // start the Ethernet connection:
      if (Ethernet.begin(mac) == 0) {
        Serial.println("Failed to configure Ethernet using DHCP");
        // no point in carrying on, so do nothing forevermore:
        while(true);
      }
      // give the Ethernet shield a second to initialize:
      delay(1000);
      Serial.println("connecting...");

      // if you get a connection, report back via serial:
      int ret = client.connect(serverName,443);
      if (ret==1) {
        Serial.println("connected");
        // Make a HTTP request:
        client.println("GET /stations/KGSO/observations/latest");
        client.println("accept: application/geo+json,*/*");
        client.println("user-agent: arduino, mymail@asdf.com");
        client.println("host: api.weather.gov");
        client.println();
      }
      else {
        // kf you didn't get a connection to the server:
        Serial.println("connection failed");
        Serial.println(ret);
        Serial.println(client.status());
      }
    }

    void loop()
    {
      // if there are incoming bytes available
      // from the server, read them and print them:

      if (client.available()) {
        Serial.print("\ngotsome\n");
        char c = client.read();
        Serial.print(c);
      }

      // if the server's disconnected, stop the client:
      if (!client.connected()) {
        Serial.println();
        Serial.println("disconnecting.");
        client.stop();

        // do nothing forevermore:
        while(true);
      }
    }

When I run this I get:

connecting...
connected

disconnecting.

Why don't I get data? I thought it was about the header info. But I looked at https://www.weather.gov/documentation/services-web-api#/ and it doesn't say it needs much.

title: Weather API Arduino

Answers: 1

body:
The Ethernet library doesn't support secure connection (so called SSL, but TLS now). To connect to a secure HTTP transport HTTPS the secure connection is necessary. The AVR MCU don't have the computing power to compute the security keys. And for less popular 32bit MCU nobody created a 'SSL' implementation for Ethernet library yet.

esp8266, esp32, MKR1010, Uno WiFi, Nano 33 IoT can do HTTPS, but all only over WiFi as far as I know.


body:
I want to get the image from the fingerprint module (https://makeradvisor.com/tools/fingerprint-sensor-module/) as a result of scanning. It is enough to have a single frame image. it would be good if the computer can get image the output image from the serial port (as in linescan camera example: https://www.youtube.com/watch?v=welv4w8B88g   https://www.tindie.com/products/ap_tech/tsl1401cl-linescan-camera/)

I am open to your suggestions if it can be done in another module.

title: Get image from Fingerprint module

Answers: 1

body:
Since all of these cheap fingerprint readers are similar you can find a compatible datasheet and just find the commands and descriptions there. However, I couldn't find a datasheet that would include a good description of the protocol. So the other option is to look at the protocot through the software SFGDemo which is apparently capable of getting an image of a fingerprint. Or to use [this][1] python package which apparently also can download the image.

  [1]: https://pypi.org/project/fpscanner/


body: I am doing a school project where I intend to measure the cafeteria line with motion sensors and the send that information with a WiFi module to a server. This is my first time using Arduino and I am not sure how many motion sensors does it support.

title: How many PIR Motion Sensors can I connect to my Arduino-Uno R3?

Answers: 1

body:
Most PIR sensors provide a simple relay output. That means they are nothing more than a switch as far as the Arduino is concerned.

You can connect hundreds of switches to an Arduino. With judicious use of diodes and a matrix arrangement you can hundreds with not many IO pins.  For example an 8x8 matrix of switches gives you 64 PIR sensors with just 16 IO pins.  For *n* pins you can have *(n/2)²* switches with a balanced (*n/2* by *n/2*) matrix.


body:
Say, I need to track a vehicle using Arduino and a (GPS+GSM) module.  Though GPS can be used to get Location of the Vehicle(and then sent using GSM), why would we even do it using GPS if we already have a GSM module. Can't GSM do both these tasks(getting location and sending it) . What's the use of using an extra module there?

I am new to network stuff, help me!

title: GSM+GPS modules

Answers: 1

body: The GSM module can estimate it's location based on cell tower triangulation but if you want a more accurate location then you need to use a GPS.


body:
I'm completely removing power from a DS3231 RTC module and my call to `rtc.lostPower()` is never hit when I reconnect everything. I'm also removing the battery, I left it overnight and it remembers the time just before I disconnected everything, but doesn't register a power loss. I'm using this with a D1 mini.

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

      if (!rtc.begin()) {
        Serial.println("Couldn't find RTC.");
        while (1); // while true
      }

      if (rtc.lostPower()) {
        Serial.println("RTC lost power, resetting time.");
        ConnectWiFi();
        GetNtpTime();
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        Serial.println("Time set after power loss");
      }
    }

title: RTC DS3231 Not resetting time on power loss

Answers: 0


body:
I’ve got mega 2560.
In my project serial port is used for communicating with PC.
However, I’d like to see debug info in serial monitor. Mega has a few hardware Serial ports. How to use one of them got extra serial monitor?

title: Multiple serial monitors with the same arduino mega

Answers: 2

body:
You need to connect one (or more) to your PC. To do that you would use a USB to TTL UART adaptor, like an FT232 board.

That will give you a new COM port that you can open with your terminal program of choice, though opening the Arduino "serial monitor" multiple times might be somewhat difficult.

body:
Use an USB to TTL Serial adapter. Wire it to one of the RX/TX pin pairs and in code use the corresponding Serial object Serial1, Serial2 or Serial3. Don't forget to wire Ground.

You can use some terminal program or Serial Monitor in Arduino IDE to communicate over the adapter. You can open a second instance of the Arduino IDE by starting it with the Desktop or menu shortcut. In this instance you can select a different port then the sketch upload port.

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

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


body:
I am doing a project, and I need an SD card. Everything worked well, but after a while when I read the SD card from my PC(Windows 10 64 bit, Intel Core), I found a file called `eecfbba=.@aa`. It's so big that it almost ate up one GB storage of my SD card. But when I tried to open it with notepad, notepad tells me that there is actually no such file, and asks me if I want to create it. I tried to delete it, but file explorer also told me there is no such file. What is it?

This is my code:
```c
#include <ArduinoJson.h>

// Version 0.20.1.19.3.7:
// 2020/01/19, 16:10, button record test, 7th version.

#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>
#include <Wire.h>
#include "RTClib.h"
//#include <string.h>

RTC_DS1307 rtc;
String strdoc;
char daysOfTheWeek[7][2] = {"su", "mo", "tu", "we", "th", "fr", "sa"};
#define SD_ChipSelectPin 10  // 如果使用 arduino nano 328 可使用Pin4

TMRpcm audio;
void setup() {
  audio.speakerPin = 8;
  Serial.begin(9600);
  pinMode(25, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  else
  {
    Serial.println("rtc started");
  }

  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD Fail");
    return;
  } else {
    Serial.println("SD OK");
  }

  audio.setVolume(6);
  audio.CSPin = SD_ChipSelectPin;

  StaticJsonDocument<200> doc;
  doc["sensor"] = "gps";
  doc["time"] = 1351824120;
  JsonArray data = doc.createNestedArray("data");
  data.add(48.756080);
  data.add(2.302038);
  serializeJson(doc, strdoc);
}
bool isrecording = false;
bool recordButtonPressed()
{
  return (digitalRead(25) == LOW);
}
bool playButtonPressed()
{
  return (digitalRead(7) == LOW);
}
void loop() {
  delay(200);
  // Below is the formatted datetime.
  DateTime now = rtc.now();
  // Below is the serialized datetime.
  String filename = (String)(now.unixtime() % 10000000) + ".j";
  //  Serial.println(filename);
  if (recordButtonPressed())
    if (!isrecording)
    {
      isrecording = true;
      audio.startRecording("test.wav", 16000, A0);
      Serial.println("stt");
    }
    else
    {
      isrecording = false;
      Serial.println("stp");
      audio.stopRecording("test.wav");
    }
  Serial.println("sdsad991===`=`");
  if (playButtonPressed())
  {
    audio.play("test.wav");
    Serial.println("ply");
  }
  String dataString = strdoc;
  if (!isrecording)
  {
    File dataFile = SD.open(filename, FILE_WRITE);

    if (!dataFile) {
      Serial.println(F("Failed to create file"));
    }
    else
    {
      dataFile.println(dataString);
      Serial.println("Wrote string.");
      dataFile.close();
      Serial.println("Closed file.");
    }
  }
  /* Please ignore this line */
  //  //    audio.play("test.wav"); break;audio.volume(1); break;audio.volume(0); break;audio.stopPlayback(); break;
}
```

P.S. I'm using Mega 2560, so MISO, MOSI, SCK and CS pins are different.(Which is 50,51,52,10).

Edit 2020/1/25, 14:15(Beijing Time) At 1/20 I have bigger problems. There are more and more big files. All of them are the same situation. For details, take a look at this photo(ignore selected files): [Imgur](https://i.stack.imgur.com/mAV1x.jpg) or 咱们中国人上不去imgur，用这个：[File-up（直接下载）](https://www.file-up.org/kbg7y8frdjtl)

title: Extra `eecfbba=.@aa` file in sd card

Answers: 1

body:
Thanks to @Juraj, I fixed the problem. Deleted those files by manually formatting the SD card.

_**This is not really the answer, you can see the answer in [this comment](https://arduino.stackexchange.com/questions/71901/extra-eecfbba-aa-file-in-sd-card#comment157026_71901) under the question.**_


body:
I have bough an LCD screen display TFT Touch Screen Board For Arduino UNO R3.

Aand the following commands are given to me for the initialization:

```
write_SPI_commond(0xFF);
write_SPI_commond(0xFF);
delay_nms(5);
write_SPI_commond(0xFF);
write_SPI_commond(0xFF);
write_SPI_commond(0xFF);
write_SPI_commond(0xFF);
delay_nms(10);

write_SPI_commond(0xB0);
write_SPI_data(0x00);

write_SPI_commond(0xB3);
write_SPI_data(0x02);
write_SPI_data(0x00);
write_SPI_data(0x00);
write_SPI_data(0x10);

write_SPI_commond(0xB4);
write_SPI_data(0x11);//0X10

write_SPI_commond(0xC0);
write_SPI_data(0x13);
write_SPI_data(0x3B);//
write_SPI_data(0x00);
write_SPI_data(0x00);
write_SPI_data(0x00);
write_SPI_data(0x01);
write_SPI_data(0x00);//NW
write_SPI_data(0x43);

write_SPI_commond(0xC1);
write_SPI_data(0x08);
write_SPI_data(0x15);//CLOCK
write_SPI_data(0x08);
write_SPI_data(0x08);

write_SPI_commond(0xC4);
write_SPI_data(0x15);
write_SPI_data(0x03);
write_SPI_data(0x03);
write_SPI_data(0x01);

write_SPI_commond(0xC6);
write_SPI_data(0x02);

write_SPI_commond(0xC8);
write_SPI_data(0x0c);
write_SPI_data(0x05);
write_SPI_data(0x0A);//0X12
write_SPI_data(0x6B);//0x7D
write_SPI_data(0x04);
write_SPI_data(0x06);//0x08
write_SPI_data(0x15);//0x0A
write_SPI_data(0x10);
write_SPI_data(0x00);
write_SPI_data(0x31);//0x23

write_SPI_data(0x10);
write_SPI_data(0x15);//0x0A
write_SPI_data(0x06);//0x08
write_SPI_data(0x64);//0x74
write_SPI_data(0x0D);//0x0B
write_SPI_data(0x0A);//0x12
write_SPI_data(0x05);//0x08
write_SPI_data(0x0C);//0x06
write_SPI_data(0x31);//0x23
write_SPI_data(0x00);

write_SPI_commond(0x35);
write_SPI_data(0x00);

//write_SPI_commond(0x36);
//write_SPI_data(0x00);

write_SPI_commond(0x0C);
write_SPI_data(0x66);

write_SPI_commond(0x3A);
write_SPI_data(0x66);

write_SPI_commond(0x44);
write_SPI_data(0x00);
write_SPI_data(0x01);

write_SPI_commond(0xD0);
write_SPI_data(0x07);
write_SPI_data(0x07);//VCI1
write_SPI_data(0x14);//VRH 0x1D
write_SPI_data(0xA2);//BT 0x06

write_SPI_commond(0xD1);
write_SPI_data(0x03);
write_SPI_data(0x5A);//VCM  0x5A
write_SPI_data(0x10);//VDV

write_SPI_commond(0xD2);
write_SPI_data(0x03);
write_SPI_data(0x04);//0x24
write_SPI_data(0x04);

write_SPI_commond(0x11);
delay_nms(150);

write_SPI_commond(0x2A);
write_SPI_data(0x00);
write_SPI_data(0x00);
write_SPI_data(0x01);
write_SPI_data(0x3F);//320

write_SPI_commond(0x2B);
write_SPI_data(0x00);
write_SPI_data(0x00);
write_SPI_data(0x01);
write_SPI_data(0xDF);//480

//write_SPI_commond(0xB4);
//write_SPI_data(0x00);
delay_nms(100);

write_SPI_commond(0x29);
delay_nms(30);

write_SPI_commond(0x2C);
```

These commands do not look like Arduino commands to me. I have placed them like this

```
#include <Arduino.h>
#include <SPI.h>

void setup()
{
    Serial.begin(9600);
    Serial.println("Test!");

    SPI.begin();

    write_SPI_commond(0xFF);
    write_SPI_commond(0xFF);
    delay_nms(5);
    write_SPI_commond(0xFF);
    write_SPI_commond(0xFF);
    write_SPI_commond(0xFF);
    write_SPI_commond(0xFF);
    delay_nms(10);

    write_SPI_commond(0xB0);
    write_SPI_data(0x00);

    write_SPI_commond(0xB3);
    write_SPI_data(0x02);
    write_SPI_data(0x00);
    write_SPI_data(0x00);
    write_SPI_data(0x10);

    write_SPI_commond(0xB4);
    write_SPI_data(0x11);//0X10

    write_SPI_commond(0xC0);
    write_SPI_data(0x13);
    write_SPI_data(0x3B);//
    write_SPI_data(0x00);
    write_SPI_data(0x00);
    write_SPI_data(0x00);
    write_SPI_data(0x01);
    write_SPI_data(0x00);//NW
    write_SPI_data(0x43);

    write_SPI_commond(0xC1);
    write_SPI_data(0x08);
    write_SPI_data(0x15);//CLOCK
    write_SPI_data(0x08);
    write_SPI_data(0x08);

    write_SPI_commond(0xC4);
    write_SPI_data(0x15);
    write_SPI_data(0x03);
    write_SPI_data(0x03);
    write_SPI_data(0x01);

    write_SPI_commond(0xC6);
    write_SPI_data(0x02);

    write_SPI_commond(0xC8);
    write_SPI_data(0x0c);
    write_SPI_data(0x05);
    write_SPI_data(0x0A);//0X12
    write_SPI_data(0x6B);//0x7D
    write_SPI_data(0x04);
    write_SPI_data(0x06);//0x08
    write_SPI_data(0x15);//0x0A
    write_SPI_data(0x10);
    write_SPI_data(0x00);
    write_SPI_data(0x31);//0x23

    write_SPI_data(0x10);
    write_SPI_data(0x15);//0x0A
    write_SPI_data(0x06);//0x08
    write_SPI_data(0x64);//0x74
    write_SPI_data(0x0D);//0x0B
    write_SPI_data(0x0A);//0x12
    write_SPI_data(0x05);//0x08
    write_SPI_data(0x0C);//0x06
    write_SPI_data(0x31);//0x23
    write_SPI_data(0x00);

    write_SPI_commond(0x35);
    write_SPI_data(0x00);

    //write_SPI_commond(0x36);
    //write_SPI_data(0x00);

    write_SPI_commond(0x0C);
    write_SPI_data(0x66);

    write_SPI_commond(0x3A);
    write_SPI_data(0x66);

    write_SPI_commond(0x44);
    write_SPI_data(0x00);
    write_SPI_data(0x01);

    write_SPI_commond(0xD0);
    write_SPI_data(0x07);
    write_SPI_data(0x07);//VCI1
    write_SPI_data(0x14);//VRH 0x1D
    write_SPI_data(0xA2);//BT 0x06

    write_SPI_commond(0xD1);
    write_SPI_data(0x03);
    write_SPI_data(0x5A);//VCM  0x5A
    write_SPI_data(0x10);//VDV

    write_SPI_commond(0xD2);
    write_SPI_data(0x03);
    write_SPI_data(0x04);//0x24
    write_SPI_data(0x04);

    write_SPI_commond(0x11);
    delay_nms(150);

    write_SPI_commond(0x2A);
    write_SPI_data(0x00);
    write_SPI_data(0x00);
    write_SPI_data(0x01);
    write_SPI_data(0x3F);//320

    write_SPI_commond(0x2B);
    write_SPI_data(0x00);
    write_SPI_data(0x00);
    write_SPI_data(0x01);
    write_SPI_data(0xDF);//480

    //write_SPI_commond(0xB4);
    //write_SPI_data(0x00);
    delay_nms(100);

    write_SPI_commond(0x29);
    delay_nms(30);

    write_SPI_commond(0x2C);
}

void loop(void)
{
    delay(1000);
}
```

and I get many errors like

```
error: ‘write_SPI_commond’ was not declared in this scope
```

Even fixing the typo to `write_SPI_command` does not work. I have no problem with using the default `SPI.transfer` of the Arduino library. But, I am wondering how to translate `write_SPI_commond` and `write_SPI_data` into a proper `SPI.transfer`?

title: SPI command versus data?

Answers: 2

body:
The “commands” provided by the vendor are not code meant to be copied
as-is. They are [pseudocode][]. If you need to know the real difference
between “write command” and “write data”, you have to look at the
datasheet of the interface chip.

See for example the [ILI9481][]. On pages 28–29 you can see a data
transfer mode compatible with SPI (type C interface, option 3). Here you
have to wire one digital output of the Arduino to the D/CX pin on the
interface chip. This pin is used to tell whether you are writing a
command (pin LOW) or data (pin HIGH).

[pseudocode]: https://en.wikipedia.org/wiki/Pseudocode
[ILI9481]: https://www.crystalfontz.com/controllers/Ilitek/ILI9481/144/

body:
To answer the question in the title "**SPI command versus data?**":

TLDR
----
Some SPI drivers will separate the data sent on the [COPI/PICO][1] lines into subsections to make it easier on the programmer.

SPI command versus data?
-----
I am currently working with the ESP32 myself and have come accross the more generic question of "**What is the difference between command and data when using SPI?**". After some reading around, I have come to the conclusion that certain SPI drivers will allow users to separate the generic data sent in SPI protocal into subsections such as ADDRESS, COMMAND, and ADDITIONAL_DATA. This is simply to make it easier for the programmer to understand what they are sending.

Not all applications will require the an ADDRESS, COMMAND, and ADDITIONAL_DATA. For example, some chips will have pre-programmed commands such as this [Inclinometer (SCA61T)][2] which then may or may not require ADDRESS and ADDITIONAL_DATA. But others, such as the [MAX7219][3] (which I am using), only require an ADDRESS and ADDITIONAL_DATA, no COMMAND.

Example
-----
Using the ESP32 SPI driver, I played around with setting the length of the command bits and address bits from 0 to some nonzero number as seen in the code snippet below.
```
spi_device_interface_config_t devcfg={
                .command_bits=4,           ///< Default amount of bits in command phase (0-16), used when ``SPI_TRANS_VARIABLE_CMD`` is not used, otherwise ignored.
                .address_bits=4            ///< Default amount of bits in address phase (0-64), used when ``SPI_TRANS_VARIABLE_ADDR`` is not used, otherwise ignored.
}
```
Then I specified the data to be sent in the command and address bits (along with the data to be sent in the tx buffer) as seen in the code below.

```
     char data[1]= {0x97};

            spi_transaction_t spi_trans={
                .cmd={0x05},          ///< Command data, of which the length is set in the ``command_bits`` of spi_device_interface_config_t.
                .addr={0x00},         ///< Address data, of which the length is set in the ``address_bits`` of spi_device_interface_config_t.
                .length=8,            ///< Total data length, in bits
                .rxlength=0,          ///< Total data length received, should be not greater than ``length`` in full-duplex mode (0 defaults this to the value of ``length``).
                .rx_buffer=data,      ///< Pointer to receive buffer, or NULL for no MISO phase. Written by 4 bytes-unit if DMA is used.
                .tx_buffer=data,      ///< Pointer to transmit buffer, or NULL for no MOSI phase

            };

```
where `spi_trans.cmd = {0x05}` with 4 bits length corresponds to a binary `0101`, `spi_trans.addr = {0x00}` with 4 bits length corresponds to a binary `0000`, and `spi_trans.tx_buffer = {0x97}` with 8 bits length corresponds to a binary `10010111`.

When using an o-scope to measure the chosen COPI and clock pins, we see the following waveform.

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

We realize the ordering of the data sent over the COPI pin is command, then address, and lastly tx data. This ordering may differ depending on which driver is used (I am using the [ESP32 SPI Master driver][4]).

  [1]: https://www.sparkfun.com/spi_signal_names?_ga=2.24794995.891517377.1639774114-1543916381.1637822354
  [2]: https://www.mouser.com/pdfdocs/tn15_spi_interface_specification.PDF
  [3]: https://www.mouser.com/datasheet/2/256/MAX7219_MAX7221-1513157.pdf
  [4]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html
  [5]: https://i.stack.imgur.com/s2ALa.png


body:
I am VERY new to this so please excuse any silly questions.

I am trying to run an FS90 micro servo in a sweeping motion until I receive a certain value from my Adafruit TCS34725 colour sensor. I currently have my loop set that it checks the colour sensor red value using an if statement and then performs a single sweep and then checks again. Rinse Repeat. Is there a way I can get it to check the sensor and stop mid sweep if there is a red colour change?

title: How to run my servo until an input is recieved?

Answers: 0


body: I would like to set a stopwatch timer that will determine how long an input is in a certain state before changing. I want to set it so that, depending on the output my code executes one of 2 switch cases. But my trouble comes in on setting a timer. Is there a function I could use? Or a method that somebody knows? The time that the input will be for each case is not fixed so I cannot use a delay.

title: How can I set a timer?

Answers: 3

body:
Even though you are not running an actual (complex) Operating System, you should adhere to common practices.  For an Arduino, you should, in many cases, avoid directly controlling the hardware so as to be compatible with as many existing libraries for your particular Arduino platform as possible.

Setting the timer directly (if you are using an official Arduino Uno which contains an Atmel328P processor the processor's timers are covered in section 14 of the [Atmel328P Specifications][1]) may cause unexpected results should you use a library which expects the timer to run without being altered.

Instead, consider using the [millis() function][2] built into the Arduino IDE.  The function returns the current number of milliseconds since the Arduino was powered up.  Record this value in your code.  Then, if you want to know if One Second has elapsed, get the new value of millis and subtract this saved value from it and see if it is greater than 1000.  When that is true, One Second has elapsed.

  [1]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
  [2]: https://www.arduino.cc/reference/en/language/functions/time/millis/

body:
<!-- language-all: lang-arduino -->

Use `micros()` ([reference page][1]) to obtain a microsecond timestamp, and `millis()` ([reference page][2]) to obtain a millisecond timestamp.

Full Disclosure: I link to a library I maintain in my answer below, and I mention a few products (no links) I created with various techniques presented here in order to act as representative examples of when one approach might be preferred over another.

# Example 1: simple linear (synchronous) software timing measurement, including low-resolution (`micros()`) and high-resolution (`timer2.get_count()`)

In the simplest sense, **let's measure how long it takes to set an output pin HIGH and then LOW again:**

    void setup()
    {
        Serial.begin(115200);
        // I'll just leave pin 9 as an input; but uncomment the line below to make it an output
        // pinMode(9, OUTPUT);
    }

    void loop()
    {
        // Measure and print how many microseconds it takes just to set an output pin HIGH and then
        // LOW again.
        uint32_t time_start_us = micros();    // <=== START TIMESTAMP
        digitalWrite(9, HIGH);
        digitalWrite(9, LOW);
        uint32_t time_end_us = micros();      // <=== END TIMESTAMP
        uint32_t time_elapsed_us = time_end_us - time_start_us;
        Serial.print("time_elapsed_us = ");
        Serial.println(time_elapsed_us);
        delay(100);
    }

The really cool [ShowInfo][3] Arduino speed profiling sketch shows that Arduino's `digitalWrite()` function takes about 5us each, so expect the code above to print ~10us. Let's see if that's correct. I ran this on an Arduino Nano and got this output:

    time_elapsed_us = 8
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 8
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 8
    time_elapsed_us = 12
    time_elapsed_us = 8
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 12
    time_elapsed_us = 8

That's weird. Why only `8` or `12` us? Why not `10`? Or `9`? Or something else? Well, it turns out the Arduino `micros()` function only has a resolution of 4us, so it will actually print out either `8` or `12` us since those are multiples of 4 us. To get better resolution you'd have to modify the hardware timer registers, as I've done in my `eRCaGuy_Timer2_Counter` library, which has 0.5us-resolution. Full Disclosure: I wrote and maintain this library. It is free and open source, but I have it on my personal website, which has ads, and I solicit donations for downloads. A fully-functional snippet is also available in code at the bottom of that web-page without downloading anything.

Here is how to do the above code with my library:

    #include <eRCaGuy_Timer2_Counter.h>

    // Convert timer2 clock counts, which are 0.5us each, to us.
    float counts_to_us(uint32_t time_counts)
    {
        float time_us = (float)time_counts/2.0;
        return time_us;
    }

    void setup()
    {
        Serial.begin(115200);
        // I'll just leave pin 9 as an input; but uncomment the line below to make it an output
        // pinMode(9, OUTPUT);

        // Configure Timer2. This MUST be done before the other Timer2_Counter functions work.
        // Note: since this messes up PWM outputs on pins 3 & 11, as well as interferes with the tone()
        // library (http: arduino.cc/en/reference/tone), you can always revert Timer2 back to normal by
        // calling `timer2.unsetup()`
        timer2.setup();
    }

    void loop()
    {
        // Measure and print how many microseconds it takes just to set an output pin HIGH and then
        // LOW again.
        uint32_t time_start_counts = timer2.get_count();    // <=== START TIMESTAMP
        digitalWrite(9, HIGH);
        digitalWrite(9, LOW);
        uint32_t time_end_counts = timer2.get_count();      // <=== END TIMESTAMP
        uint32_t time_elapsed_counts = time_end_counts - time_start_counts;
        float time_elapsed_us = counts_to_us(time_elapsed_counts);
        Serial.print("time_elapsed_us = ");
        Serial.println(time_elapsed_us);
        delay(100);
    }

Now look at the output. Here's the more accurate and precise results with my `eRCaGuy_Timer2_Counter` library. Much better! But why those spurious 14.50us values I have marked with `<===`? Why are they off by 4us? I will explain below.

    time_elapsed_us = 10.00
    time_elapsed_us = 10.50
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 14.50  <===
    time_elapsed_us = 10.50
    time_elapsed_us = 10.50
    time_elapsed_us = 10.50
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 14.50  <===
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 10.50
    time_elapsed_us = 10.50
    time_elapsed_us = 10.50
    time_elapsed_us = 10.50
    time_elapsed_us = 10.00

The tradeoff of doing what Im doing is that you will get a 4us jitter introduced more often. Every time the 8-bit timer2 counter overflows, an ISR (Interrupt Service Routine) is called. This counts overflows to keep track of the 32-bit software timer from an 8-bit hardware counter. Entering this ISR takes about 4us, which means that if you try to grab a timestamp but then the ISR is called, you have to wait 4+us to get that timestamp, so it is off by that much. One of the several Arduino experts I really look up to, Nick Gammon, mentions this here in his [Interrupts](http://www.gammon.com.au/forum/?id=11488) article where he says, "There is a tweaking figure of 4 µS...". So, this 8-bit counter counts at 1 tick per 0.5us, which means it rolls over every 256 ticks * 0.5us/tick = 128us. So, every 128us you will have at least a 4us delay error introduced if you try to call the `timer2.get_count()` exactly when the ISR is called. If you get really unlucky you may even get this effect twice and be off by as much as 8us. When using the standard `micros()` function, since it rolls over only every 256 ticks * 4us/tick = 1024us, you get this 4us error effect 8x less frequently. That's the tradeoff of getting better resolution: you also get more-frequent 4+us jitter.

And just for kicks, here's a really bad one. Notice the `20.50`us value--off by 10.50us!

    time_elapsed_us = 15.00 <===
    time_elapsed_us = 10.50
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 15.00 <===
    time_elapsed_us = 10.50
    time_elapsed_us = 10.00
    time_elapsed_us = 20.50 <======
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 10.50
    time_elapsed_us = 10.00
    time_elapsed_us = 10.50
    time_elapsed_us = 10.50
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00
    time_elapsed_us = 10.00

Using mode filters, median filters, or other filters, these spurious results can be removed, at, of course, the cost of reduced frequency response to the thing being measured (all this means really is it takes multiple measurements to know the true value, just as we need to see with our eyes multiple measurements above to deduce 10.0us seems to be the right answer).

# Example 2: non-blocking (asynchronous) timing measurement of external event

**More-complicated Example: measure how long INPUT pin 9 is HIGH, and print out the HIGH time out each time it goes LOW again.**

In general, use this approach for any and all input events you need to measure at the 100us to ~200us resolution or larger level. You can use this on every single pin at once and get good results with resolutions around that level, depending really just on how long your main loop takes to run each iteration.

    constexpr uint8_t PIN = 9;

    void setup()
    {
        Serial.begin(115200);
        pinMode(PIN, INPUT);
    }

    void loop()
    {
        // This will measure how long `SOME_PIN` is HIGH, in microseconds.

        static uint32_t time_start_us = micros();
        bool time_just_acquired = false; // true if a new time value was just measured
        uint32_t time_elapsed_us = 0;

        bool pin_state = digitalRead(PIN);
        static bool pin_state_old = LOW;

        if (pin_state == HIGH && pin_state_old == LOW)
        {
            // The pin just barely went HIGH, so "start the timer" by obtaining a timestamp of the
            // start time
            time_start_us = micros();
            pin_state_old = pin_state; // update
        }
        else if (pin_state == LOW && pin_state_old == HIGH)
        {
            // The pin just barely went LOW, so "stop the timer" by obtaining a timestamp of the
            // end time
            uint32_t time_end_us = micros();
            pin_state_old = pin_state; // update
            time_elapsed_us = time_end_us - time_start_us;
            time_just_acquired = true;
        }

        // In some other place later down the code where you need this value,
        // you can use it like this. Here I just print the value.
        if (time_just_acquired)
        {
            time_just_acquired = false; // reset
            Serial.print("time_elapsed_us = ");
            Serial.println(time_elapsed_us);
        }
    }

_IMPORTANT: notice in all my examples above I use ONLY UNSIGNED INTEGER variables for timestamps. This is ESSENTIAL. Using **signed** integers for timestamps in the same way I've written them here would be a violation of the C standard because it will produce undefined behavior when you do subtraction which results in underflow, or when the integer has overflow. Using unsigned integers, however, is perfectly valid. Ex: `(uint8_t)0 - (uint8_t)1` = `255`, because it is an unsigned 8-bit integer which safely underflows from its lowest value back around to its highest value. Similarly, `(uint8_t)255 + (uint8_t)1` = `0` because it is an unsigned 8-bit integer which safely overflows from its highest value back around to its lowest value. This is how `time_elapsed_us = time_end_us - time_start_us` works in both of my examples as well. As the 32-bit microsecond counter overflows, which it will every 70 minutes or so, it wraps around back to 0. This means that sometimes `time_end_us` will be SMALLER than `time_start_us`, and you could end up with a measurement like this: `time_elapsed_us = 124 - 4294967295`, which equals `125`._

# Example 3: use external interrupts to detect changes on pins to measure external events

Use this approach when you need to measure external events at the 4~10us or larger resolution level on 2 pins maximum at a time.

This is a really good approach for measuring external events, but you get only 2 pins per Arduino Uno or Nano or similar that can do it. They are pins 2 or 3. See the table here: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/.

For a demo, see [Edgar Bonet's answer here](https://arduino.stackexchange.com/a/76992/7727).

# Example 4: use pin change interrupts to measure external events

Use this approach when you need to measure external events at the 4~10us or larger resolution level on > 2 pins maximum at a time.

These are like external interrupts except you have to manage up to 8 pins in a single interrupt service routine (ISR), instead of only 1 pin per ISR, so they aren't quite as good as "external interrupts". _Every single digital-capable pin on an Arduino Uno or Nano can do this._ I use this approach when reading many PWM signals from a radio control receiver, for instance, but it requires some sophistication and a ring buffer to do it right, as the time in the ISR *must* be minimized or else you get tons of jitter all over the place! That means you just grab the timestamp in the ISR, store it in a ring buffer, and exit. You do NOTHING ELSE! No subtraction, no math, no determining which pin fired, _nothing!_ You then process the ring buffer of timestamps and pin states in your main loop to determine which pin changed and do the math to obtain a new time reading on that pin. I used this for passing signals through a fire-shooting battlebots hexacopter that flew on ABC TV. It worked well. It made me happy to see the ISR do its job.

# Example 5: use input capture (on pin 8 *only*) to measure an external event

This is the "golden", or "best" approach. But, you get 1 pin per Arduino Uno or Nano that can do it. Use this approach when you need to measure external events at the 62.5 _nanosecond_ or larger resolution level **jitter-free**. There will be NO ISR TIMESTAMP DELAY WHATSOEVER with this approach, which is really cool.

Input Capture is only available on 16-bit timers on the 8-bit AVR microcontrollers such as the ATmega328. Since an Uno or Nano only has 1 16-bit timer, this means they get 1 single input capture pin. It is pin 8. Don't waste this pin for anything else if you need perfect time measurements of external events using input capture. Input capture is the "perfect" way to measure external events since it stores the time count in a hardware register at the moment the event happens, without CPU interaction through an ISR, which, as we know, would cause a delay and 4+us jitter.

I first did this on a commercial product I made which needed to read a single Radio Control receiver PWM pin. It made me happy to see it work right, as it has zero jitter. I'll come back and add a demo (code only, no more mention of the product) if I get a chance. This technique is also *perfect* for reading PPM (Pulse Position Modulation) signals, which are just a bunch of multiplexed Radio Control PWM signals.

  [1]: https://www.arduino.cc/reference/en/language/functions/time/micros/
  [2]: https://www.arduino.cc/reference/en/language/functions/time/millis/
  [3]: https://playground.arduino.cc/Main/ShowInfo/
  [4]: https://www.electricrcaircraftguy.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html

body:
Your title is about “setting a timer”, but your actual question is about
measuring the length of a pulse. There are two functions provided by the
Arduino IDE for this purpose, `pulseIn()` and `pulseInLong()`:

* [`pulseIn()`][pulseIn] is based on a carefully timed delay loop. It
  has a resolution of the order of one microsecond, but will not count
  the time spent servicing interrupt requests. It works best for very
  short pulses timed with interrupts turned off.
* [`pulseInLong()`][pulseInLong] is based on `micros()`. It has a
  resolution of 4 µs and will _not_ work properly if interrupts are
  turned off. It works best for longer pulses where its limited
  resolution and interrupt latency are tolerable.

Both of these are _blocking_ functions: they completely block your
sketch while they perform the measurement. If you don't want your sketch
to be unresponsive during this time, you can write a non-blocking
version of `pulseInLong()` using a [finite-state machine][FSM] like
this:

```cpp
// Measure the length of a pulse in a non-blocking manner.
// Returns 0 if no measurement is available at the time of the call.
void get_pulse_length() {
    static enum {
        INITIAL_WAIT,    // wait for the first (partial) pulse to end
        BETWEEN_PULSES,  // wait for the pulse to start
        WITHIN_PULSE     // wait for the pulse to end
    } pulse_state = INITIAL_WAIT;
    static uint32_t pulse_start;  // when the current pulse started

    uint8_t pin_state = digitalRead(pulse_pin);
    uint32_t now = micros();
    switch (pulse_state) {
        case INITIAL_WAIT:
            if (pin_state == LOW)
                pulse_state = BETWEEN_PULSES;
            break;
        case BETWEEN_PULSES:
            if (pin_state == HIGH) {
                pulse_start = now;
                pulse_state = WITHIN_PULSE;
            }
            break;
        case WITHIN_PULSE:
            if (pin_state == LOW) {
                pulse_state = BETWEEN_PULSES;
                return now - pulse_start;
            }
            break;
    }
    return 0;
}
```

Note that this measures high pulses. You will have to swap `HIGH` and
`LOW` if you want to measure low pulses. You would use it like this:

```cpp
void loop() {
    uint32_t pulse_length = get_pulse_length();
    if (pulse_length) {
        // handle the pulse
    }
}
```

The resolution of the measurement is the execution time of `loop()`, so
you have to make sure there is nothing blocking there, and specially no
calls to `delay()`. If you need a better resolution from a non-blocking
method, you can use interrupts to trigger the measuring process:

```cpp
volatile uint32_t pulse_start, pulse_length;
volatile bool pulse_valid;

void on_rise() {
    pulse_start = micros();
    attachInterrupt(digitalPinToInterrupt(pin), on_fall, FALLING);
}

void on_fall() {
    pulse_length = micros() - pulse_start;
    pulse_valid = true;
    attachInterrupt(digitalPinToInterrupt(pin), on_rise, RISING);
}

uint32_t get_pulse_length()
{
    if (!pulse_valid) return 0;
    noInterrupts();
    uint32_t pulse_length_copy = pulse_length;
    pulse_valid = false;
    interrupts();
    return pulse_length_copy;
}

void setup() {
    attachInterrupt(digitalPinToInterrupt(pin), on_rise, RISING);
}
```

This should give you the resolution of `micros()`, i.e. 4 µs, but
occasionally you may get results that are slightly off if interrupts
happen to be disabled when the input transitions. If this is
unacceptable, the only other options I see is to use a hardware timer
with _input capture_ capability. You will have to look at the datasheet
of your microcontroller to see how it works, and maybe do a Web search
for “Arduino input capture”.

[pulseIn]: https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/
[pulseInLong]: https://www.arduino.cc/reference/en/language/functions/advanced-io/pulseinlong/
[FSM]: https://majenko.co.uk/blog/finite-state-machine


body: A lot of tutorials are about how to control Arduino through WiFi, but I need my Arduino to send information about motion sensor activity to a server. Is that possible?

title: Can you make Arduino Uno send information through a WiFi module to a server?

Answers: 1

body:
> Can you make Arduino Uno send information through a WiFi module to a server?

Yes, I can.

The simplest way is through an HTTP "GET" request. Every time you request a web page (and there are plenty of examples of that) you are sending data to the server to tell it both what web page to get (`/foo/bar.php`) and what data to submit to that web page (`?baz=4`).

It's then up to you to craft that GET request, such as:

    GET /foo/bar.php?baz=4 HTTP/1.1
    Host: example.com
    Content-length: 0

and write the PHP web page (or whatever language you prefer to write web pages in) to do something meaningful with the "baz = 4" parameter.


body:
I simply hate the default Arduino "IDE".
On Windows I use Visual Studio Code with the related plugin.

Now I have a Ubuntu machine and I'm looking for the definitive IDE.
Questions:

1. I'm not sure whether to use VSC I need to install the default IDE as well
2. is there something better?

By the way, I also have QtCreator, PHPStorm, MPLAB X, STM32Cube (Eclipse based).

title: Latest news about alternative Arduino IDEs

Answers: 2

body:
I use the Arduino IDE to 'build' everything.

However, in case of a bigger project, I use a 'decent' code editor (Visual Studio in my case) to edit, and the Arduino IDE to build.

Also, because I prefer testing all non-Arduino related code on the PC (not on the Arduino), the Visual Studio (C++) project uses some stub classes I created (specifically for my project), and I can run the application on my PC.

When some part is finished, I can build the same code in Arduino IDE, but without the stubs (because these are acquired from Arduino.h and related Arduino files).

What IDE is best to 'edit' code is very subjective I think. But in the above way I can see many classes/files at a glance on the left side (and not in the top like Arduino IDE where only like 5 tabs fit on a screen), and to test lots of code on the PC already before sending it to an Arduino.

The GitHub repository can be found here: https://github.com/michelkeijzers/Mestra

Project inside is DmxLightShow.

body:
Arduino creators toughed of you.
Personally I use Geany, but you can use eclipse, but I find the Arduino plugin rather hostile, especially when it comes to editing default libraries (to add printf) and pointlessly complex serial monitor settings default above the NANO's range.
Although its missing testing feature without upload

Although most other editors would be quite happy with arduinos file too, but  you have to always create new project with native IDE.
You will find use external editor feature in Arduino-ide's settings in which case every time file is saved it gets immediately updated in Arduino's IDE, so you can use it for your tasting as a sub-window.


body:
I upload code into arduino nano using a self-made PCB with bluetooth using this [method][1]. I was initially using Arduino Nano (chinese Clone, the one with CH340G) and Bluetooth module HC-05 (version 3.0) (Lets assume this bluetooth is **BT1**)

**At command response for BT1**

    AT+NAME?
    +NAME:H-C-2010-06-01
    OK
    AT+POLAR?
    +POLAR:1:1
    OK
    AT+VERSION
    VERSION:3.0-20170601
    OK
    AT+UART?
    +UART:9600,0,0
    OK

All the things were working perfectly till the new nano as well as latest version of bluetooth arrived.

**Bluetooth problem:** I was trying to configure the newer bluetooth **BT2** and I faced the error highlighted in code.

**AT Commands response for BT2**

        AT+NAME?
        +NAME:HC-05
        OK
        AT+VERSION?
        +VERSION:4.0-20190815
        OK
        **AT+POLAR**
        **ERROR:[0]**
        AT+UART?
        +UART:9600,0,0
        OK

The problem I am facing is I am unable to change the state pin with AT+POLAR command. I think this version of bluetooth has different AT Commands. If anyone knows about this particular problem please help.

Also I tried uploading code using old bluetooth to a newer version of Arduino Nano (New bootloader OPTIBOOT) and it was successful. Needed to change the baud rate of program as well as Bluetooth to 115200.

  [1]: https://www.instructables.com/id/Arduino-Bluetooth-Programming/

title: Arduino Bluetooth upload problem HC-05 v4.0

Answers: 0


body:
I am trying to set the time on my DS3231, then read that time on my arduino nano. This is for a digital clock project. I am using DS3232 library by JChristensen.

He has an example that can set the DS3231 time through the serial monitor, and it works great, but I don't understand how to implement it into my sketch.

I can confirm that once the external RTC is set using said example, I can then upload my code, and the clock holds time when unplugged. It's setting the time within my sketch that I can't figure out. I've been at it for about 8 hours today and read through the github resources.

Here's my code. Towards the top you can see my attempt to set the system time, then set it to the RTC.

     #include "SevSeg.h";
        #include <DS3232RTC.h>; //Jack Christensen
        https://github.com/JChristensen/DS3232RTC
        #include <Streaming.h>; //Mikal Hart https://github.com/janelia-
         arduino/Streaming
        //Also requires time library https://github.com/PaulStoffregen/Time

        SevSeg sevseg;

        void setup() {
        // put your setup code here, to run once:

        //Serial.begin(9600);

        setSyncProvider(RTC.get);// the function to get the time from the RTC
        setTime(8,0,0,20,1,2020);
        time_t t = now();
        RTC.set(now());

         byte numDigits = 4;
         byte digitPins[] = {2, 3, 4, 5};
         byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12};
         bool resistorsOnSegments = false; // 'false' means resistors are on digit
         pins
         byte hardwareConfig = COMMON_CATHODE; // See README.md for options
         bool updateWithDelays = false; // Default 'false' is Recommended
         bool leadingZeros = false; // Use 'true' if you'd like to keep the leading
         zeros
         bool disableDecPoint = true; // Use 'true' if your decimal point doesn't
         exist or isn't connected. Then, you only need to specify 7 segmentPins[]

         sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins,
          resistorsOnSegments,
           updateWithDelays, leadingZeros, disableDecPoint);

        }

         void loop() {

        sevseg.setChars("hola");
        sevseg.refreshDisplay();

         if(millis()>6000) {

        int adj = 0;
        int timenumber;
        int hr = hourFormat12();
        int Min = minute();

        timenumber = (hr*100) + Min; //converts time into a number for the seven
        segment display

       sevseg.setNumber(timenumber);
       sevseg.refreshDisplay();
        }

        }

  And JChristensen's Example Code:

    // Arduino DS3232RTC Library
    // https://github.com/JChristensen/DS3232RTC
    // Copyright (C) 2018 by Jack Christensen and licensed under
    // GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
    //
    // Example sketch to display the date and time from a DS3231
    // or DS3232 RTC every second. Display the temperature once per
    // minute. (The DS3231 does a temperature conversion once every
    // 64 seconds. This is also the default for the DS3232.)
    //
    // Set the date and time by entering the following on the Arduino
    // serial monitor:
    //  year,month,day,hour,minute,second,
    //
    // Where
    //  year can be two or four digits,
    //  month is 1-12,
    //  day is 1-31,
    //  hour is 0-23, and
    //  minute and second are 0-59.
    //
    // Entering the final comma delimiter (after "second") will avoid a
    // one-second timeout and will allow the RTC to be set more accurately.
    //
    // No validity checking is done, invalid values or incomplete syntax
    // in the input will result in an incorrect RTC setting.
    //
    // Jack Christensen 08Aug2013

    #include <DS3232RTC.h>      // https://github.com/JChristensen/DS3232RTC
    #include <Streaming.h>      // http://arduiniana.org/libraries/streaming/

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

        // setSyncProvider() causes the Time library to synchronize with the
        // external RTC by calling RTC.get() every five minutes by default.
        setSyncProvider(RTC.get);
        Serial << F("RTC Sync");
        if (timeStatus() != timeSet) Serial << F(" FAIL!");
        Serial << endl;
    }

    void loop()
    {
        static time_t tLast;
        time_t t;
        tmElements_t tm;

        // check for input to set the RTC, minimum length is 12, i.e. yy,m,d,h,m,s
        if (Serial.available() >= 12) {
            // note that the tmElements_t Year member is an offset from 1970,
            // but the RTC wants the last two digits of the calendar year.
            // use the convenience macros from the Time Library to do the conversions.
            int y = Serial.parseInt();
            if (y >= 100 && y < 1000)
                Serial << F("Error: Year must be two digits or four digits!") << endl;
            else {
                if (y >= 1000)
                    tm.Year = CalendarYrToTm(y);
                else    // (y < 100)
                    tm.Year = y2kYearToTm(y);
                tm.Month = Serial.parseInt();
                tm.Day = Serial.parseInt();
                tm.Hour = Serial.parseInt();
                tm.Minute = Serial.parseInt();
                tm.Second = Serial.parseInt();
                t = makeTime(tm);
                RTC.set(t);        // use the time_t value to ensure correct weekday is set
                setTime(t);
                Serial << F("RTC set to: ");
                printDateTime(t);
                Serial << endl;
                // dump any extraneous input
                while (Serial.available() > 0) Serial.read();
            }
        }

        t = now();
        if (t != tLast) {
            tLast = t;
            printDateTime(t);
            if (second(t) == 0) {
                float c = RTC.temperature() / 4.;
                float f = c * 9. / 5. + 32.;
                Serial << F("  ") << c << F(" C  ") << f << F(" F");
            }
            Serial << endl;
        }
    }

    // print date and time to Serial
    void printDateTime(time_t t)
    {
        printDate(t);
        Serial << ' ';
        printTime(t);
    }

    // print time to Serial
    void printTime(time_t t)
    {
        printI00(hour(t), ':');
        printI00(minute(t), ':');
        printI00(second(t), ' ');
    }

    // print date to Serial
    void printDate(time_t t)
    {
        printI00(day(t), 0);
        Serial << monthShortStr(month(t)) << _DEC(year(t));
    }

    // Print an integer in "00" format (with leading zero),
    // followed by a delimiter character to Serial.
    // Input value assumed to be between 0 and 99.
    void printI00(int val, char delim)
    {
        if (val < 10) Serial << '0';
        Serial << _DEC(val);
        if (delim > 0) Serial << delim;
        return;
    }

title: Setting Time Function With DS3232 Library

Answers: 1

body:
I figured it out. You must first set the built in arduino RTC using the time library, then set the DS3232 from there. It did not work for my code before because it has to be called *outside* of the setup function.

For instance, I made a function that adjusts the hour:

    void adjHr() { //hour adjustment function

    if(millis() >= time_now + period){
            time_now += period;
            time_now = millis();
            setTime(hour()+1,minute(),second(),day(),month(),year());
            RTC.set(now());
        }

My setup function also includes:

    setSyncProvider(RTC.get);

Allows the code to get time from the DS3232.


body:
I am using mpu6050 for counting the twitch movement. The algorithm is counting the peak/twitch whenever it goes above the threshold value. Now, I want to add that the algorithm count twitch only when it goes above threshold value and all the twitch within 90s are counted as one twitch movement. Kindly help me with this. Also try to integrate this in my code.

**Here is the code:**

    #include "I2Cdev.h"
    #include "MPU6050.h"

    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        #include "Wire.h"
    #endif

    MPU6050 accelgyro;

    int16_t ax, ay, az;
    float threshhold=5000.0;
    float conmove=4;
    const int sampletime=90000;

    float xval[100]={0};
    float yval[100]={0};
    float zval[100]={0};
    float xavg;
    float yavg;
    float zavg;

    int twitch,flag=0;
    MPU6050 mpu6050;

    int16_t tr;          // raw temperature data register value
    char buffer[7];      // temporary string buffer; used with dtostrf() function
    #define OUTPUT_READABLE_ACCELGYRO

    #define LED_PIN 13
    bool blinkState = false;

    void setup() {

        // join I2C bus (I2Cdev library doesn't do this automatically)
        #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
            Wire.begin();
        #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
            Fastwire::setup(400, true);
        #endif

        Serial.begin(115200);

        // initialize device
        Serial.println("Initializing I2C devices...");
        accelgyro.initialize();
        mpu6050.initialize();  // initialize MPU6050 sensor module

        // verify connection
        Serial.println("Testing device connections...");
        Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

        pinMode(LED_PIN, OUTPUT);
        calibrate();
        delay(5000);
    }

    void loop() {

        accelgyro.getAcceleration(&ax, &ay, &az);
        tr = mpu6050.getTemperature();

        #ifdef OUTPUT_READABLE_ACCELGYRO
        +
            // display tab-separated accel/gyro x/y/z values
            Serial.print("a/g:\t");
            Serial.print(ax); Serial.print("\t");
            Serial.print(ay); Serial.print("\t");
            Serial.print(az);
        #endif

        #ifdef OUTPUT_BINARY_ACCELGYRO
            Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
            Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
            Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
        #endif

        // blink LED to indicate activity
        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
        int acc=0;
        float totvect[100]={0};
        float totave[100]={0};
        float xaccl[100]={0};
        float yaccl[100]={0};
        float zaccl[100]={0};

        for (int i=0;i<100;i++)
        {
            xaccl[i]=float(ax);
            delay(1);
            yaccl[i]=float(ay);
            delay(1);

            zaccl[i]=float(az);
            delay(1);

            totvect[i] = sqrt(((xaccl[i]-xavg)* (xaccl[i]-xavg))+ ((yaccl[i] - yavg)*(yaccl[i] - yavg)) + ((zval[i] - zavg)*(zval[i] - zavg)));
            totave[i] = (totvect[i] + totvect[i-1]) / 2 ;
            //acc=acc+totave[i];
            Serial.println(totave[i]);
            Serial.print("T = ");  Serial.print(dtostrf(tr/340.0+36.53, 5, 1, buffer));  Serial.println(" °C");

            // delay(200);

            //cal twitch
            if (totave[i]>threshhold && flag==0)
            {
                twitch=twitch+1;
                flag=1;
            }
            else if (totave[i] > threshhold && flag==1 )
            {
                //do nothing
            }
            if (totave[i] <threshhold  && flag==1 )
            {flag=0;}

            Serial.println('\n');
            Serial.print("twitch=");
            Serial.println(twitch);
        }

        //float tim=acc/100;
        //Serial.println(tim);
        delay(1000);
        // stepcal(totave);
    }

    void calibrate()
    {
        digitalWrite(13,HIGH);
        accelgyro.getAcceleration(&ax, &ay, &az);

        float sum=0;
        float sum1=0;
        float sum2=0;

        for (int i=0;i<100;i++)
        {
            xval[i]=float(ax);

            sum=xval[i]+sum;
        }
        delay(100);
        xavg=sum/100.0;

        Serial.println(xavg);

        for (int j=0;j<100;j++)
        {
            yval[j]=float(ay);

            sum1=yval[j]+sum1;
        }
        yavg=sum1/100.0;

        Serial.println(yavg);
        delay(100);
        for (int i=0;i<100;i++)
        {
            zval[i]=float(az);

            sum2=zval[i]+sum2;
        }
        zavg=sum2/100.0;
        delay(100);
        Serial.println(zavg);

        digitalWrite(13,LOW);
    }

title: How to add another condition in the loop?

Answers: 1

body:
You can do this with the `millis()` function. It returns the number of milliseconds since startup and can be used as a simple clock. Take the if statement, where you increment `twitch`:

    if (totave[i]>threshhold && flag==0)
    {
      if(millis()-last_twitch_timestamp > 90000){
        twitch=twitch+1;
        flag=1;
        last_twitch_timestamp = millis();
      }
    }

This will check, if at least 90 seconds (90000ms) have passed since the last registered twitch (time difference between the current time and the timestamp of the last twitch). If yes, it will register another twitch and reset the timestamp to the current time (return value of `millis()`). This deactivates twitch registering for 90s after each twitch.

For this to work, you need to define the `last_twitch_timestamp` variable at global scope:

    unsigned long last_twitch_timestamp = 90000;

I initialize the timestamp to 90000, so that the very first twitch can be registered. If you initialize it to zero, you would need to wait 90s, until the first twitch can be registered.

---

Btw: The following delays don't make any sense. You can remove them:

    xaccl[i]=float(ax);
    delay(1);
    yaccl[i]=float(ay);
    delay(1);

    zaccl[i]=float(az);
    delay(1);

And you should really really keep all lines indented correctly. The Arduino IDE has an autoformat feature to make it simpler for you.


body:
I am trying to use the OTA to update my code in esp32. I have used Web updater so far and it has worked perfectly. But I want to update the code even when I am not connected in the same network with my esp32. Say, the esp32 have an ip from my phone Ap : 192.168.1.43 and I am connected in a different one say, 192.168.25.12 As both of them are class C ip having default subnet mask then we are in different network.

I have found this following question
https://arduino.stackexchange.com/questions/66181/ota-updating-the-esp32-from-a-separate-server
It did not clarify things to me.

title: OTA update for ESP32 in Arduino ide from a different nework

Answers: 0


body:
I have a ProtoCentral FDC1004 board (datasheet: http://www.ti.com/lit/ds/symlink/fdc1004.pdf) connected to an Arduino. I am then trying to connect to the system via matlab.

I have found the address (0x50) using *addrs = scanI2CBus(a)* and I am now trying to read measurements from it.

Page 15 of the datasheet says the following to trigger measurements:

     1. Setting REPEAT (Register 0x0C:bit[8]) to 0.
     2. Setting the corresponding MEAS_x field (Register 0x0C:bit[7:4]) to 1.
        – For example, to trigger a single measurement of Measurement 2 at a rate of 100S/s,
        set Address 0x0C to 0x0540.

**Q1**: How do I work out where the value "0x0540" comes from?

**Q2**: I don't seem to be able to write this value, I'm able to write other values to this register and read them back however. How can I write 0x0540 to this register?

My matlab script is as follows:

    a = arduino('COM7', 'Uno', 'Libraries', 'I2C');
    capdev = device(a,'I2CAddress',0x50);

    writeRegister(capdev, 0x0C, 0x0540,'uint16');
    readRegister(capdev,0x0C,'uint16')
    value1 = readRegister(capdev,0x02,'uint16')
    value2 = readRegister(capdev,0x03,'uint16')

readRegister(capdev,0x0C,'uint16') simply displays the last value I wrote to this register during testing (eg 3)

0x02 and 0x03 are supposedly where measurement 2 is stored. These read as 0.

**Q3**: Any idea what I'm doing wrong, or how to implement this correctly?

Thank you!

title: I2C Communication Matlab - FDC1004

Answers: 0


body:
I am using the Grove - Slide Potentiometer (http://wiki.seeedstudio.com/Grove-Slide_Potentiometer). How can I set the potValue so that at maximum it will 128?

    int potPin= A0;
    int readValue;
    int potValue;

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

    void loop() {
     readValue = analogRead(potPin);
     potValue = (255./500.) * readValue;
     Serial.print("You are writing a value of ");
     Serial.println(potValue);
    }

title: Set slide potentiometer values

Answers: 2

body:
You can use the `map` function, see https://www.arduino.cc/reference/en/language/functions/math/map/.

Example: If your pot meter gives values from 100 to 1000 and you want to map that range to a range of 0 to 128 you can easily write:

    potValue = map(readValue, 100, 1000, 0, 128);

High likely, in your case and if the potentiometer is 'perfect' it returns values from 0 to 1023 and you can write:

    potValue = map(readValue, 0, 1023, 0, 128);

body:
analogRead() returns 0x0000 to 0x03ff

If the max data 0x03ff is shifted to the right by 3 bits (or divide by 8),
then 0x03ff becomes 0x007f, or 127.

I think this will do it:

    desiredMax = analogRead(A0) >> 3; // divide 1023 max by 8, becomes 127 max


body:
Thanks for your presentation https://arduino.stackexchange.com/tags/max7219/info.
You say that multiple MAX7219 8x8 blocs can easily be daisy-chained and you show an example of at least 12 blocs displaying "Testing12345".
Trying several programs I found for Arduino, I never succeeded to chain more than 8 blocs with 8x8 matrix (either 8 individual blocs or 2 groups of 4 as on your image).
So I'ld be very happy if you send me examples of programs managing more than 8 blocs for fixed or scrolling displays.
Many thanks in advance.

title: Daisy chaining of multiple blocs of 4x(8x8) MAX7219 matrix

Answers: 2

body: Try using @Majenko 's MAX libary https://github.com/MajicDesigns/MD_MAX72XX .  It allows you to specify how many modules are to be addressed.

body:
All is OK changing the proposed statement
# define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
to
# define HARDWARE_TYPE MD_MAX72XX::FC16_HW