body:
I'm trying to creature an instrument out of a few boards I have. The plan is to have piezo sensors wait for a hit, then be read by a digital pin, then execute code based on what piezo sensor was hit.

I know how to make a note play, but I don't know how to read a signal from a piezo that's between 3V and 5V. I'm not worried about velocity measurements, I just want there to be a hit, register the hit through arduino, then relay the pin number to a track number.

I read that pin change interrupts can read a signal instantly.

Below is some example code for my audio output board that plays audio files. This specific bit of code is for "notes" on an instrument.

              wTrig.masterGain(-8);                 // Lower main volume
              wTrig.trackPlayPoly(6);               // Play first note
              delay(1000);
              wTrig.trackPlayPoly(7);               // Play second note
              delay(1000);
              wTrig.trackPlayPoly(8);               // Play third note
              delay(1000);
              wTrig.trackFade(6, -50, 5000, 1);     // Fade Track 6 to -50dB and stop
              wTrig.trackFade(7, -50, 5000, 1);     // Fade Track 7 to -50dB and stop
              wTrig.trackFade(8, -50, 5000, 1);     // Fade Track 8 to -50dB and stop

I don't have experience with code, but this is how I think activating a note would work:

    wTrig.trackPlayPoly(pin number)
    delay(100);
    wTrig.trackFade(pin number, -50, 5000, 1);

As far as limiting voltage, don't I just need to put some resistors in circuit with the piezo sensors?

In psuedo-code, this is what I want to make happen:

    Listen for signal from any pin
    Store that pin number as a variable
    wTrig.trackPlayPoly(pin number)
    delay(100);
    wTrig.trackFade(pin number, -50, 5000, 1);

title: How can I read a piezo sensor and have it output a fixed voltage?

Answers: 2

body:
A piezo will output a decaying sinusoid when you feed it an impulse (a hit on the attached surface). Problem with a high frequency sinusoid is that one: half the time it's negative, and two: it forces a near-real-time monitoring of the analog voltage there, ie no or small delays in your code.

I've made a pattern recognition 'drum' with piezos, and the general approach was to first start with plotting the analog voltage of the piezo. This is done by putting the positive of the piezo to an analog pin and the negative to ground, *and* a 1M resistor between the leads (this value worked for me, play with different values to see what works best). Then do a serial plot (ctrl shift L in the IDE) and observe:

 - how high the peak is for different distances and strengths of 'knocks'
 - how many times a significant peak occurs before decaying.

Your end goal is to have the Arduino recognize a peak by seeing when the analog reading is above a threshold value , then have a dead period where it ignores subsequent peaks (so it doesn't read multiple events on a single sinusoid), and then play your note. Longer dead period means less false-positives, shorter means more responsive.

I apologize for the long-windedness of my somewhat ambiguous response, I'll try to remember to paste my code when I'm at my computer tomorrow.

body:
If the piezo is mounted to a surface, and you're hitting the surface to create vibrations, it is complicated as mentioned in the other answer, and it would be a good idea to connect piezo brass to a stable 2.5V and use rail clamping diodes on the pin.  For this purpose, you may be okay with just a couple 100 ohm resistors as a divider and a capacitor between ground and the 2.5V.  The proper audio way is more involved.

But if you're tapping the piezo directly with your finger, or tapping a thin plate and foam on top of the piezo, it's a lot simpler.  I've done this with a 100k ohm resistor in parallel (better response and consistency than 1 M ohm) and 5V zener diode in parallel for a 5V processor.  An analog pin with AnalogRead function can determine the voltage.  Brass wired to ground, center area wired to pin.  I've found that placing thin foam underneath everything gets rid of the crosstalk, especially if you don't need velocity sensitivity.

I would avoid using the delay function because it will prevent other piezos from working during that time.  Millis() calculations allow other actions to be performed.


body: I need to broadcast small amounts of data in a radius of about 500 meters to 2 Kms. in real time. Any compatible receiver in the range should be able to receive that data. Is there a suitable module for the same? I am considering HC-12 but don't think it can used for broadcasting data to all the surrounding receivers.

title: Broadcast data to radius of at least 500 meters

Answers: 2

body:
Maybe you can look into the LoPy Microcontroller, a MicroPython enabled controller, that has a 1km WiFi range. It uses the Espressif ESP32 chipset (with 802.1b/g/n 16mbps WiFi) and has Bluetooth (BLE & Classic) integrated into the board.

(Reference: https://www.pycom.io/product/lopy/)

body: You can use NRF2L01 2.4ghz rf tranceivers.They have a range of approx 1 km without antannae and 1.8 km with antannae.Also the ESP8266 wifi module normally has a range of 300m but can be used for the ranges you require with some big dish antannae.


body:
As a continuation of my question. Here's the code for controlling the 4 digit 7 segment display:

    int a = 2;
    int b = 3;
    int c = 4;
    int d = 5;
    int e = 6;
    int f = 7;
    int g = 8;
    int p = 9;

    int d4 = 10;
    int d3 = 11;
    int d2 = 12;
    int d1 = 13;

    void setup()
    {
      //set all the pins of the LED display as output
      pinMode(d1, OUTPUT);
      pinMode(d2, OUTPUT);
      pinMode(d3, OUTPUT);
      pinMode(d4, OUTPUT);
      pinMode(a, OUTPUT);
      pinMode(b, OUTPUT);
      pinMode(c, OUTPUT);
      pinMode(d, OUTPUT);
      pinMode(e, OUTPUT);
      pinMode(f, OUTPUT);
      pinMode(g, OUTPUT);
      pinMode(p, OUTPUT);

    }
    /***************************************/
    void loop()

    {
      //The 7-segment LED display is a common-cathode one. So also use digitalWrite to  set d1 as high and the LED will go out
      digitalWrite(d1, HIGH);
      digitalWrite(d2, HIGH);
      digitalWrite(d3, HIGH);
      digitalWrite(d4, HIGH);

      switch(x)
      {
        case 0:
        digitalWrite(d1, LOW);//Light d1 up
        break;
        case 1:
        digitalWrite(d2, LOW); //Light d2 up
        break;
        case 2:
        digitalWrite(d3, LOW); //Light d3 up
        break;
        default:
        digitalWrite(d4, LOW); //Light d4 up
        break;
      }
    }
    //The function is to control the 7-segment LED display to display numbers. Here x is the number to be displayed. It is an integer from 0 to 9
    void pickNumber(int x)
    {
      switch(x)
      {
        default:
        zero();
        break;
        case 1:
        one();
        break;
        case 2:
        two();
        break;
        case 3:
        three();
        break;
        case 4:
        four();
        break;
        case 5:
        five();
        break;
        case 6:
        six();
        break;
        case 7:
        seven();
        break;
        case 8:
        eight();
        break;
        case 9:
        nine();
        break;
      }
    }
    void clearLEDs() //clear the 7-segment display screen
    {
      digitalWrite(a, LOW);
      digitalWrite(b, LOW);
      digitalWrite(c, LOW);
      digitalWrite(d, LOW);
      digitalWrite(e, LOW);
      digitalWrite(f, LOW);
      digitalWrite(g, LOW);
      digitalWrite(p, LOW);
    }

    void zero() //the 7-segment led display 0
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, HIGH);
      digitalWrite(c, HIGH);
      digitalWrite(d, HIGH);
      digitalWrite(e, HIGH);
      digitalWrite(f, HIGH);
      digitalWrite(g, LOW);
    }

    void one() //the 7-segment led display 1
    {
      digitalWrite(a, LOW);
      digitalWrite(b, HIGH);
      digitalWrite(c, HIGH);
      digitalWrite(d, LOW);
      digitalWrite(e, LOW);
      digitalWrite(f, LOW);
      digitalWrite(g, LOW);
    }

    void two() //the 7-segment led display 2
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, HIGH);
      digitalWrite(c, LOW);
      digitalWrite(d, HIGH);
      digitalWrite(e, HIGH);
      digitalWrite(f, LOW);
      digitalWrite(g, HIGH);
    }

    void three() //the 7-segment led display 3
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, HIGH);
      digitalWrite(c, HIGH);
      digitalWrite(d, HIGH);
      digitalWrite(e, LOW);
      digitalWrite(f, LOW);
      digitalWrite(g, HIGH);
    }

    void four() //the 7-segment led display 4
    {
      digitalWrite(a, LOW);
      digitalWrite(b, HIGH);
      digitalWrite(c, HIGH);
      digitalWrite(d, LOW);
      digitalWrite(e, LOW);
      digitalWrite(f, HIGH);
      digitalWrite(g, HIGH);
    }

    void five() //the 7-segment led display 5
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, LOW);
      digitalWrite(c, HIGH);
      digitalWrite(d, HIGH);
      digitalWrite(e, LOW);
      digitalWrite(f, HIGH);
      digitalWrite(g, HIGH);
    }

    void six() //the 7-segment led display 6
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, LOW);
      digitalWrite(c, HIGH);
      digitalWrite(d, HIGH);
      digitalWrite(e, HIGH);
      digitalWrite(f, HIGH);
      digitalWrite(g, HIGH);
    }

    void seven() //the 7-segment led display 7
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, HIGH);
      digitalWrite(c, HIGH);
      digitalWrite(d, LOW);
      digitalWrite(e, LOW);
      digitalWrite(f, LOW);
      digitalWrite(g, LOW);
    }

    void eight() //the 7-segment led display 8
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, HIGH);
      digitalWrite(c, HIGH);
      digitalWrite(d, HIGH);
      digitalWrite(e, HIGH);
      digitalWrite(f, HIGH);
      digitalWrite(g, HIGH);
    }

    void nine() //the 7-segment led display 9
    {
      digitalWrite(a, HIGH);
      digitalWrite(b, HIGH);
      digitalWrite(c, HIGH);
      digitalWrite(d, HIGH);
      digitalWrite(e, LOW);
      digitalWrite(f, HIGH);
      digitalWrite(g, HIGH);

My problem is how to include the voltage code here? Here's the code for voltage code:

        /*
    * Display5vOrless sketch
    * prints the voltage on analog pin to the serial port
    * Warning - do not connect more than 5 volts directly to an Arduino pin.
    */

    const float referenceVolts = 5.0; // the default reference on a 5-volt board
    const int batteryPin = 0; // battery is connected to analog pin 0

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

    void loop()
    {
     int val = analogRead(batteryPin); // read the value from the sensor
     float volts = (val / 1023.0) * referenceVolts; // calculate the ratio
     Serial.println(volts); // print the value in volts
     delay(500);
     }

Please help me! Thank you!

title: How to include Voltage code in 4 digit 7 segment dislay

Answers: 1

body: Yes you can display single digits what happen when you want to display double or triple digits. You need a code that can handle that. You need to cut up volts an iterare over it. Anyway create a class that takes volt and return it on the display. That's what you you need to do to merge that code. Are you up for that? Or are you gonna find a library that can handle that?


body: What will happen if I by mistakenly connect GND and +5v of an Arduino Nano? Is there any protection for it? Or will it get short and fry out something?

title: What happens if we connect GND and +5v?

Answers: 2

body:
According to [this image](http://cdn-tienda.bricogeek.com/847-thickbox_default/arduino-pro-mini-328-5v-16mhz.jpg) and [this datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/mic5205.pdf), that nano's voltage regulator is internally limited.

That means it will heat up and shut down if over-loaded. Of course, your nano could use a less-effective regulator and simply smoke away. It's also possible that the 5205 would not clamp in time to prevent damage on an instant dead-short. Generally, i've found the arduino boards to be fairly resilient, compared to other MCUs, so you can _probably_ get away with it at least a time or two.

Dead shorting is never a good idea even if you can get away with it because there can be incremental (as opposed to catastrophic) damage. You might cause instability in the regulator, and you might limit it's ability to limit volts. Those problems might not be revealed instantly, but instead at the worst (unexpected) time.

EDIT:
based on your edit, it sounds like your "FTDI" is fried, but not _necessarily_ your MCU.

body:
Depending on how you are powering your board different things will happen.

1. If you are powering through USB from a PC the PC should, according to the USB standard, detect an over-current situation and disconnect the power from the port. However some don't, in which case see point 2.

2. If you are powering through USB from a USB power supply (phone charger, etc) the charger's output voltage will drop to near zero and the current will hit maximum for the supply. This may or may not damage the supply, but either way it's not a nice thing to do.

3. If you are powering from a small external battery (say a 9V PP3 battery) things will start to get hot. The voltage regulator will most likely overheat, the battery may overheat, but not much damage should occur - a small PP3 battery can't provide much current.

4. If you are powering from a large external battery (e.g., Li-Ion cells) or an external power supply, things will get more nasty. The on-board regulator will overheat. If it isn't thermally protected (genuine Arduinos should be, but cheap Chinese clones may not be) then it will fail and you will find smoke coming out of the regulator. At this point the regulator is dead. If the board contains a polarity protection diode that may fail in the same way (I have seen these blow clean off the board before). Physical damage (blackening and blistering) may occur to the PCB as well.

So all in all shorting +5V to GND is never a good idea.


body:
I have hooked up 2 channel 5-volt relays with NodeMCU v1.0 as shown in the fritzing below.

[![Relay are powered with a different power source than NodeMCU][1]][1]
Relay are powered with a different power source than NodeMCU.

As of now, I am powering the NodeMCU from my laptop and the relay board from a 5-volt battery.

Below is the code I have written:

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266mDNS.h>

    const char* ssid = "said.";
    const char* password = "secret";
    ESP8266WebServer server ( 80 );
    const int led = 13;
    const int outputLed = 12;

    void turnOnRelayOne(){
      digitalWrite (outputLed, 1);
      digitalWrite (5, HIGH); //GPIO 5 // Relay 1
      server.send (200, "text/html", "Relay 1 turned on.");
      digitalWrite (outputLed, 0);
    }

    void turnOnRelayTwo(){
      digitalWrite (outputLed, 1);
      digitalWrite (4, HIGH); //GPIO 4 // Relay 2
      server.send (200, "text/html", "Relay 2 turned on.");
      digitalWrite (outputLed, 0);
    }

    void handleRoot() {
      digitalWrite ( led, 1 );

      char temp[400];
      int sec = millis() / 1000;
      int min = sec / 60;
      int hr = min / 60;
      int h = dht.readHumidity();
      int t = dht.readTemperature();
      snprintf ( temp, 400,

                 "\
      \
        <meta http-equiv='refresh' content='5'/>\
        <title>NodeMCU hooked to Relay Board</title>\
        \
      \
      \

Hello from NodeMCU!
\

Uptime: d:d:d
\
      \
    ",

              hr, min % 60, sec % 60
               );
      server.send ( 200, "text/html", temp );
      digitalWrite ( led, 0 );
    }

    void handleNotFound() {
      digitalWrite ( led, 1 );
      String message = "File Not Found\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";

      for ( uint8_t i = 0; i < server.args(); i++ ) {
        message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
      }

      server.send ( 404, "text/plain", message );
      digitalWrite ( led, 0 );
    }

    void setup ( void ) {
      pinMode ( led, OUTPUT );
      pinMode(10, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(outputLed, OUTPUT);
      digitalWrite ( led, 0 );
      Serial.begin ( 9600 );
      WiFi.begin ( ssid, password );
      Serial.println ( "" );

      // Wait for connection
      while ( WiFi.status() != WL_CONNECTED ) {
        delay ( 500 );
        Serial.print ( "." );
      }

      Serial.println ( "" );
      Serial.print ( "Connected to " );
      Serial.println ( ssid );
      Serial.print ( "IP address: " );
      Serial.println ( WiFi.localIP() );

      if ( MDNS.begin ( "esp8266" ) ) {
        Serial.println ( "MDNS responder started" );
      }

      server.on ( "/", handleRoot );

      server.on ( "/inline", []() {
        server.send ( 200, "text/plain", "this works as well" );
      } );

      server.on("/relay1", turnOnRelayOne);
      server.on("/relay2", turnOnRelayTwo);
      server.onNotFound ( handleNotFound );
      server.begin();
      Serial.println ( "HTTP server started" );
    }

    void loop (void) {
      server.handleClient();
    }

When I execute the URL: `192.168.1.8/relay1` the outputLed blinks as per the logic in `turnOnRelayOne`.

But neither of the relays turns on. Please help.

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

title: How to make a 5-volt relay work with NodeMCU?

Answers: 5

body: The relay has no reference for what the voltage from the NodeMCU is. Since the power supplies of the two devices are isolated (from each other; the laptop may not be isolated itself, but the battery certainly should be) you can (and in fact *must*) connect the grounds of the relay board and the NodeMCU together. If neither power supply is isolated or if you are unsure if they are isolated then you should use an optoisolator in order to prevent potential power issues.

body:
I believe the problem could be that the relay is 5v but the signal coming from the NodeMCU is 3.3v. You may need do something like boost the signal to 5v or implement a logic level shifter, for example.

Here's a related post:
https://electronics.stackexchange.com/questions/213051/how-do-i-use-a-5v-relay-with-a-3-3v-arduino-pro-mini

body:
This relay module works differently.
It is on when the signal is LOW and it turns off when the signal is HIGH (3v3V on the NodeMCU)
So you only need to modify the code in the two functions to be LOW instead of HIGH
Also make sure the NodeMCU and the relay module have a common ground.

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266mDNS.h>

    const char* ssid = "said.";
    const char* password = "secret";
    ESP8266WebServer server ( 80 );
    const int led = 13;
    const int outputLed = 12;

    void turnOnRelayOne(){
      digitalWrite (outputLed, 1);
      digitalWrite (5, LOW); //GPIO 5 // Relay 1
      server.send (200, "text/html", "Relay 1 turned on.");
      digitalWrite (outputLed, 0);
    }

    void turnOnRelayTwo(){
      digitalWrite (outputLed, 1);
      digitalWrite (4, LOW); //GPIO 4 // Relay 2
      server.send (200, "text/html", "Relay 2 turned on.");
      digitalWrite (outputLed, 0);
    }

    void handleRoot() {
      digitalWrite ( led, 1 );

      char temp[400];
      int sec = millis() / 1000;
      int min = sec / 60;
      int hr = min / 60;
      int h = dht.readHumidity();
      int t = dht.readTemperature();
      snprintf ( temp, 400,

                 "\
      \
        <meta http-equiv='refresh' content='5'/>\
        <title>NodeMCU hooked to Relay Board</title>\
        \
      \
      \

Hello from NodeMCU!
\

Uptime: d:d:d
\
      \
    ",

              hr, min % 60, sec % 60
               );
      server.send ( 200, "text/html", temp );
      digitalWrite ( led, 0 );
    }

    void handleNotFound() {
      digitalWrite ( led, 1 );
      String message = "File Not Found\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";

      for ( uint8_t i = 0; i < server.args(); i++ ) {
        message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
      }

      server.send ( 404, "text/plain", message );
      digitalWrite ( led, 0 );
    }

    void setup ( void ) {
      pinMode ( led, OUTPUT );
      pinMode(10, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(outputLed, OUTPUT);
      digitalWrite ( led, 0 );
      Serial.begin ( 9600 );
      WiFi.begin ( ssid, password );
      Serial.println ( "" );

      // Wait for connection
      while ( WiFi.status() != WL_CONNECTED ) {
        delay ( 500 );
        Serial.print ( "." );
      }

      Serial.println ( "" );
      Serial.print ( "Connected to " );
      Serial.println ( ssid );
      Serial.print ( "IP address: " );
      Serial.println ( WiFi.localIP() );

      if ( MDNS.begin ( "esp8266" ) ) {
        Serial.println ( "MDNS responder started" );
      }

      server.on ( "/", handleRoot );

      server.on ( "/inline", []() {
        server.send ( 200, "text/plain", "this works as well" );
      } );

      server.on("/relay1", turnOnRelayOne);
      server.on("/relay2", turnOnRelayTwo);
      server.onNotFound ( handleNotFound );
      server.begin();
      Serial.println ( "HTTP server started" );
    }

    void loop (void) {
      server.handleClient();
    }

body:
I have several of these modules. They have an optional opto-isolator built-in, but you have to remove the jumper to use it.

* Connect your GPIO trigger as you have it
* Run the relay's `Vcc` and `Gnd` pins to the MCU, not the power plug.
* connect the power plug's +5v to the left-most pin, where the jumper once stood: `JDVcc`
* connect the power plug ground to the MCU or the open common `Gnd` on the left-group of pins.

Now your relay coil(s) will be powered by the 5v plug, but the relay's logic and control are handled by the MCU.

body: How are you powering your ESP-12E?  This is not included in your diagram. I have had success using the VU pin (5V output) when powering from the Micro-USB.  You would then connect VCC to VU, GND to GND, and Signal to your GPIO4.  If you are powering your ESP-12E from a 5v power supply directly into the VIN pin, then I would power the Relay from the same 5V power supply.  you would connect the + from the power supply to VIN (ESP) and VCC (relay) all the grounds tied together then the GPIO4 to Signal.


body:
I'm trying to send each character of a string object to a subroutine. I'm using the following code to do this, but it doesn't work:

    string sInput = "some text"
    for (int i=1; i < sInput.length(); i++) {
      showLetter(sInput.substring(i, i));
    }

Subroutine:

    void showLetter(String sInput)

My belief is that this should be iterating through the string and selecting one character (not to be confused with a char) at a time and sending it to the subroutine.

I haven't used C++ for 30 years and I am having difficulty finding why this won't work. I understand that I could use a char array, but I wanted to use this method.

If C++/Arduino coding doesn't work this way, to get credit you MUST explain why not.

Any help would be appreciated.

entire code follows...

    /*
    visual morse code

    a dot is 1 unit
    a dash is 3 units
      space between parts of the same letter is one unit
    the space between letters is 3 units
    the space between words is 7 units
    */

    void parseString(String sInput);
    void showletter(char sInput);
    void dot(void); //dot
    void dash(void);  //dash
    void letterSeparator(void); //between letters
    void wordSeparator(void); //space
    int baseUnitLength = 100;

    // the setup function runs once when you press reset or power the board
    void setup(){
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(LED_BUILTIN, OUTPUT);
    }

    // the loop function runs over and over again forever
    void loop(){
      //call a routine with a string.
      //the routine parses the string and blinks the dot and dash for morse code for each character

      parseString("sos ");

      //showLetter("s");
      //showLetter("o");
      //showLetter("s");
      //showLetter(" ");
    }

    void parseString(String sInput)
    {
      for (int i=1; i<sInput.length(); i++){
        showLetter(sInput.substring(i,i));
      }
    }
    void showLetter(String sInput){
      if (sInput == "a")
        {
          dot();
          dash();
          letterSeparator();
        }
      else if (sInput == "b")
        {
          dash();
          dot();
          dot();
          dot();
          letterSeparator();
        }
      else if (sInput == "s")
        {
          dot();
          dot();
          dot();
          letterSeparator();
        }
      else if (sInput == "o")
        {
          dash();
          dash();
          dash();
          letterSeparator();
        }
      else if (sInput == " ")
        {
          wordSeparator();
        }
    }
    void dot(){
        digitalWrite(LED_BUILTIN, HIGH);
        delay(baseUnitLength);
        digitalWrite(LED_BUILTIN, LOW);
        delay(baseUnitLength);
      }
    void dash(){
        digitalWrite(LED_BUILTIN, HIGH);
        delay(baseUnitLength * 3);
        digitalWrite(LED_BUILTIN, LOW);
        delay(baseUnitLength);
      }
    void letterSeparator(){
        digitalWrite(LED_BUILTIN, LOW);
        delay(baseUnitLength * 3);
      }
    void wordSeparator(){
        digitalWrite(LED_BUILTIN, LOW);
        delay(baseUnitLength * 6);
      }

title: Passing a substring to a function or sub

Answers: 3

body:
I would suggestion the following:

    String sInput = "some text";

    void showLetter(char c);

    for (int i = 1; i < sInput.length(); i++) {
      showLetter(sInput[i]);
    }

Rewritten using C/C++ strings (null-terminated character vector):

    const char* sInput = "some text";

    void showLetter(char c);

    for (int i = 1; i < strlen(sInput); i++) {
      showLetter(sInput[i]);
    }

And slightly more efficient:

    const char* sInput = "some text";

    void showLetter(char c);

    const char* sp = sInput;
    char c;
    while ((c = *sp++) != 0) {
      showLetter(c);
    }

The next step is to move the string literal to program memory to reduce the amount of RAM needed.

Cheers!

body:
Mr. jfpoilpret provided me with the answer and should be credited, as such.
It appears the subString function needs to have 1 added to the second parameter in order to properly reference the number of characters you need in the String.
In my case, iterating through a String and referencing only one character at a time means I need to do the following sInput.substring(i,i+1)
Also, the String object uses a zero based index.
EX:
   String sString = "This is a peach.";
   sString.substring(0,4)     //should return "This"
   sString.substring(8,9)     //should return "a"
   sString.substring(15,16)   //should return "."

In addition, you could also use the String function charAt (EX: sString.charAt(i)).
The charAt returns a char and if you are passing it to a function/sub you need to make sure the function/sub is expecting a char data type.
Also, it is easier to use a switch case when using the charAt function, as you don't have to do a conversion from String to char, as switch case does not work with Strings.

body:
You got your answer, and you understood how this works. However, your
sentence “_It appears the subString function needs to have 1 added to
the second parameter [...]_” makes me believe you find this behavior
somewhat contrived, whereas it should be intuitive to any C or C++
programmer.

As I think this may help, I will share here the mental picture I use for
thinking about array indices. I call it the “L-shaped cursor”, and it
goes like this:

An array index can represent two different things:

* a particular cell within the array
* an “edge” of a cell, i.e. either the limit between two cells or an
  edge of the whole array.

This is depicted in following picture of an array of length `N`, where
the numbers above it are the edge indices and the numbers below are the
cell indices. `i` and `j` are just two particular indices:

    0   1   2           i           j               N
    ┌───┬───┬───┬───────┰───┬───────┰───┬───────┬───┐
    │   │   │   │  ⋅⋅⋅  ┃   │  ⋅⋅⋅  ┃   │  ⋅⋅⋅  │   │
    └───┴───┴───┴───────┺━━━┵───────┺━━━┵───────┴───┘
      0   1   2           i           j          N−1

Since each index can represent two things, I like to think about them as
being L-shaped cursors, like the ones I've drawn in bold for the indices
`i` and `j`.

Now, if you think about the purpose of the `substring()` method, it's
job is to cut a slice along the string, and you need to tell it where to
place the “knife”. Since the knife will cut along edges, it's perfectly
natural to use edge indices for that. Then

    someString.substring(i, j)

will give you the slice of the string that lies between the edges `i`
and `j`. Looking at the picture above you can see this includes the cell
numbered `i` but not the one numbered `j`.

I hope this picture helps you find the behavior of `substring()` more
natural now. It _does_ help me avoid [fencepost
errors](https://en.wikipedia.org/wiki/Off-by-one_error#Fencepost_error).


body:
I am setting up a page on NodeMCU running as a web server and I want to be able to turn on and off a light based on the url being clicked.

I want to know how I can get the status so that I can set the URL based on the pin status as well as pass  the GPIO pin status in the JSON from the NodeMCU web server.

The code is [here][1].

  [1]: https://arduino.stackexchange.com/questions/36330/how-to-make-5volt-relay-to-work-with-node-mcu?noredirect=1#comment72314_36330

title: How to read NodeMCU GPIO pin status?

Answers: 1

body:
Independent of the setting of port direction (input or output), pin can be read through the digitalRead():

    int pin_light = 3;
    int status = digitalRead(pin_light);


body:
this probably simple thing to do however I can't think of a way to pass argument to function call

    ESP8266WebServer server ( 80 );

    void toggleRelayOne() {
      char temp[400];
      String msg = "";
      if (relay1 == 0) {
        relay1 = 1;
        msg = "Light is turned on";
      }
      else {
        relay1 = 0;
        msg = "Light is turned off";
      }

      digitalWrite (5, relay1); //GPIO 5 // Relay 1
      snprintf ( temp, 400,
                 "<html>\
      <head>\
        <meta http-equiv='refresh' content='5'/>\
        <title>NodeMCU DHT11 Sensor and Relay Board</title>\
        <meta http-equiv='refresh' content='0; url=../'>\
        </head>\
      <body>\
      %d .</body>\
      </html>"
                 , 1);
      server.send ( 200, "text/html", temp );
    }

    void setup ( void ) {

      pinMode(10, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(4, OUTPUT);

      Serial.begin ( 9600 );
      WiFi.begin ( ssid, password );
      Serial.println ( "" );
      // Wait for connection
      while ( WiFi.status() != WL_CONNECTED ) {
        delay ( 500 );
        Serial.print ( "." );
      }

      Serial.println ( "" );
      Serial.print ( "Connected to " );
      Serial.println ( ssid );
      Serial.print ( "IP address: " );
      Serial.println ( WiFi.localIP() );

      if ( MDNS.begin ( host ) ) {
        Serial.println ( "MDNS responder started" );
      }
      MDNS.addService("http", "tcp", 80);
      server.on ( "/", handleRoot );
      server.on("/relay1", toggleRelayOne);
      server.begin();
      Serial.println ( "HTTP server started" );
    }

in the above function where I am calling `toggleRelayOne` using `server.on("/relay1", toggleRelayOne);` I want to be able to pass relay id so I can use same function to toggle multiple relays.

title: how to send argument to ESP8266WebServer objects on function

Answers: 1

body:
Use `server.arg()` to pass commands from the web as GET params:

`digitalWrite (5, relay1);`

becomes

`digitalWrite (server.arg("pin").toInt(), relay1);`

where the URL is something like `http://192.168.1.5/relay1?pin=15`

Of course, the rest of your code probably needs to be adapted to manage the extra states, read/write all in one http call, etc.


body:
I recently purchased a 5V arduino pro mini that I now wish to connect to a BLE device.

I firstly tried the BLE device with my Uno board and it worked very well! However when I now try to use it on my mini it does not start.

This is my wiring:
First I connect the pro mini to the uno in order to upload the code looking like this:

1. Arduino Mini Pro to Arduino Uno

2. RX --> TX
3. TX --> RX
4. VCC --> 5v
5. GND --> GND
6. RST --> RST

Then I wire the mini to my BLE device (https://learn.adafruit.com/getting-started-with-the-nrf8001-bluefruit-le-breakout/hooking-everything-up):

1. Arduino Mini Pro to BLE nRF8001

2. 13 --> SCK
3. 12 --> MISO
4. 11 --> MOSI
5. 10 --> REQ
6. 9 --> RST
7. 2 --> RDY
8. GND --> GND
9. VCC --> VIN

When I connect this setup to the computer the arduino uno starts and also the pro mini (both has LED lights on). I upload a simple test code that worked when i tried it with the uno but the BLE device does not respond (it seems like it does not turn on) when i use it with the pro mini.

Any idea what might be wrong? I have my board put as: Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz).

Thanks a ton!! :)

title: Why is the BLE device not starting on my Arduino Pro Mini?

Answers: 1

body:
> This is my wiring: First I connect the pro mini to the uno in order to upload the code looking like this:

    Arduino Mini Pro to Arduino Uno

    RX --> TX
    TX --> RX
    VCC --> 5v
    GND --> GND
    RST --> RST

How would this work? The bootloader in the Uno and Mini Pro will both try to reply. You need a FTDI or a USB-to-UART module instead of the Uno. Alternatively, start by programming the Uno to act as a USB-to-UART converter using Serial and SoftwareSerial.

Cheers!


body:
This is really a two part question. I have an ESP8266 hooked up to USB. I have connected my LED strip (WS2812B LEDs) to the RX port, so I can control them individually and so on. I realised WiFi is a bit slow and will eventually crash the ESP8266 if I send enough requests, which is why I want to give serial a go.

 1. If I open up the serial monitor, how do I send something to it, such as a color or 100 colors in one command? I'd assume `Serial.read()` inside a `Serial.write()` would display whatever I type in, but it doesn't do that. I can `Serial.write()` inside a loop, and it will display that.
 2. Is something like this even possible? I'm looking for a way to send a lot of information (could be 100 colors (1 per LED)) as fast as possible. Speed is the key here.

Software serial is an option as well, as long as it's faster than WiFi.

title: Send serial commands through IDE while RX pin is in use

Answers: 1

body:
Regarding “I have connected my LED strip (WS2812B LEDs) to the RX port”:  If you connect an LED strip to the RX pin, there's a good chance you won't be able to read serial data reliably on that pin, and may have trouble loading new sketches.  It makes sense to connect the LEDs to some pin other than RX.

Regarding “If I open up the serial monitor, how do I send something to it”:  Ordinarily, one uses the serial monitor to receive data from an attached MCU or to send data to the MCU. (An MCU is a microcontroller – eg an Arduino or ESP8266.)  In the sketch on the MCU, use [`Serial.write()`](https://www.arduino.cc/en/Serial/write) to send binary data to the monitor, and [`Serial.print()`](https://www.arduino.cc/en/Serial/Print) to send text and formatted numbers to the monitor.

If you want to send serial data rapidly from your host computer to the MCU, write a C or Python (etc) program that opens a serial port, marshals the data, and sends it.  In the  sketch on the MCU, use [`Serial.available`](https://www.arduino.cc/en/Serial/Available) to test if characters are available to read, and [`Serial.read`](https://www.arduino.cc/en/Serial/Read) to read a character.  For faster transmission, you can send binary data instead of ASCII, but would need to read up on that before attempting it.

For fast data transmission, aim for either high data rates or strong data compression.  For example, you might make up a protocol that only sends colors for pixels that are going to change; or might have high-level commands that tell the MCU how to generate a set of data, via color end points, step rates, and numbers of steps.

In general, wifi data rates are somewhat higher than serial data rates.  If that is not what you are experiencing, perhaps review the article [*Found a way to upload data VERY fast by wifi*](https://github.com/esp8266/Arduino/issues/1853) from github.com/esp8266.

---

*Edit 1:*
Regarding “Nothing is displayed in the serial monitor” [from code like `if (Serial.available()) { Serial.write(Serial.read()); }`]:  I'm assuming that the sketch in use has a `setup()` routine containing a `Serial.begin(somedatarate)` statement, with the same data rate selected in the serial monitor as in the `Serial.begin()` statement.   I'm also assuming the sketch has a `loop()` routine containing the `if (Serial.available()) { Serial.write(Serial.read()); }` code.

I'm also assuming the sketch was properly downloaded, and then the serial monitor was opened, using the USB-serial port the ESP8266 is attached to, and then you typed some text into the text entry box of the serial monitor and pressed or clicked Enter to send the text to the ESP8266, with a proper setting for the end-of-line character.

If all those assumptions are correct, but nothing shows up in reply to the text you send, then it seems likely some hardware or software issue is occurring.  For example, when the Serial data structure is set up (when the sketch begins running) it might be selecting an incorrect Rx pin.  Or something may be loading down the Rx pin.  To find out if either of those is the case, use an oscilloscope (if you have one) to look at what's arriving at different ESP8266 pins when you send text from the  serial monitor.  If no scope, connect a 5K-10KΩ resistor to an LED and use that as a logic probe.  One end of the resistor connects to a probe; the other end goes to the LED anode; and the LED cathode is grounded.  Test if that's working by touching the probe to +3.3V.  When the probe appears to be working ok, use it to check for brief flashes of data at different Rx pins on the ESP8266 when you send data from the serial monitor.  If no data gets to the ESP8266, it can't echo it.  (Note, I'm not sure how your NodeMCU ESP8266 handles serial-via-USB data; my notion that serial data should be visible on some Rx pin might be wrong.)

If it appears data is getting to some pin but isn't showing up as available, you might try opening software serial on that pin.  Some examples appear in code in a [serial monitor note at github.com/esp8266](https://github.com/esp8266/Arduino/issues/704).  I don't know enough about NodeMCU / ESP8266 to say what to do if probing and software serial don't help.


body:
I'm building a simple RS232 data logger with the Sparkfun OpenLog and a SEEED RS232-TTL adaptor. I'm powering it with a 9 volt battery and a 7805 voltage regulator.

It's dead simple. I built it on a breadboard first and determined that TX-TX and RX-RX connections are called for. I logged several files on the breadboard then soldered it all up. Now it's not working, sigh.

When I power it up  both lights will flash rapidly for about a second and then it settles down to a steady on-off with both lights.

If I delete the config file a new one is created, which shows that it recognizes the card at least.

I've triple checked my wiring and confirmed I have no shorts, and that the voltage is good.

I'm attaching a photo as built. Hopefully it's obvious what's what. The purple trace is ground.

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

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

title: Sparkfun OpenLog both lights flashing

Answers: 2

body:
The problem with the circuit was a bad rs232-ttl converter. Not sure how that messed up the openlog, but replacing it fixed the problem.

In the photo above, D1 on the converter is an led which should be normally on.

body: If the OpenLog's RX pin is held low for too long at startup, it'll reset to 9600 baud to attempt to recover. A bad rs232-ttl converter could cause this, if the RX pin was being held low. If you need the OpenLog to ignore this, see the ignoreRX parameter in config.txt and the hookup guide.


body:
I am currently gathering info from a BLE device. I made a thread earlier where I successfully split a string consisting of 5 letters to their unique chars.

However from this BLE device i will also send some different information from time to time where I send 3 different values with a space after each one. So for example looking like this:

`-0.1 0.51 0.07`

So what I want to do now is to store this three numbers in different doubles and what I have done so far is this:

First i store the recieved message:

    String recievedMessage;

    recievedMessage += (char)BTLEserial.read();

Now I have to determine if the value sent is the 5 letters or if it is the numbers with a space between each value.

    if (recievedMessage.length() > 5) //so if the recievedmessage is more than 5 words then it is the 3 values that is being sent.
    {
    char * charTheMessage = recievedMessage.c_str();
    char *str;
    str = strtok(charTheMessage, " ");

    double one = str[0];
    double two = str[1];
    double three = str[2];

    Serial.println (one);
    Serial.println (two);
    Serial.println (three);

    }

    if (recievedMessage.length() == 5)
    {
     //http://arduino.stackexchange.com/questions/36227/how-can-i-split-a-string-into-multiple-parts/36237?noredirect=1#comment72313_36237
    //Here I split the letters into 5 different values if the value sent is 5.
    }

But this values do not come out right when I print them in the serial monitor. I have also read that strtok is not reliable when data is sent fast so is strtok the right way to go you think?

title: How can I split a string into three parts after space and turn the values to doubles?

Answers: 1

body:
You're almost there. Strtok returns the *first* token in the string only. You then have to convert that to a double yourself. You then call strtok again with NULL as the source string to get the next token. And so on.

I have written a good strtok example on here already. Look around, you may find it.


body:
Im working on a RGB LED matrix project (10 x 10 Neopixels) and I'm using classes to handle the different hardware components. Whats the best way to deal with multiple files in the project eg, I have a class which holds the various display functions such as writing text and drawing circles, but every time I change something it takes ages to compile (Greater than 30 seconds) is there a way to have multiple files without using classes?

Any help would be greatly appreciated.

Cheers

title: Complex Arduino programs

Answers: 2

body:
I noticed that it is very hard to use classes with the default IDE.
Each file will be in a different tab, but normally each class has a header (.h) and implementation (.c) file, so 2 extra tabs per class.

If you have just 3-4 classes you can use the default IDE.

However, if you want to use more, you have to use e.g. Eclipse or Visual Studio, whatever IDE you like best.

Search for Eclipse/Arduino, I think there are multiple options.

Myself I use [visualmicro][1] ... it is free except you cannot use the debugger option.

I used several classes in my sketch and don't think the compile time was 30 seconds; it might be depending also on the amount of include files.

Also a complex program is not necessarily a program with many classes. I would say, that if you put too much functionality in one class (or one single sketch), you get a complex program.

  [1]: http://www.visualmicro.com/page/Arduino-Visual-Studio-Downloads.aspx

body:
Yes you can have multiple files without classes.

Functions don't have to go in classes, see loop and setup for an example. All you have to do is declare the function in a header file and then implement it in a body.

so:

    // File Bob.h
    #ifndef __BOB_H__
    #define __BOB_H__

    int SomeFunction(const char val);

    #endif // __BOB_H__

    // File Bob.cpp
    #include Bob.h
    int SomeFunction(const char val)
    {
       return (int)val;
    }

    // File SketchName.ino
    #include "Bob.h"

    setup()
    {
      ......... Stuff

Now in **theory** the compiler will only rebuild Bob.cpp when you change code in it.  In practice you will change code in it and the compiler won't rebuild it and you'll tare your hair out until you remember that if all else fails, rebuild all!

In `SketchName.ino` some people will say you should always put your includes first, some will say last and some will say it makes no difference.  In my experience its easier to fix duplicate definitions by changing your code so I always put 'my' includes last, because that way the compiler will report the errors against my code.

BTW 30 seconds is not a long build time.  I've worked on projects taking 12+ hours, and missing a semi colon on those projects does not make you popular :)


body:
I'm trying to do something seemingly simple, but I'm running into difficulties. I want to send about 5 separate integers between two Arduinos over software serial. I have written the following, but I rarely get the two numbers on the receiving end - they're usually garbled or in the wrong order. I'm sure that I'm missing something obvious, but I can't work it out no matter how hard I try. Any help would be greatly appreciated.

Sender:

    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(10, 11); // RX, TX

    int val, val2;

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

    void loop()
    {
      val = 123;
      val2 = 456;
      if(mySerial.read()=='#')
      {
        mySerial.write(highByte(val));
        mySerial.write(lowByte(val));
        delay(3);
      }
      if(mySerial.read() == '~')
      {
        mySerial.write(highByte(val2));
        mySerial.write(lowByte(val2));
        delay(3);
      }
    }
Receiver:

    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(10, 11); // RX, TX

    byte val;
    byte low, high;

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

    void loop()
    {
      mySerial.write('#');
      byte h = mySerial.read();
      byte l = mySerial.read();
      int y = word(h, l);
      delay(2);
      mySerial.write('~');
      byte h2 = mySerial.read();
      byte l2 = mySerial.read();
      int z = word(h2, l2);

      Serial.println(y);
      Serial.println(z);
      Serial.println();
    }

title: Random data sending integers between two Arduinos

Answers: 2

body:
You are being too impatient.

The receiver needs to wait until there is some data available.  `if (mySerial.Available() > 0)`.  So before every read add that line and it should work.

body:
You need to add a delay to the Receiver software immediately after you send the `#` and the `~` characters.

    void loop()
    {
      mySerial.write('#');
      delay(8);    // <<<<<<<< Line added
      byte h = mySerial.read();
      byte l = mySerial.read();
      int y = word(h, l);
      delay(2);
      mySerial.write('~');
      delay(8);    // <<<<<<<< Line added
      byte h2 = mySerial.read();
      byte l2 = mySerial.read();
      int z = word(h2, l2);

      Serial.println(y);
      Serial.println(z);
      Serial.println();
    }

The delay is needed so the microcontroller has enough time to send the character out of the serial port, have it processed by the other side and then the new data sent back.

Using 9600 baud, the time for each bit is around 104 microseconds. So a byte of data sent will take about 1.04 milliseconds. One byte sent + processing time + 2 bytes back is about 4 milliseconds. Adding a bit of margin, 8 ms delay would be a good value to use.

Using `if (mySerial.Available() > 0)` will not work on its own unfortunately, as Matt's answer suggests. What would happen is that you send the first `#` and then immediately it would check for any data recieved. From the calculation above we know it would take about 4 ms to get data back. So it just skips the if statement and goes onto the 2ms delay and then sending the `~`. It then checks if serial is available. By this time the first response 'may' be back, so if it is, it then saves the data into `h1` and `l1`. It then finishes the serial prints and loops back to the beginning. In this time the second response has come back, so after it sends `#` for the second time, the response to the `~` gets saved into `h` and `l`. This will continue forever.


body:
I recently made a thread where I read BLE data that has three different numbers/values. The data changes but it typically looks something like this:
`0,5` `-0,1` `0`

I successfully store the three numbers in a unique char* but when I try to convert the char* to a double I get the value 0.0 in return.

This is my code:

            while (tok)
            {
                if (currentRow == 0)
                {
                  currentRow = currentRow +1;
                  double a = atof(tok);
                  Serial.println (a);
                }

                else if (currentRow == 1)
                {
                  currentRow = currentRow+1;
                  double b = strtod(tok, NULL);
                  Serial.println (b);
                }

                else {
                  currentRow = 0;
                  double c = atof (tok);
                  Serial.println (c);
                }

                tok = strtok(NULL, " ");
            }

title: Converting a char* with numbers to a double is giving me 0.0 in return

Answers: 1

body: The value that was being sent used a comma "," instead of a dot "." that was needed in order to convert the number.


body: When I connect my Arduino through USB to my laptop, it does not make any sound like something is connected but green light is on. And port option in the Arduino IDE remains grayed out. I might have burned my Arduino, maybe? Please help.

title: Arduino does not make any sound when connected to laptop?

Answers: 2

body:
The Arduino will not make a sound, but probably you refer to the sound Windows makes when a USB device is connected?

Try (except for the tips already given by JRobert)

- different USB port
- reinstall Arduino IDE
- disable/enable or reinstall driver in Control panel/hardware/system/USB devices

body:
There are a number of possible scenarios as to what is wrong:

1. The USB cable is a power only cable and has no data lines. However, this is unlikely because, whilst power-only USB cables are common with mobile phones (i.e. USB to Micro USB), a *full on* USB-A to USB-B cable, which is what the Uno uses, *normally* do not come in a power-only configuration.
2. The port is damaged on the laptop. This is unlikely, but it worth checking by connecting a keyboard or mouse to the same port, to see if data is transferred
3. You have no driver installed. This is the most likely scenario. Normally the Arduino will trigger a driver to be automatically installed. However, in the case of the cheap Chinese clones, which use the CH340G chip, then the CH340 driver will need to be installed, if you are using Windows. Check the Device Manager in Windows to see if you Uno is recognised when connected, or whether is is shown as an "Unknown Device". A quick google should provide you with the correct driver for the CH340G. Please note that, if you are using Linux, then no driver is required, see [Majenko's answer][1] to https://arduino.stackexchange.com/questions/33069/safe-place-to-download-ch340g-drivers-from.

  [1]: https://arduino.stackexchange.com/questions/33069/safe-place-to-download-ch340g-drivers-from#answer-33072


body:
I have a short program which should receive data, use this data to turn on/off an LED, and send data when a button is pressed. It is deployed on a Digispark board. The button is connected to `INT0` port (PB2). The interrupt works, but data is not send. Receiving data works fine.

What am I missing here?

    #include <SoftSerial.h>

    #define RxD 1
    #define TxD 0
    #define out 3
    #define btn 2
    #define testled 4

    SoftSerial blueToothSerial(RxD, TxD); //RX, TX
    volatile int buttonState = 0;

    void setup() {
      pinMode(out, OUTPUT);
      pinMode(btn, INPUT);
      pinMode(testled, OUTPUT);
      setupBlueToothConnection();
      digitalWrite(out, HIGH);
      digitalWrite(testled, HIGH);
      attachInterrupt(0, intrpt, CHANGE);
    }

    void loop() {
      char newVal;
      if(blueToothSerial.available()){
        newVal = blueToothSerial.read();
        if (newVal == '1') {
          digitalWrite(out, HIGH);
        } else {
          digitalWrite(out, LOW);
        }
      }
    }

    void intrpt() {
      buttonState = digitalRead(btn);
      if (buttonState == HIGH) {
        // turn LED on:
        digitalWrite(testled, HIGH);
      } else {
        // turn LED off:
        digitalWrite(testled, LOW);
        blueToothSerial.println("0");
      }
    }

    void setupBlueToothConnection() {
      blueToothSerial.begin(9600);
      blueToothSerial.print("\r\n+STWMOD=0\r\n");
      blueToothSerial.print("\r\n+STNA=HC-05\r\n");
      blueToothSerial.print("\r\n+STOAUT=1\r\n");
      blueToothSerial.print("\r\n+STAUTO=0\r\n");
      delay(2000);
      blueToothSerial.print("bluetooth connected!\n");
      delay(2000);
      blueToothSerial.flush();
    }

**EDIT**

Serial data is sent fine. The above code works. On Windows I can see the data are coming, but not on OS X.

title: Serial data is not sent on interrupt

Answers: 1

body:
If you are handling interrupts then you need to keep the code as quick and simple as possible.  I suspect that in this case calling `blueToothSerial.println` is what's causing the problem. It may well be calling an operation that an ISR can't call and so it fails and your code doesn't write the data you expect it to.

All I ever do in ISRs is set flags and then get the 'normal' code to handle changes to the flags. Personally I wouldn't do the digitalWrites within the ISR. Have two volatile variables, one for the pin state and one when sending a message is required and handle those in your `loop()`.


body: So I'm trying to work on a project and need to include bluetooth. The latest problem I have is I'm using a Lilypad Arduino and need to keep the project in the same round area. I was looking at this: https://www.sparkfun.com/products/12580 however I'm not sure how I would make it smaller? Does it have to clip on or can I simply solder it in a way that it's resting directly above/below the Lilypad?

title: Best Bluetooth module for the Lilypad?

Answers: 0


body:
I'm using the Arduino's site test code for getting raw values from a MPU-6050 accelerometer + gyro. In the loop, there are this lines for getting the next data from its registers:

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

    Wire.requestFrom(MPU_addr, 14, true);  // request a total of 14 registers

    AcX = Wire.read()<<8 | Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    AcY = Wire.read()<<8 | Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    AcZ = Wire.read()<<8 | Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
    Tmp = Wire.read()<<8 | Wire.read();  // 0x41 (TEMP_OUT_H)   & 0x42 (TEMP_OUT_L)

    GyX = Wire.read()<<8 | Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
    GyY = Wire.read()<<8 | Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
    GyZ = Wire.read()<<8 | Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

Hex numbers indicates, of course, the address of each register. However, I can't get how, if the first instruction only requests from the MPU_addr (constant), it changes to the consecutive registers. Is it that `<<8|` makes something like a sum or a logic OR to switch the register to read?

Regards!

title: What does this notation stands for? Wire.read() <<8 | Wire.read()

Answers: 2

body:
1 << 3 means the value 1 shifted 3 times to the left. So 1 in binary is 0000001, shifted left 3 places is 00001000. And 0001101 << 3 will be 1101000.

The | command is a logic or (where bits will be 1 if one of the bits is 1, e.g. 001100 | 001001 = 001101.

Probably every Wire.read() gives the next byte.
For the first line: Acx = Wire.read() << 8 | wire.read() means one (mostly the first byte) is read, it is shifted to the left one byte and the other (mostly next byte) read is placed in the right. So it results in the first two read bytes to be positioned in AcX. It is semantically the same as Wire.read() * 256 + Wire.read(), but normally a bit shift is easier for a computer, same as | and the + operator.

body:
Just adding a couple of points to Michel Keijzers's answer.

The expression `Wire.read() << 8` takes the value returned by
`Wire.read()`, which is an `int`, and shifts it 8 bits to the left,
which is equivalent to multiplying by 256. If you are using a 32-bit
microcontroller (e.g. an Arduino Due), this is safe. However, most
Arduinos are based on an 8-bit AVR chip. On them, an `int` is 16-bits
and can only hold values up to 32767. If the initial value is larger
than 127, then the bit shift causes a signed integer overflow, which in
C and C++ is _undefined behavior_ (read: “illegal operation”). It is
_likely_ that everything runs fine and you get the expected result, but
it is unwise to ever rely on undefined behavior in C or C++.

The proper way to do the shift is to cast the initial value to an
unsigned data type, which is always safe v.s. overflows, and then do the
shift, like in

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

    ((uint16_t) Wire.read()) << 8

You may omit the outer parentheses if you know your operator priorities.

The second point is about the already mentioned fact that the order of
the reads is not specified. The simplest fix is to do one read per
statement, as in:

    AcX = (uint16_t) Wire.read() << 8;  // first read MSB
    AcX |= Wire.read();                 // then LSB

It is worth noting that the first statement has an implicit cast from
`uint16_t` (the result of the shift) to `int16_t` (the type of `AcX`).
This can also overflow if the shifted value is larger than 32767.
However, an overflow happening during a conversion in _not_ undefined,
but rather _implementation defined behavior_. This means that the
authors of the compiler must decide and document what happens. Arduino
code is usually compiled by gcc, and [the gcc docs document this
behavior][gcc doc] as

> • _The result of, or the signal raised by, converting an integer to a
> signed integer type when the value cannot be represented in an object
> of that type (C90 6.2.1.2, C99 and C11 6.3.1.3)._
>
> For conversion to a type of width N, the value is reduced modulo 2^N
> to be within range of the type; no signal is raised.

This is exactly what we want here, and since it is the most efficient
choice on a two’s complement architecture, it seems unlikely that
another compiler would make a different choice.

[gcc doc]: https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html#Integers-implementation


body:
I'm a noob when it comes to time-based coding.

I have a pressure sensor which shows me readings for when someone is sitting on a chair.

I want to turn a motor for 2 seconds when the pressure sensor says occupied
I want to turn the motor the other way for 2 seconds when the pressure sensor says empty.

Also after the motor has turned for 2 seconds, I don't want it to turn the motor at all until the reading of the pressure has changed to the other reading.

Here is my code.

    #include <AFMotor.h>
    AF_DCMotor motor(1,MOTOR12_64KHZ);
    AF_DCMotor motor2(2,MOTOR12_64KHZ);
    int fsrPin = 0;     //FSR and 10K resistor are connected to pin 0
    int fsrReading;     //the analog reading from the resistor divider

    bool WheelLock = true;  //controls whether the wheelchair is locked or not
    long startTime = millis();
    long stopTime = startTime;

    void setup(void){
      Serial.begin(9600);
      motor.setSpeed(255);
      startTime = 0;
      stopTime = 5000;
    }

    void loop(){
      while(startTime < stopTime){
        if(onChair() == false){
          motor.run(BACKWARD);
          startTime = millis();
        }
        else{
          motor.run(FORWARD);
          startTime = millis();
        }
      }
      motor.run(RELEASE);
      Serial.println("RELEASED");
      startTime = 0;
      Serial.println(startTime);
    }

    bool onChair(){
      fsrReading = analogRead(fsrPin);

      if(fsrReading > 800){
        Serial.println("Wheelchair is occupied");
        WheelLock = false;
      }

      else{
        Serial.println("Wheelchair is empty");
        WheelLock = true;
      }
      delay(200);
      return WheelLock;
    }

title: Run motor for a set amount of depending of Pressure Sensor

Answers: 3

body:
I think you want something like this:

    int motorRunSecs = 2
    bool chairLastState = false;
    bool chairCurrState = false;
    int motorDirection = FORWARD;

    void loop() {
        chairCurrState = onChair();

        // if the chair occupied state has changed, then do something
        if (chairCurrState != chairOccupied) {

            // set the motor Direction based on the state of the chair
            motorDirection = ((chairCurrState) ? FORWARDS : BACKWARDS);

            // run motor for X secs
            motor.run(motorDirection);
            delay(motorRunSecs * 1000);
            motor.run(RELEASE);

            // now update the last chair state
            chairLastState = chairCurrState;
        }
    }

body:
You really want to look at the finite state machine to model your problem.
With this, you are looking at states and the transition between states.

In your problem, for example, you want to turn on a motor for a certain length of time
after the chair state changes from empty to occupied. However, in your code you are not retaining
the previous state (empty or occupied) so you cannot act when there is a state change fom empty to occupied.

Here is some rough C++ code to show you how this could work in paractice.

    // states:
    // ChairOccupancyState: occupied; empty
    // MotorState: on; off

    // pseudo code

    loop() {
       if ( ChairOccupancyState == empty && onChair == true ) {
          // we have a transition from empty to occupied
          // switch motor on direction 1
          motorState = on ;
          // record time
          motor_on_at_ms  = millis() ;
          ChairOccupancyState = occupied ;
       }

       if ( ChairOccupancyState == occupiedy && onChair == false ) {
          // we have a transition from occupied to empty
          // switch motor on direction 2
          motorState = on ;
          // record time
          motor_on_at_ms  = millis()
          ChairOccupancyState = empty ;
       }

       If (motorState == on && millis() - motor_on_at_ms > 2000 ) {
          motorState == off ;
          // switch motor off
       }

    }

body:
Fairly easy.

You have to determine if the pressure has changed from its previous reading.

If it has, you can start to turn the motor for two seconds.

Once the time is up, turn the motor off.

Once you put your code in that framework, it would be much easier to code top down.


body:
For this project I seek to create a counter of water glasses we drank throughout the day.
I use for this an **Arduino UNO card**, a **Piezo buzzer** and a **Neopixel rgb LEDs strip** (5 LEDs for this test).

Aside from the last 2 LEDs that only light up to indicate to the user that his presence is considered by the product, I would like that when the HC-SR04 first detects our glass of water between 0 and 5cm (*cheers!*), the first LED lights up and stays on. When the first LED is on and the HC-SR04 detects a second time our water glass is between 0 and 5cm, then the second LED lights up and stays on as well. And so on.
For each glass detected between 0 and 5cm, a slight sound sounds through the piezo buzzer.

By using the **Adafruit Neopixel library** ([download here][1]), I manage to make everything work as I see fit. However, I still have trouble programming if the LED *n* is on then the *n+1* LED lights up at the next detection between 0 and 5cm, without all the LEDs lighting at the same time in a single detection.

I recently tried to use a boolean to identify when the LED *n* is *true* (ON/HIGH), but unsuccessfully. I leave you my code as is by thanking you for any help you can bring me.

See my layout and my code below:
[![Arduino UNO + Components layout][2]][2]

    #include <Adafruit_NeoPixel.h>

    const int trigPin = 9;
    const int echoPin = 10;
    const int buzzer = 11;

    #define dinPin 4
    #define numLEDs 5

    Adafruit_NeoPixel strip = Adafruit_NeoPixel(numLEDs, dinPin, NEO_GRB + NEO_KHZ800);

    long duration;
    int distance;

    int blue;
    int green;
    int off;

    boolean lightLED = false;

    void setup() {
      strip.begin();
      strip.setBrightness(80);
      strip.show();

      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
      pinMode(buzzer, OUTPUT);
      Serial.begin(9600);
    }

    void loop() {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);

      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      duration = pulseIn(echoPin, HIGH);

      distance = duration * 0.034 / 2;

      uint32_t blue = strip.Color(0, 100, 255);
      uint32_t green = strip.Color(0, 255, 20);
      uint32_t off = strip.Color(0, 0, 0);

      ///////////////////////////////////////////////////////////
      // LED 1 + Buzzer
      ///////////////////////////////////////////////////////////

      if (distance <= 5) {

        if (! lightLED) {
          strip.setPixelColor(0, blue);
          strip.show();
          delay(0);
        }

        else {
          lightLED = false;
        }

        digitalWrite(buzzer, HIGH);
        tone(buzzer, 400, 100);
        delay(75);
        tone(buzzer, 600, 100);
        delay(75);
        tone(buzzer, 800, 100);
        delay(75);
        noTone(buzzer);

      }

      else {
        digitalWrite(buzzer, LOW);
      }

      ///////////////////////////////////////////////////////////
      // LED 2
      ///////////////////////////////////////////////////////////

      if (lightLED && distance <= 5) {

        lightLED = true;

        if (! lightLED) {
          strip.setPixelColor(1, blue);
          strip.show();
          delay(0);
        }
      }

      ///////////////////////////////////////////////////////////
      // DETECT USER PRESENCE
      ///////////////////////////////////////////////////////////

      if (distance >= 6 && distance <= 20) {
        strip.setPixelColor(3, green);
        strip.setPixelColor(4, green);
        strip.show();
        delay(0);
      }

      else {
        strip.setPixelColor(3, off);
        strip.setPixelColor(4, off);
        strip.show();
        delay(0);
      }

      // Voir la distance dans le moniteur
      Serial.print("Distance: ");
      Serial.println(distance);
    }

Sorry for the code that is a bit rough, I am a beginner but I hope not to have lost you in my explanations (I lose myself in my code…).

Thanks,

Thibaut

  [1]: https://github.com/adafruit/Adafruit_NeoPixel
  [2]: https://i.stack.imgur.com/ypueL.png

title: Turn on one by one the LEDs of a Neopixel rgb LEDs strip for each detection at the same distance from an Ultrasonic Distance Sensor (HC-SR04)

Answers: 0


body:
The program plays a random mp3 file from an Adafruit mp3 breakout board. The trigger to play the song is a sharp IR sensor. Basically to play a file you pass your hand over the sensor and it plays the full track. If you want to stop the file playing pass your hand over again and it switches it to an off mode.

I wrote a `while` statement using `millis()` to keep track of time. I would like for the songs to keep playing for a defined time or if you pass your hand over it, it stops playing the music.

Right now it's only playing a single file. It appears that the if statement I have in the while loop is being ignored. The program goes straight to break when the file is played.

    //----------------------------------------------------------
    // MUSIC PLAYER
    // vonderasche
    // 3/26/2017
    //----------------------------------------------------------

    // include SPI, MP3 and SD libraries
    #include <SPI.h>
    #include <Adafruit_VS1053.h>
    #include <SD.h>
    #include <SharpIR.h>

    // constants
    #define ir A4
    #define model 1080
    #define TRIGGER_PIN  5
    #define ECHO_PIN     6
    #define MAX_DISTANCE 200

    // These are common pins between breakout and shield
    #define DREQ 3
    // VS1053 Data request, ideally an Interrupt pin
    // DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
    #define CARDCS 4 // Card chip select pin
    // These are the pins used for the breakout example
    #define BREAKOUT_DCS 8
    // VS1053 Data/command select pin (output)
    // used to be pin 8
    #define BREAKOUT_RESET  9 // VS1053 reset pin (output)
    #define BREAKOUT_CS     10 // VS1053 chip select pin (output)

    Adafruit_VS1053_FilePlayer musicPlayer =
    // create breakout-example object!
    Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS,     DREQ, CARDCS);

    SharpIR SharpIR(ir, model);

    int state = 1;
    const unsigned long onTimer = 1200000;

    /// File listing helper
    void printDirectory(File dir, int numTabs) {
      while (true) {
        File entry = dir.openNextFile();
        if (!entry) {
          // no more files
          break;
        }
        for (uint8_t i = 0; i<numTabs; i++) {
          Serial.print('\t');
  }
        Serial.print(entry.name());
  if (entry.isDirectory()) {
          Serial.println("/");
          printDirectory(entry, numTabs + 1);
  } else {
          // files have sizes, directories do not
          Serial.print("\t\t");
          Serial.println(entry.size(), DEC);
  }
  entry.close();
   }
    }

    // random seed function
    int rNumbers(int rNum) {
      randomSeed(analogRead(3));
      rNum = random(1, 10);
      return rNum;
    }

    // play a certain file
    void playFile(int rNum) {
      switch (rNum) {
        case 1:
          Serial.println(F("Playing track 001"));
          musicPlayer.startPlayingFile("track001.mp3");
          break;
        case 2:
          Serial.println(F("Playing track 002"));
          musicPlayer.startPlayingFile("track002.mp3");
          break;
        case 3:
          Serial.println(F("Playing track 003"));
          musicPlayer.startPlayingFile("track003.mp3");
          break;
        case 4:
          Serial.println(F("Playing track 004"));
          musicPlayer.startPlayingFile("track004.mp3");
          break;
        case 5:
          Serial.println(F("Playing track 005"));
          musicPlayer.startPlayingFile("track005.mp3");
          break;
        case 6:
          Serial.println(F("Playing track 006"));
          musicPlayer.startPlayingFile("track006.mp3");
          break;
        case 7:
          Serial.println(F("Playing track 007"));
          musicPlayer.startPlayingFile("track007.mp3");
          break;
        case 8:
          Serial.println(F("Playing track 008"));
          musicPlayer.startPlayingFile("track008.mp3");
          break;
        case 9:
          Serial.println(F("Playing track 009"));
          musicPlayer.startPlayingFile("track009.mp3");
          break;
        case 10:
          Serial.println(F("Playing track 010"));
          musicPlayer.startPlayingFile("track010.mp3");
          break;
        }
      }

    void setup() {
      Serial.begin(9600);
      Serial.println("Adafruit VS1053 Simple Test");
      if (!musicPlayer.begin()) {
        // initialise the music player
        Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
        while (1);
      }
      Serial.println(F("VS1053 found"));
      if (!SD.begin(CARDCS)) {
  Serial.println(F("SD failed, or not present"));
  while (1); // don't do anything more
      }
      // list files
      printDirectory(SD.open("/"), 0);
      // Set volume for left, right channels. lower numbers == louder volume!
      musicPlayer.setVolume(30, 30);
      // Timer interrupts are not suggested, better to use DREQ interrupt!
      //musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT);
      // timer int
      // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
      // audio playing
      musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT); // DREQ int
    }

    void loop() {
      // calls random number function
      int randomNumber;
      // takes distance measurment
      float distance = (SharpIR.distance() / (2.4));
      static enum { ON, OFF } state;
      // if distance range is between certain values switch the state
      if (distance > 1 && distance < 12) {
        switch (state) {
          case ON:
            {
   unsigned long previousMillis = millis();
   unsigned long currentMillis = millis();
            while ((currentMillis - previousMillis) < onTimer) {
              Serial.println("inside while loop");
              randomNumber = rNumbers(randomNumber);
              // calls random number function
              playFile(randomNumber); // plays music file
              float distance2 = (SharpIR.distance() / (2.4));
              delay(1000);
              //breaks timer if hand swipe
              if (distance2 > 2 && distance2 < 8) {
                Serial.println("Break");
                break;
              }
              currentMillis = millis();
            }
            state = OFF;
          }
          break;
        case OFF:
          {
          Serial.println("Triggered Off");
          musicPlayer.stopPlaying();
          state = ON;
          }
          break;
        }
      };
    }

title: Issue with IF statement

Answers: 2

body:
There's probably a good chance that when you trigger the ON state by placing your hand close to the sensor, the while loops runs and hits the if statement before you have moved your hand out of the trigger distance.

I see the delay of 1 second before the if, however, you take the reading of the IR sensor before the delay.

Try the delay before reading the sensor:

            ...
            playFile(randomNumber);  // plays music file

            delay(1000); // let the user move their hand
            float distance2 = (SharpIR.distance() / (2.4));

            //breaks timer if hand swipe
            if (distance2 > 2 && distance2 < 8)
            {
            ...

If you wanted to remove the delay function (highly recommended) after playing the file, set the state to something like PLAYING.

Then in the PLAYING state switch case you first wait for an IR reading that there is no hand present (allowing the user to finish moving their hand away), set a flag that you are ready to detect the hand. Then if that flag is true and the IR sensor reads a hand, then you can move to the OFF state.

You can add a second condition to the PLAYING state to test for elapsed time as well.

body:
The intent of some of your code isn't clear, and the description “The program goes straight to break when the file is played” looks wrong – it appears that at least one `delay(1000)` will occur between start and break, so perhaps you mean that about a second after playing starts, it breaks.

If so, here is a possible explanation of that behavior:

1. At the beginning of `loop()`, you say `distance = (SharpIR.distance() / (2.4));`

2. Suppose that results in a value between 2 and 8.  Then the `if` condition `(distance > 1 && distance < 12)` will be true, so the body of the `if` will execute.

3. `state` initially is `ON` (`state` is static, and per §6.7.9.10 of the N1570 C++ spec, apparently gets initialized to 0, which corresponds to `ON`) and will be `ON` after each execution of the `OFF` case in `loop()`.

4. When `state` is `ON`, we proceed into the `ON` case of the `switch`, set some variables to current time, then use a few microseconds to serial-print and call `rNumbers()` and `playFile()`.  Then `distance2 = (SharpIR.distance() / (2.4));` sets `distance2` to about the same value read a few microseconds earlier into `distance`; as we supposed earlier, a number between 2 and 8.

5. With `delay(1000)`, the program sits for a second doing nothing and paying attention to nothing.

6. The `(distance2 > 2 && distance2 < 8)` condition for the next `if` is  true, so program prints "Break", breaks out of the `while`, turns off `state`, breaks out of the `switch`, exits `loop()`, enters `loop()`, etc.

However, now that a second has gone by, the Sharp sensor shouldn't be reading a gesture.  If it is, that will allow the `OFF` case to execute and call `musicPlayer.stopPlaying()`.

---

Note, issue the `randomSeed(analogRead(3))` call only once, and do so within `setup()`.  Calling it within each `rNumbers()` call is going to give you non-random numbers.


body:
I am making a high-range and fast obstacle detection system.

The HC-04 is too slow for that, other sensors don't have the range, and Lidar is too costly.

Any idea how to make a long range (more than 10 m) high-speed obstacle detection system?

title: High-range obstacle detection system

Answers: 1

body: You can Use PIR Sensor which is Cost Effective and covers upto 10 Meters


body:
I am using this code.. But everytime after one rfid tag is read by the reader, I have to manually press the reset button on the arduino before scanning the next tag. I want to do this operation after every 10 or 20 seconds from one tag scanning without manually pressing the reset button. What changes I have to make to this code??

    /*
    * source: http://www.electroschematics.com/11301/arduino-rfid-reader-rc522-access-control-system/
    * Read a card using a mfrc522 reader on your SPI interface
    * Pin layout should be as follows (on Arduino Uno):
    * MOSI: Pin 11 / ICSP-4
    * MISO: Pin 12 / ICSP-1
    * SCK: Pin 13 / ISCP-3
    * SS: Pin 10
    * RST: Pin 9
    */

    #include <SPI.h>
    #include <RFID.h>
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address----------------------------------------------

    #define SS_PIN 10
    #define RST_PIN 9

    RFID rfid(SS_PIN,RST_PIN);

    int startAlarm = false;
    int resetAlarm = 2;
    int relay = 6;
    int alarm = 8;

    int serNum[5];

    int cards[][5] = {
      {00,162,227,135,198} // card 1

    };

    bool access = false;

    void setup()
    {
      // Setup size of LCD 20 characters and 2 lines
      lcd.begin(20,2);    //------------------------------------------------------
      // Back light on
      lcd.backlight();  //---------------------------------------------------------

      lcd.setCursor(0,0);         //----------------------------------------------
      lcd.print("SCAN your ID");   //------------------------------------------------

        Serial.begin(9600);
        SPI.begin();
        rfid.init();
        pinMode(resetAlarm, INPUT);
        pinMode(relay, OUTPUT);
        pinMode(alarm, OUTPUT);
        digitalWrite(relay, HIGH); // or LOW if you have a regular relay------------------------------(ALREADY CHANGED)
        attachInterrupt(0, reset_alarm, LOW);
    }

    void loop()
    {

        if(rfid.isCard()){

            if(rfid.readCardSerial()){
                Serial.print(rfid.serNum[0]);
                Serial.print(",");
                Serial.print(rfid.serNum[1]);
                Serial.print(",");
                Serial.print(rfid.serNum[2]);
                Serial.print(",");
                Serial.print(rfid.serNum[3]);
                Serial.print(",");
                Serial.print(rfid.serNum[4]);
                Serial.println("");

                for(int x = 0; x < sizeof(cards); x++){
                  for(int i = 0; i < sizeof(rfid.serNum); i++ ){
                      if(rfid.serNum[i] != cards[x][i]) {
                          access = false;
                          break;
                      } else {
                          access = true;
                      }
                  }
                  if(access) break;
                }

            }

           if(access){
              Serial.println("Welcome!");
              startAlarm = false;
              digitalWrite(relay, LOW); // HIGH with regular relay (I have already changed the code)  //------------------------------
              lcd.setCursor(0,0);   //----------------------------------------------------------------------------------------------
              lcd.print("Access Granted");  //-------------------------------------------------------------------------------------------
              delay(3000);
              lcd.clear();
              lcd.setCursor(0,0);         //----------------------------------------------
              lcd.print("SCAN your ID");   //------------------------------------------------
                 //---------------------------------------------------------------
           } else {
               Serial.println("Not allowed!");
               startAlarm = true;
               digitalWrite(relay, HIGH);  // LOW with regular relay (I have already changed the code)----------------------------------
               lcd.setCursor(0,0);         //------------------------------------------------------------------------------------
               lcd.print("Invalid Access ");        //------------------------------------------------------------------------------------
               delay(3000);
               lcd.clear();                            //--------------------------------------------
               lcd.setCursor(0,0);         //----------------------------------------------
               lcd.print("SCAN your ID");   //------------------------------------------------

           }
        }

        if(startAlarm) {
           digitalWrite(alarm, HIGH);
        } else {
          digitalWrite(alarm, LOW);
        }

        rfid.halt();

    }

    void reset_alarm(){
        startAlarm = false;
    }

title: How to reset the arduino uno after 5 seconds?

Answers: 2

body:
I would think the rfid library would be able to read multiple cards in a row... however I'm not familiar with it.

Here is an answer from a similar question about how to initiate a hardware reset with software using the watchdog timer - https://arduino.stackexchange.com/a/1478/31106 :

> The SoftReset library makes it easy. Although it is not difficult to
> implement directly. Shown below..
>
>     #include <avr/wdt.h>
>     ...
>     setup() {
>
>       ...
>       MCUSR = 0;  // clear out any flags of prior resets.
>       ...
>
> then when desired...
>
>     ...
>     wdt_enable(WDTO_15MS); // turn on the WatchDog and don't stroke it.
>     for(;;) {
>       // do nothing and wait for the eventual...
>     }
>     ...

body:
This may not be your only issue, but I think you are using `sizeof()` wrongly.  This 'function' returns the number of bytes occupied by a variable or type OR the number of bytes occupied by an array.

So

    1 == sizeof(char)
    6 == sizeof ("Hello")  // Because of the trailing null
    2 == sizeof(int)
    int cards[][5] = {
                      {00,162,227,135,198} // card 1
                     };
    10 == sizeof (cards)

So you line that says `for(int x = 0; x < sizeof(cards); x++){` is happening 10 times, not once.

Personally I would never use sizeof to measure the size of an array, but if you have to then you need to do this:

    size = sizeof (cards) / sizeof (int)


body:
I'm trying out computer to computer serial communication using 2 Arduino Unos (both connected to different computers).
Right now, I use the Software Serial library, which redirects data from the SoftwareSerial ports to the hardware Serial (over USB to the PC).

Is there any way to bypass the 328p chip, and only use the 16U2, which works as a USB to Serial converter?
Will the circuit in the diagram work? By connecting the GND to RST on both the Unos, the 328p gets disabled, which in theory should all me to directly tap into the serial line of the 16U2.

[![Circuit][1]][1]

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

title: Arduino Uno as USB to Serial converter (bypass 328p)

Answers: 2

body:
As per your diagram, ground the reset pin on both Arduinos and connect TX to RX on the one to RX to TX on the other. Alternatively, if your Unos have a socketed 328P, you can remove it.

(This answer summarized from the comments above in order to take it off the "unanswered" list.)

body:
The circuit you have drawn will work for PC to PC coms. Essentially your connection diagram looks like this:

`PC1` -(USB)- `Arduino1` -(TTL serial)- `Arduino2` -(USB)- `PC2`

To answer your second question, you can bypass the 328p chip by removing them both as they are not needed. The 16U2 converts the USB to TTL serial which it provides to the Arduino on pins 0 and 1. Since the ATmega328p microcontrollers aren't being used (ie in reset state) then you may as well remove them and use them on another project.


body:
I am trying to move servos with a VR headset, I am using the Unreak 4 Arduino Plugin, but that is not the problem. I send the rotation Y and Z from the headset, convert them to int and then send them together as an int separated by commas. Here's what it does: It gets the rotation Z, it converts it to int, then it converts it to String, I add a comma at the end of the String, then I add the rotation Y after the comma, and it returns me: "rotationZ","rotationY" (the values between " are the numbers sent by Unreal to arduino), these results may come in negative or positive value.

Then inside arduino I have this code:

    #include <Servo.h>
    #include <SoftwareSerial.h>

    Servo servo1;
    Servo servo2;  // Crea un Objeto servo

    int angle = 10;
    int posicion = 10;    // Variable de la posicion del servo

    String user_input1;

    int r;
    int g;

    void setup()
    {
      Serial.begin(9600);
      servo1.attach(2);  // Selecionamos el pin 2 como el pin de control para el servo
      servo2.attach(3);  // Selecionamos el pin 2 como el pin de control para el servo

      servo1.write(0);
      servo2.write(0);

      Serial.setTimeout(5);
    }

    void loop()
    {
      if (Serial.available() > 0)
        {
      String firstValue  = Serial.readStringUntil(',');
     // String first = Serial.readString(); //next character is comma, so skip it using this
      String secondValue = Serial.readStringUntil(',');
    //  String second =  Serial.readString();

       r = firstValue.toInt();
       g = secondValue.toInt();
        }
      if (r < 0)
      {
        r = r * -1;
      }

      if (g < 0)
      {
        g = g * -1;
      }

      Serial.println(r);
      Serial.println(g);

      servo1.write(r);
      servo2.write(g);

    }

As you can see, it gets the numbers between the commas and then it converts them to int, and then it applies to the servos which are in pins number 2 and 3 (yes, everything is plugged in correctly), which it should then move them acordingly the position of the VR headset, I've also tried to make them always receive positive results but still doesn't work. I have searched over the internet on how to separate a string divided by commas and I still don't know if it's correctly done.

EDIT: I also tried to input the numbers in the console manually, and it gets them right and moves the servos but it still doesn't work with the VR. I also added Serial.setTimeout(5) to try if it works that way.

Thanks in advance for reading this bunch'o text about my problem.

title: Sending a string to arduino and is not reacting to it

Answers: 1

body:
> I also tried to input the numbers in the console manually, and it gets them right and moves the servos but it still doesn't work with the VR.

This implies that the problem is in the code sending the data.  Get a terminal emulator program and hook that up to the code generating the data from the VR headset (you will need 'local echo' turned on).  I suspect you will see the headset is not writing the data in the format you expect.  Also it will let you capture a real sample of data that you can feed into you program to generate a repeatable test.

If this isn't the fault, then please can you post the a few lines of data so we can see whats wrong.


body: The datasheet of MQ5 sensor says, it requires a pre-heat of 24 hours. Does this mean that it needs to be powered on for 24 hours consecutively before usage? Some other websites (e.g. http://www.circuitstoday.com/interfacing-mq5-lpg-sensor-to-arduino) say that 15 minutes pre-heat would suffice. Could someone clarify this issue? Thanks.

title: Pre-heat time required for MQ-5 gas sensor

Answers: 2

body:
Please be clear when you mean the one time only pre-heat and when you mean turning the sensor on to take a measurement.

It is a electrochemical sensor and it needs time to burn-in. During those 24 hours, the impedance of the sensor changes a lot. After those 24 hours it can be used in a normal way and it will return consistant values.

The pre-heat should be done just once. I mean: just once in the lifespan of the sensor. After buying it, you should run the pre-heat.
When the manufacturer writes in the datasheet that the pre-heat time is 24 hours, then you should do 24 hours.
I suggest to connect the sensor in a normal way, with 'A' en 'B' pins connected and with the load resistor, and keep it on for 24 hours. Maybe it is already stable after a few hours, but keep it on for 24 hours to be sure.

To take a measurement, the sensor needs time to warm up. About 5 minutes might be okay. I think that 2 minutes is definitely too short.
When the sensor is always at room temperature, and the time to warm up is always the same, then the measurement is relative accurate and can be compared with other measurements. That means that when the sensor is mostly turned off to save power, only a few minutes to warm up can be used. However, I would start with at least 5 minutes.

[**EDIT**] The datasheets and other information from the manufacturers use the term "pre-heat" in different ways. The Technical Note in the link by @EnricBlanco uses the term "preheating" only for the "one-time-only" heating after storage to make the sensor more stable, as far as I can tell. Although it is not "one-time-only", it should be applied after storage or changing conditions as well. @EnricBlanco, try a very cheap MQ gas sensor (which is probably not preheated in the factory) and see how the impedance changes a lot during the first hours of preheating, and becomes stable after a few hours.

body:
> Does this mean that it needs to be powered on for 24 hours
> consecutively before usage?

No, it just means that typical performance data in the datasheet has been measured after 24h. So, if you want to be within specification you must observe that 24h preheating time.

Does it mean you can't use the sensor before those 24h? Absolutely not. Given the small size of the sensor, thermal equilibrium will be almost surely reached within 30 min. And it would probably take just a few minutes to be within +/- X % of the specification (you can only know by actually measuring how much time does the output need to stabilise, which you should do).

At the end, **the time to wait for thermal stabilisation of the sensor (preheating time) will depend on your application**.

Only if you want a very accurate measure of gas concentration, you will need to wait those 24h (and also have a good calibration of your sensor, as well as means to compensate other environmental factors like temperature, humidity, etc.). But if you wanted to do this kind of measurement you probably won't be using a MQ-5 sensor anyway.

**EDIT:**

Take a look at this excellent [technical note][1] from Figaro Sensors to better understand the preheating time. It ISN'T a burn-in time *per se*, but a stabilisation time whose duration depends on several factors.

  [1]: http://www.figarosensor.com/products/common(1104).pdf


body:
I have some several custom PCB's based on Atmega 2560.
I am using AVRISP MarkII for flashing. No bootloader.

Flashing is flawless, it just works. I have one assembled PCB works as it should be, no issues.

But, the other one has a quite time lag in its functions.
It has also been flashed OK but, it is not running quite OK.

**Here are my observations;**

By asserting Reset, I expect four leds on the pcb running (on and then off) by 100ms intervals one after each others. This is happening in the very beginning in Setup() section of the program.

**Note that:** Leds are connected to MCU via mosfets. If MCU output is LOW, they are ON and vice versa.

So, with this problematic PCB, all leds come ON all together after 10 seconds after pressing reset button and they stay almost 60 seconds before they start the sequence (on and then off) as coded.

And then that sequence is also slowly occurring. It is not 100ms as I coded but almost 4 seconds or so.

I am suspecting from the external clock (16Mhz) circuitry but I can't proof it accurately as I don't have oscilloscope at hand.

You may see the simple code I use to test that behavior;

    void TestLeds() {
     unsigned long interval = 100;

     digitalWrite(LED1_PIN, LOW);
     delay(interval);
     digitalWrite(LED1_PIN, HIGH);
     delay(interval);

     digitalWrite(LED2_PIN, LOW);
     delay(interval);
     digitalWrite(LED2_PIN, HIGH);
     delay(interval);

     digitalWrite(LED3_PIN, LOW);
     delay(interval);
     digitalWrite(LED3_PIN, HIGH);
     delay(interval);

     digitalWrite(LED4_PIN, LOW);
     delay(interval);
     digitalWrite(LED4_PIN, HIGH);
    }

How/where should I check the bottle-neck on that?

Thank you.

**EDIT:**

To be more specific, I add this output regarding programming;
[here][1]

  [1]: https://www.dropbox.com/s/77f1mig7q91d34j/Output of Programming with AVRISP mkII.txt?dl=0

title: Too slow start up with Atmega2560 on custom PCB

Answers: 2

body:
I am closing the case. It is not 100% satisfaction though. Because, using Visual Studio with Visual Micro didn't help me on that issue in a natural way but something else.

For the future reference for somebody might get benefit out of this, I like to explain here what I did to get over this issue briefly. As @Gerben (big credits go to him) has pointed the right direction, I did check fuses by installing Atmel Studio 7 and use its programmer.

Yes, the fuses were completely wrong. I have therefore read the fuses from my healthy PCB and noted aside and then applied these very same fuse settings to the slow working PCB. I have just programmed the fuses, Firmware was the one I programmed earlier in the uC. So, voilà, the slowness has gone.

I think I am going to use Atmel Studio 7 now on next to Visual Studio as it has everything built-in including Arduino support.

Thanks everybody involved.

body: Just burn the bootloader via  arduino ide before you burn your firmware. During bootloader burning, ide also configures the fuse bits you needed.


body: How to obtain four PWM outputs at 100 kHz using an arduino uno board? The requirement is that all four PWM outputs should have controllable duty ratios individually.

title: PWM generation using Arduino uno

Answers: 2

body:
You can't squeeze 100kHz out of an Arduino without a major software rewrite (at which point you will be using an AtMega chip rather than Arduino). `analogWrite` defaults to ~500Hz and can be boosted to [62.5kHz](http://playground.arduino.cc/Main/TimerPWMCheatsheet) on some Arduino models, and only for 2 pins. Other PWM pins are capped at 31.4kHz.

You can achieve 100kHz PWM by toggling pins manually and busy-waiting, but you won't be able to do anything else during this. Or you can make use of interrupts, which is a big leap from Arduino ecosystem as I already said.

body:
In a comment to Dmitry Grigoryev’s answer you wrote:

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

    void setup()
    {
        TCCR2A = 0x23;
        TCCR2B = 0x09;
        OCR2A = 159;
        pinMode(3, OUTPUT);
    }

    void loop()
    {
        OCR2B = 80;
    }

It seems you already have the solution to your problem: that's exactly
the way to do it!

Well, there is a catch: since you are using `OCR2A` to define the period
of your timer, this means you are left with a single PWM channel, where
the duty cycle is controlled by `OCR2B`. Given that the Arduino Uno has
only three timers, it would seem you can only have up to three PWM
channels at 100 kHz.

But there is a solution. Timer 1 has a feature the other timers
don't have: you can define its period using using the input capture
register `ICR1` instead of `OCR1A`. This leaves you both output compare
registers available for PWM. For this you have to set the timer into
waveform generation mode 14, i.e. fast PWM with TOP = ICR1.
Now you can have your four channels, with Timer 0 driving
pin 5, Timer 2 driving pin 3, and Timer 1 driving
pins 9 and 10.

Some caveats:

* As already pointed out by Dmitry Grigoryev, your PWM resolution is
  slightly reduced.

* By reconfiguring Timer 0, you loose the Arduino Timekeeping function
  `millis()`, `micros()` and, `delay()`. You could write your own ISR to
  count the overflows of some other timer, but it would be called every
  10 µs: even if it is very short it would eat a non-trivial
  fraction of your CPU power.