message:
GPS(Incorrect time showing)

Anyone help? It shows incorrect time. Please help.

      /* Conexion pines
         Arduino        GPS
            D3           RX
            D4           TX
      */

      #include <SoftwareSerial.h>  //incluimos SoftwareSerial
      #include <TinyGPS.h>         //incluimos TinyGPS

      TinyGPS gps;  //Declaramos el objeto GPS
      SoftwareSerial serialgps(10,11);      //Declaramos el pin 4 (Tx del GPS) y 3 (Rx del GPS)

      //Declaramos la variables para la obtención de datos
      int year;
      byte month, day, hour, minute, second, hundredths;
      unsigned long chars;
      unsigned short sentences, failed_checksum;

      void setup()
      {
       Serial.begin(9600);  //Iniciamos el puerto serie
       serialgps.begin(9600); //Iniciamos el puerto serie del gps

       //Imprimimos en el monitor serial:
       Serial.println("");

      }

      void loop()
      {
       while(serialgps.available())
       {
        int c = serialgps.read();
        if(gps.encode(c))
        {
         float latitude, longitude;
         gps.f_get_position(&latitude, &longitude);
         Serial.print("Latitud/Longitud: ");
         Serial.print(latitude,5);
         Serial.print(", ");
         Serial.println(longitude,5);
         gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
         Serial.print("Date: "); Serial.print(day, DEC); Serial.print("/");
         Serial.print(month, DEC); Serial.print("/"); Serial.print(year);
         Serial.print(" Time: "); Serial.print(hour, DEC); Serial.print(":");
         Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC);
         Serial.print("."); Serial.println(hundredths, DEC);
         Serial.print("Altitud (metros): "); Serial.println(gps.f_altitude());
         Serial.print("Rumbo (grados): "); Serial.println(gps.f_course());
         Serial.print("Velocidad(kmph): "); Serial.println(gps.f_speed_kmph());
         Serial.print("Satelites: "); Serial.println(gps.satellites());
         Serial.println();
         gps.stats(&chars, &sentences, &failed_checksum);

         delay(10000);
        }
       }
      }

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

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

body:
Like Majenko's comments suggested, you must shift the UTC time to your local time.  The Time library can help you do this.

There are some other problems:

*  You cannot wait 10 seconds without processing the characters. The Arduino receive buffer only has room for 64 characters. The GPS device could have sent 10000 characters during that time, so most of them will get dropped. This prevents the GPS library from parsing a GPS data successfully.  It will eventually "see" a complete set of data, sometime after the 10 seconds.  You may see data once every 11 seconds, not 10.

*  You are printing the several values even though they may not be valid.  For example, if you are not moving, or you do not have good satellite reception, the GPS device may not provide a speed.

*  The Arduino `millis()` clock will not be synchronized with the GPS clock. You could use the GPS updates as an exact 1-second clock. Simply count 10 fixes as they arrive, and this will mean that 10 seconds have elapsed.

*  You should use a different serial port and/or library. [This answer](https://arduino.stackexchange.com/questions/34126#34130) describes the various choices: HardwareSerial (i.e. Serial on pins 0 & 1), AltSoftSerial (8 & 9 on an UNO) or NeoSWSerial (any two pins).

Here is a [NeoGPS](https://github.com/SlashDevin/NeoGPS) version of your sketch that addresses these issues:

    #include <NeoSWSerial.h>
    #include <NMEAGPS.h>

    NMEAGPS gps;  //Declaramos el objeto GPS
    gps_fix fix;  // all GPS fields, including date/time, location, etc.
    uint8_t fixCount;
    NeoSWSerial serialgps(10,11);

    void setup()
    {
     Serial.begin(9600);  //Iniciamos el puerto serie
     serialgps.begin(9600); //Iniciamos el puerto serie del gps

     //Imprimimos en el monitor serial:
     Serial.println( F("Test") );

    }

    void loop()
    {
     // Check for GPS characters and parse them
     if (gps.available( serialgps ))
     {
      // Once per second, a complete GPS fix structure is ready.  Get it.
      fix = gps.read();

      // Count elapsed seconds
      fixCount++;

      if (fixCount >= 10)
      {
        fixCount = 0; // reset counter

        // adjust from UTC to local time
        if (fix.valid.time)
          adjustTime( fix.dateTime );

        printGPSdata();
      }
     }
    }

    void printGPSdata()
    {
      Serial.print( F("Latitud/Longitud: ") );
      if (fix.valid.location) {
        Serial.print( fix.latitude(), 5 );
        Serial.print( F(", ") );
        Serial.print( fix.longitude(), 5 );
      }
      Serial.println();

      Serial.print( F("Date: ") );
      if (fix.valid.date) {
        Serial.print( fix.dateTime.date  ); Serial.print('/');
        Serial.print( fix.dateTime.month ); Serial.print('/');
        Serial.print( fix.dateTime.year  );
      }

      Serial.print( F(" Time: ") );
      if (fix.valid.time) {
        Serial.print( fix.dateTime.hours ); Serial.print(':');
        if (fix.dateTime.minutes < 10)
          Serial.print( '0' );
        Serial.print(fix.dateTime.minutes); Serial.print(':');
        if (fix.dateTime.seconds < 10)
          Serial.print( '0' );
        Serial.print( fix.dateTime.seconds );
        Serial.print('.');
        if (fix.dateTime_cs < 10)
          Serial.print( '0' );
        Serial.print( fix.dateTime_cs );
      }
      Serial.println();

      Serial.print( F("Altitud (metros): ") );
      if (fix.valid.altitude)
        Serial.print( fix.altitude() );
      Serial.println();

      Serial.print( F("Rumbo (grados): ") );
      if (fix.valid.heading)
        Serial.print( fix.heading() );
      Serial.println();

      Serial.print( F("Velocidad(kmph): ") );
      if (fix.valid.speed)
        Serial.print( fix.speed_kph() );
      Serial.println();

      Serial.print( F("Satelites: ") );
      if (fix.valid.satellites)
        Serial.println( fix.satellites );
      Serial.println();
      Serial.println();
    }

    //--------------------------

    void adjustTime( NeoGPS::time_t & dt )
    {
      NeoGPS::clock_t seconds = dt; // convert date/time structure to seconds

      // Offset to the local time
      const int32_t          zone_hours  = +8L;
      const NeoGPS::clock_t  zone_offset = zone_hours * NeoGPS::SECONDS_PER_HOUR;
      seconds += zone_offset;

      dt = seconds; // convert seconds back to a date/time structure

    } // adjustTime

If you want to try it, NeoGPS, AltSoftSerial and NeoSWSerial are available from the IDE Library Manager, under the menu **Sketch -> Include Library -> Manage Libraries**. NeoGPS is smaller, faster, more reliable and more accurate than all other GPS libraries.

Even if you don't use it, there are many suggestions on the Installation and Troubleshooting pages.


sender: user

message:
What does the term "9g" in servo's rating mean?

[![Servos][1]][2]

I frequently see 9g mentioned in servos. I searched the web but couldn't find any worthwhile answers. At first I thought it meant 9grams but the weight of the servo isn't 9 grams, so have to be something else.

  [1]: https://i.stack.imgur.com/050DJm.png
  [2]: https://i.stack.imgur.com/050DJ.png

sender: assistant

body:
According to the [link][1] it is.

However, if you look at [this][2] more detailed datasheet, it shows 14.7 g.

Probably it's the weight of the motor part itself, not the plastic enclosure around it.

Btw, most websites (without actually using data sheets), mention a weight of 9 g.

  [1]: http://www.micropik.com/PDF/SG90Servo.pdf
  [2]: http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf


body:
According to [Flite Test web site][1], the 9g reference is the weight without the wire lead. They measured one model at 8 grams rounded down. I suspect the weight also ignores the horn as well as the wire.

The article referenced on the web site calls the weight reference as a standard, which means that it more likely allows for heavier or lighter servos as long as the size of the servo matches.

If you purchase a servo for a model known to use a 9g servo, you know the hole you have to build for it to fit. If you purchase a 5g servo, it will be a different hole and you may have a 6 or 7 gram weight, but the servo fits as it should.

  [1]: https://www.flitetest.com/articles/servos-101


body:
From a model airplane perspective...

The "9g" is supposed to mean 9 grams in weight. Each vendor has their own way to define their weight.

 - with wires
 - without wires
 - with or without control horns
 - "about the same as a competitor's 9 gram servo"

Most are not accurate.

It is not a standard for size, and has nothing to do with hole size or screw spacing


message:
ESP8266 doesn't detect WiFi

I try to connect my NodeMCU Amica to my WiFi network, but it doesn't detect any networks around. I chose Board "NodeMCU 1.0 (ESP - 12E Module)", upload speed of 115200 and I have the correct port selected.

When I try the blink sketch, it works perfectly, but when I try to use the WiFiScan example, I only get the message "no networks found" and I don't.

I did pay attention that the upload speed in the sketch and monitor are always the same as the one I selected. Also, I tried out different upload speeds, without any succes either.

I already changed my network to 2.4 GHz, and also tried to downgrade the libraries to older versions, but nothing helped till now.

About any help, I would be really glad.

body: Firstly try to set it up as AP and check whether is it working ? If not, there is issue with power supply. Because WiFi Scan requires more current... than normal WiFi connection operation.


body:
1. Make sure you have entered correct ssid and password for that.
It is very much case sensitive.
2. Second reason for this can be insufficient amount of power supply supplied to it so make sure you are using good quality of power adapter for it.
3.https://tttapa.github.io/ESP8266/Chap07 - Wi-Fi Connections.html
Then try refering this link step by step...
Hope this will help
Thanks


message:
Arduino Serial Output Gone Wild!

I'm having a slight problem that I'm unable to work out. I am using an arduino Uno to print an incremental, but predefined wheel circumference. This is all working beautifully except it gives a negative reading during execution, and then runs into the positive etc. Without being exact, the output is something like the following:

1.85, 3.71, 5.56, 7.41, 9.27, 11.15....

When this multiple reaches 32.00 or greater, it then counts negatively back down to zero, then positively up to 32.00 again.

I can't quite work out why this would be, so hoping that one of you guys would be able to shed some light. The code is as follows:

    #include <Arduino.h>

    int InterruptPin = 2;
    int circ = 1854; //mtrs
    int km = 0;

    void calculate(){
        km = km + circ;
        //float temp = km / 1000;
        float temp = (float)km / (float)1000;
        Serial.println(temp);
    }

    void setup(){
        pinMode(InterruptPin, INPUT);
        attachInterrupt(digitalPinToInterrupt(2), calculate, RISING);
        Serial.begin(9600);
    }

    void loop(){

    }

body:
`km` is never reset but continously incremented.

    km = km + circ;
This leads to an overflow of the value after some time.

When you declare `int km;`, then `int`  on an Arduino Uno is `int16_t`, it thus has a maximum positive value of `2^15 - 1 = 32767`. Since `circ` is constant `1854`, after executing the ISR a total of `CEIL(32767 / 1854) = 18` times, `km` becomes greater than that maximum positive value. Thus an integer overflow occurs which takes you back to the maximum negative value of the `int16_t`. (See https://en.wikipedia.org/wiki/Integer_overflow)

You might want to use `uint32_t` or similiar from `stdint.h` if you want to cover a greater value range. I think however your underlying algorithm is flawed, since even then `km` *will*  overflow after some later time. You must reset it at some point or only store the number of **revolutions**, which is a much smaller number. If you want to get the traveled distance then, you take the number of revolutions and multiply it by the circumference.

Also you should not not use any `Serial` printing within in interrupt service routine! And you should also declare your used interrupt variables as `volatile`. Read [this article][1] for more info.

  [1]: https://arduino.stackexchange.com/questions/30968/how-do-interrupts-work-on-the-arduino-uno-and-similar-boards


message:
Fail to retrieve the value from gsm sim 900A by using AT Command to PHP script

I am currently trying to establish a connection between my gsm sim900A to one of my test server. The connection seems pretty good so far, though I'm a little bit confused why there are **no values retrieved** by my php file. Even so, the insert query works although it insert empty value into the database. So my question is how to retrieve it properly? I already change the method in php script to POST, both of it doesn't return any good signs.

Arduino Code:

    void postData()
    {
      sim900a.println("AT+HTTPINIT");
      delay(1000);
      printSerialData();

      sim900a.println("AT+HTTPPARA=\"CID\",1");
      delay(1000);
      printSerialData();

      sim900a.println("AT+HTTPPARA=\"URL\",\"test.my/demo/writedata.php\"");
      delay(1000);
      printSerialData();

      sim900a.println("AT+HTTPDATA=12,10000");
      delay(1000);
      printSerialData();

      sim900a.println("strBoton=999");
      delay(1000);
      printSerialData();

      sim900a.println("AT+HTTPACTION=1");
      delay(1000);
      printSerialData();

      sim900a.println("AT+HTTPREAD");
      delay(1000);
      printSerialData();

      sim900a.println("AT+HTTPTERM");
      delay(1000);
      printSerialData();
    }

PHP Code:

    <?php
    $servername = "test.my";
    $username = "****";
    $password = "****";
    $dbname = "test";

    $conn = new mysqli($servername, $username, $password, $dbname);

    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

    $Boton = $_GET["strBoton"];

    $sql = "INSERT INTO test VALUES ('$Boton')";

    if ($conn->query($sql) === TRUE) {
        echo "New record created successfully";
    } else {
        echo "Error: " . $sql . "<br>" . $conn->error;
    }
    $conn->close();
    ?>

Output:

    AT+HTTPINIT
    OK

    AT+HTTPPARA="CID",1
    OK

    AT+HTTPPARA="URL","test.my/demo/writedata.php"
    OK

    AT+HTTPDATA=12,10000
    DOWNLOAD
    OK

    AT+HTTPACTION=1
    OK

    AT+HTTPREAD
    OK

    AT+HTTPTERM
    +CME ERROR: operation not allowed

    AT+SAPBR=0,1
    OK

body:
I am not sure but, in this [tutorial][1] at page 8, it does almost the same code pattern like yours. You might want to check it. Sorry but I don't know PHP, I can't help you with it.

But I am confused with AT+HTTPACTION, since AT+HTTPACTION=0 is the read and AT+HTTPACTION=1 is the post. Check the tutorial and optimize your commands.

Also check [this][2] one. It writes WAIT=6 after AT+HTTPREAD before terminating it.

  [1]: http://simcom.ee/documents/SIM900/SIM900_HTTPS AT Command Set_V1 00.pdf
  [2]: http://m2msupport.net/m2msupport/athttpterm-terminate-the-http-session/


message:
Problem for control speed of a DC motor with a L298N

*(Not native english speaker here, feel free to edit my sentences)*

I try to control the speed of a DC motor with a L298N shield but it doesn't work very well. Here is my scheme :

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

The power comes from a transfo with an adjustable voltage of ~7v 1.0 Amp. I don't care about the sens of rotation, so I set `IN1` to 5v and `IN2` to the ground, is it right to do it like that ?

Now here is the code I'm using :

    #define CONTROL_M   9  // To Enable input

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

    void loop ()
    {
        test_analog_motor();
    }

    void test_analog_motor()
    {
        for (int i; i < 250; i=i+25)
        {
            Serial.println(i);
            analogWrite(CONTROL_M, i); // Any value between 0 and 255
            delay(500);
        }
    }

With that code, the speed of my motor should progressively increase and then goes back to 0. I'm aware that, maybe if the value is too low, the motor will have trouble to start so I "help" it manually.

If I doesn't use the Enable output of my Arduino and just use the jumper instead, the motor turns with a good torque. This prooves at least that my shield isn't damaged.

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

Now here is the problem I have : With the scheme I've shown above, it simply doesn't work, nothing happens when I set the grounds in common, why ? Then if I remove the cable that goes to the arduino ground, it works but the motor has a very low torque, it seems also that there is a kind of latency in regards to what display the Serial monitor.

I feel a bit stupid with what I did with the grounds, it seems wrong t me  but I don't know what to do instead :/ What can I do ? My goal is to have the best possible control of the speed of that DC motor in term of reactivity, does a L298N is suited for that ?

**EDIT**
I did tested the PWM with an oscilloscope and a multimeter, the arduino PIN I was using worked correctly. I don't know why but now, the shield works too, I mean : Problem solved. One theory is that I adjusted the tension of my power supply under 5V. In that cas the shield doesn't nothing Arduino is magic sometimes...

  [1]: https://i.stack.imgur.com/AVsVo.png
  [2]: https://i.stack.imgur.com/CMARW.png

body:
You do need the ground wire. The reason it 'works' without it is that enable input effectively then has an aerial connected and is responding in the same was as if you touch the input jack on an amplifier and hear a buzzing sound.

There is a link behind the blue connectors that enables the onboard 5v regulator. I assume you have this fitted, or it wouldn't work with the jumper as you describe.

There is a tutorial here : http://www.instructables.com/id/How-to-use-the-L298-Motor-Driver-Module-Arduino-Tu/

I can't see anything different from what you're doing that would cause it to fail, but perhaps you have a problem with pin 9 from your board - you might have damaged it by misconnection, as certain ways of wiring that schematic could put 12V on the arduino pin.  You could also try using pin 13 : the arduino LED should then be lit in sympathy with the PWM signal and you'll know it's working.


message:
Cannot connect to mBot after using Arduino IDE

Today I bought an mBot (from Makeblock) the one that uses 2.4G serial connection. After assembling it, I connected to it using mBlock (software based of Scratch) and I could control it using keyboard triggers. Then I went in Arduino IDE and used it to run some scripts on the mBot.

Next I tried to switch back to mBlock software, but now it cannot connect to the mBot anymore. Whatever Scratch-like scrips I build, they don't run anymore in mBlock.

Did I miss anything? Is there anything I can do so I can start using mBlock again?

body:
I received some really good piece of advice on the official [forum][1] and it solved my problem, it now works:

> When you go back to using the mBlock (Scratch) environment you will
> need to reload the firmware (Upgrade firmware from the Connect menu
> item). At least that’s what I’ve had to do. Oh, and make sure that you
> have shut down the Arduino environment to release the serial port.

  [1]: http://forum.makeblock.com/t/cannot-connect-to-mbot-via-mblock-after-using-arduino-ide/10921


message:
Arduino Code for Pulse Skip Modulation (PSM)

I have recently bought this light dimmer, and only when I received it I noticed it works with PSM (Pulse Skip Modulation) and not PWD (Pulse Width Modulation).

Does anyone know how to write Arduino code and do the wiring for this dimmer? I can't seems to find a working example.

Thanks

[![RobotDyn PSM Light Dimmer][2]][2]
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/T7Qfr.jpg
  [2]: https://i.stack.imgur.com/97mzH.jpg

body:
I assume you use [this module][1].

PSM is often used because of it's higher efficiency with light loads. It's also better for AC loads, since they should get a complete AC voltage and not a DC voltage (when you cut half of the wave).

The module you have, is build to support you with implementing PSM correctly. It has a zero-crossing detection, which gives you a signal on the Z-C pin, every time the AC sine wave crosses zero voltage (which is the best time to switch). You can sense the signal with an interrupt in your Arduino. The website does not explain exactly, what is outputted by the Z-C pin on a zero crossing, but you can check this easily yourself, by monitoring both AC and Z-C voltage in operation. Most likely you will have to use either a `FALLING` or a `CHANGE` interrupt.

PSM works with modulating the number of pulses (in this case full sine wave periods) are transmitted to the load. Imagine you want to dim the light in 10 distinct values.

 - For full power you always set the pin marked with PWM to high, when a full sine wave is starting (this is at every second zero crossing). This means the PWM pin is always high.
 - For half power you turn the PWM pin high for 5 full periods and then turning it off for further 5 periods.
 - For 10% (a value of 1) you turn the PWM pin high for 1 full period and then off for 9 periods.

The downside of this method is, that you might see the light flickering when having low values.

When implementing this, you can use the `attachInterrupt()` function with the Z-C pin. In the callback function you toggle a global (volatile!) boolean variable, to indicate, if a new full period is starting, or if the zero crossing signal is only indicating the start of the negative part of the sine wave. Also use a global (volatile!) counter variable, that counts (increments every full period) to the value, you preset (Here something between 0 and 10). When the counter variable is 0 (and the desired value is greater than 0) you write HIGH to the PWM pin of your module. When the counter reaches the desired value, you write LOW to the PWM pin. When the counter reaches the maximum value, you have reset it to 0.

In code something like this:

<!-- language: c -->

    volatile byte counter=0;
    volatile boolean new_period = true;
    volatile byte value=5;
    #define MAX_VALUE 10

    void setup(){
      // set pinModes for the correct pins

      // active interrupt. Note, that you may have to change FALLING to a value fitting the output of the module (see explanation above)
      attachInterrupt(digitalPinToInterrupt(Z_C_pin), zero_crossing, FALLING);
    }

    void zero_crossing(){
      if(new_period){
        if(counter==0 && value>0) digitalWrite(PWM_pin,HIGH);
        if(counter==value) digitalWrite(PWM_pin,LOW);
        counter++;
        if(counter > MAX_VALUE) counter=0;
      }
      new_period=!new_period;
    }

Note: Especially when having a great range of possible values, some of the values can be exchanged by a better behavior, that would prevent a bit of the flickering. For example, when using 100 distinct dimming stages and wanting to dim to 50%, you can either (as depicted above) turn the light on for 50 periods and then turning it of for another 50 periods. Or you can turn on during every second period. Though this will not help you with really small values. So I left it out for simplicity.

  [1]: https://robotdyn.com/ac-light-dimmer-module-1-channel-3-3v-5v-logic-ac-50-60hz-220v-110v.html


body:
Just adding to [chrisl's answer](https://arduino.stackexchange.com/a/51859/50645) since I bought this module, too.

There is a simple example on the [manufacturers website of this module](https://robotdyn.com/ac-light-dimmer-module-1-channel-3-3v-5v-logic-ac-50-60hz-220v-110v.html) which does not seem to implement PSM the obvious way:
<!-- language: c -->

    /*
    Connect RobotDyn AC Light Dimmer as follows:
    Dimmer pin  --  Arduino pin
        VCC     --    5V
     GND     --    GND
     Z-C     --    D2
     PWM     --    D3

    Glow sketch for AC Voltage dimmer with Zero cross detection
    Based on the sketch by Charith Fernanado
    Adapted by RobotDyn: http://www.robotdyn.com
    License: Creative Commons Attribution Share-Alike 3.0 License.
    Attach the Zero cross pin of the module to Arduino External Interrupt pin
    Select the correct Interrupt # from the below table (the Pin numbers are digital pins, NOT physical pins: digital pin 2 [INT0]=physical pin 4 and digital pin 3 [INT1]= physical pin 5)

    Pin    |  Interrrupt # | Arduino Platform
    ---------------------------------------
    2      |  0            |  All
    3      |  1            |  All
    18     |  5            |  Arduino Mega Only
    19     |  4            |  Arduino Mega Only
    20     |  3            |  Arduino Mega Only
    21     |  2            |  Arduino Mega Only

    In the program pin 2 is chosen
    */
    int AC_LOAD = 3;    // Output to Opto Triac pin
    int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

    void setup()
    {
      pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
      attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
    }

    // the interrupt function must take no parameters and return nothing
    void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
    {
      // Firing angle calculation : 1 full 50Hz wave =1/50=20ms
      // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) For 60Hz => 8.33ms (10.000/120)
      // 10ms=10000us
      // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

      int dimtime = (75*dimming);    // For 60Hz =>65
      delayMicroseconds(dimtime);    // Off cycle
      digitalWrite(AC_LOAD, HIGH);   // triac firing
      delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)
      digitalWrite(AC_LOAD, LOW);    // triac Off
    }

    void loop()  {
      for (int i=5; i <= 120; i++){  // We use 120 as the lowest and 5 as the highest brightness setting. May be adjusted depending on the lamp used.
        dimming=i;
        delay(20);
       }
      for (int i=120; i >= 5; i--){  // Same as above
        dimming=i;
        delay(20);
       }
    }

They are using an interrupt as suggested by chrisl.
There is no flickering present with low dim values (using an incandescent bulb).
See [this video](https://www.youtube.com/watch?v=Oq6Cnqwbbbg) for a similar board with the original version of the above sketch.

**Note:** If you want to integrate your own code into this example, it will likely not work as intended because the Arduino is busy with `delayMicroseconds()` most of the time

----------
EDIT: The manufacturer of this module just released a library. Check it out on [their github](https://github.com/RobotDynOfficial/Lib-RBD-Dimmer-for-Mega-UNO-Leonardo)


body: This module allows you to implement pulse skipping modulation but also phase angle control. The code that reins.ch posted is actually the latter.


message:
Use ESP8266 GPIOs after Flash Startup

I'm a bit confused about the ESP8266 launching and GPIO behaviour.
[![enter image description here][1]][1]

When I'm programming the ESP8266 I have to set GPIO2 high and GPIO0 low.
But when I want to use the ESP8266 in my project I have to set GPIO2 and GPIO0 to HIGH, but if they are both high I can't use them as inputs or outputs. So my question is how can I use atleast of the GPIO as an output and starting the ESP8266 without reprogramming it.

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

body:
ESP8266 was developed for 'Serial over WiFi' as system-on-chip based on the Tensilica processor. The GPIO pins of Tensilica where used for different purposes of the system, like antena, flash memory connection, boot setup etc.

The more general use of the ep8266 as micro-controller with WiFi has evolved, but needs to accept the legacy of the original concept. Smart people even found a way how to share SPI with the flash memory of the system.

If you want to use the IO pins of the esp8266 (they are not called GPIO in datasheet), you must accept the required boot state and use only circuit,
sensor or actuator that doesn't disturb it and can handle it.

io0 LOW tels the esp8266 to boot into bootloader flashing mode. It is evaluated by ROM software in the boot process. Pull-up circuit is required to achieve normal boot. So if you want to attach something to this pin, it must accept this conditions. For button it is ideal.

If you want to use io 0 or io 2 as output, use logic that is normally HIGH and make sure it is not connected direct or indirect to ground at startup.


message:
Arduino BMP085 Barometric sensor blank serial monitor

I am a beginner as far as arduino and microcontrollers are concerned.
I am using a BMP085 barometric pressure sensor.I have made all the necessary connections to my arduino uno board and double checked them. What I want to do is get readings from the sensor and display them on my arduino serial monitor. The code I am using compiles and uploads without any error but when I open my serial monitor, it is blank. I tried using a humidity/temperature sensor before this and that sensor returns values to the serial monitor.
The barometric sensor is new and this was my first time usage.

Here is my sketch. I took it from here.
https://www.sparkfun.com/tutorials/253

Any help would be greatly appreciated.

the code

    #include <Wire.h>

    #define BMP085_ADDRESS 0x77  // I2C address of BMP085

    const unsigned char OSS = 0;  // Oversampling Setting

    // Calibration values
    int ac1;
    int ac2;
    int ac3;
    unsigned int ac4;
    unsigned int ac5;
    unsigned int ac6;
    int b1;
    int b2;
    int mb;
    int mc;
    int md;

    // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
    // so ...Temperature(...) must be called before ...Pressure(...).
    long b5;

    short temperature;
    long pressure;

    // Use these for altitude conversions
    const float p0 = 101325;     // Pressure at sea level (Pa)
    float altitude;

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

    void loop()
    {
      temperature = bmp085GetTemperature(bmp085ReadUT());
      pressure = bmp085GetPressure(bmp085ReadUP());
      altitude = (float)44330 * (1 - pow(((float) pressure/p0), 0.190295));

      Serial.print("Temperature: ");
      Serial.print(temperature, DEC);
      Serial.println(" *0.1 deg C");
      Serial.print("Pressure: ");
      Serial.print(pressure, DEC);
      Serial.println(" Pa");
      Serial.print("Altitude: ");
      Serial.print(altitude, 2);
      Serial.println(" m");
      Serial.println();

      delay(1000);
    }

    // Stores all of the bmp085's calibration values into global variables
    // Calibration values are required to calculate temp and pressure
    // This function should be called at the beginning of the program
    void bmp085Calibration()
    {
      ac1 = bmp085ReadInt(0xAA);
      ac2 = bmp085ReadInt(0xAC);
      ac3 = bmp085ReadInt(0xAE);
      ac4 = bmp085ReadInt(0xB0);
      ac5 = bmp085ReadInt(0xB2);
      ac6 = bmp085ReadInt(0xB4);
      b1 = bmp085ReadInt(0xB6);
      b2 = bmp085ReadInt(0xB8);
      mb = bmp085ReadInt(0xBA);
      mc = bmp085ReadInt(0xBC);
      md = bmp085ReadInt(0xBE);
    }

    // Calculate temperature given ut.
    // Value returned will be in units of 0.1 deg C
    short bmp085GetTemperature(unsigned int ut)
    {
      long x1, x2;

      x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
      x2 = ((long)mc << 11)/(x1 + md);
      b5 = x1 + x2;

      return ((b5 + 8)>>4);
    }

    // Calculate pressure given up
    // calibration values must be known
    // b5 is also required so bmp085GetTemperature(...) must be called first.
    // Value returned will be pressure in units of Pa.
    long bmp085GetPressure(unsigned long up)
    {
      long x1, x2, x3, b3, b6, p;
      unsigned long b4, b7;

      b6 = b5 - 4000;
      // Calculate B3
      x1 = (b2 * (b6 * b6)>>12)>>11;
      x2 = (ac2 * b6)>>11;
      x3 = x1 + x2;
      b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

      // Calculate B4
      x1 = (ac3 * b6)>>13;
      x2 = (b1 * ((b6 * b6)>>12))>>16;
      x3 = ((x1 + x2) + 2)>>2;
      b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

      b7 = ((unsigned long)(up - b3) * (50000>>OSS));
      if (b7 < 0x80000000)
        p = (b7<<1)/b4;
      else
        p = (b7/b4)<<1;

      x1 = (p>>8) * (p>>8);
      x1 = (x1 * 3038)>>16;
      x2 = (-7357 * p)>>16;
      p += (x1 + x2 + 3791)>>4;

      return p;
    }

    // Read 1 byte from the BMP085 at 'address'
    char bmp085Read(unsigned char address)
    {
      unsigned char data;

      Wire.beginTransmission(BMP085_ADDRESS);
      Wire.write(address);
      Wire.endTransmission();

      Wire.requestFrom(BMP085_ADDRESS, 1);
      while(!Wire.available())
        ;

      return Wire.read();
    }

    // Read 2 bytes from the BMP085
    // First byte will be from 'address'
    // Second byte will be from 'address'+1
    int bmp085ReadInt(unsigned char address)
    {
      unsigned char msb, lsb;

      Wire.beginTransmission(BMP085_ADDRESS);
      Wire.write(address);
      Wire.endTransmission();

      Wire.requestFrom(BMP085_ADDRESS, 2);
      while(Wire.available()<2)
        ;
      msb = Wire.read();
      lsb = Wire.read();

      return (int) msb<<8 | lsb;
    }

    // Read the uncompensated temperature value
    unsigned int bmp085ReadUT()
    {
      unsigned int ut;

      // Write 0x2E into Register 0xF4
      // This requests a temperature reading
      Wire.beginTransmission(BMP085_ADDRESS);
      Wire.write(0xF4);
      Wire.write(0x2E);
      Wire.endTransmission();

      // Wait at least 4.5ms
      delay(5);

      // Read two bytes from registers 0xF6 and 0xF7
      ut = bmp085ReadInt(0xF6);
      return ut;
    }

    // Read the uncompensated pressure value
    unsigned long bmp085ReadUP()
    {
      unsigned char msb, lsb, xlsb;
      unsigned long up = 0;

      // Write 0x34+(OSS<<6) into register 0xF4
      // Request a pressure reading w/ oversampling setting
      Wire.beginTransmission(BMP085_ADDRESS);
      Wire.write(0xF4);
      Wire.write(0x34 + (OSS<<6));
      Wire.endTransmission();

      // Wait for conversion, delay time dependent on OSS
      delay(2 + (3<<OSS));

      // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
      Wire.beginTransmission(BMP085_ADDRESS);
      Wire.write(0xF6);
      Wire.endTransmission();
      Wire.requestFrom(BMP085_ADDRESS, 3);

      // Wait for data to become available
      while(Wire.available() < 3)
        ;
      msb = Wire.read();
      lsb = Wire.read();
      xlsb = Wire.read();

      up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);

      return up;
    }

wirings:
https://i.stack.imgur.com/oRX0V.jpg

body:
There are several versions of breakout boards for the BMP085. The device itself is 3v3. Some breakouts provide a regulator so you can supply 5V. Some also perform level-shifting so you can drive the I2C lines at 5V and work correctly with the sensor's 3v3 levels.

It isn't clear which type you have there, but you seem to be powering it from 3v3 on the arduino. A photo of the other side of the sensor board would help.

If the sensor has a regulator, sourcing it from 3v3 will drop it a little (the regulator needs some overhead). This might mean the sensor is running at too low a voltage.

If the board has no regulator, then it's correct to power it from 3v3. However, the I2C lines also need conversion. You will be driving 5V into a 3v3 input, which can damage it. You will also be receiving 3v3 levels from the sensor into the 5V arduino, which will probably work but might not.

Ideally, put level shifters in between. They need to be bidirectional, like these : https://www.adafruit.com/product/757

In some cases you can get away with resistors only, but not easily on the bidirectional I2C bus. SPI is easier as the pins are unidirectional.


message:
Arduino Nano ATmega328P bootloader difference

There are two ATmega328P bootloaders, old and current.  What is the difference between these bootloaders?

I'm aware that Nanos sold by Arduino use the new bootloaders but I haven't been able to find any release notes about the bootloader.

body:
The bootloader currently shipped on the official Arduino Nano boards and selected via the Arduino IDE's **Tools > Processor > ATmega328P** after choosing **Tools > Board > Arduino Nano** is the same version of optiboot used by the Arduino/Genuino Uno:
https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L152

    nano.menu.cpu.atmega328.bootloader.file=optiboot/optiboot_atmega328.hex

https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L72

    uno.bootloader.file=optiboot/optiboot_atmega328.hex

The bootloader selected via **Tools > Processor > ATmega328P (Old Bootloader)** is the ["ATmegaBOOT"](https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L167) bootloader.

As used by the Nano hardware definition, there are two significant differences between the two bootloaders:

1. Optiboot will not go into an endless reset loop after a watchdog reset. [ATmegaBOOT will](https://github.com/arduino/Arduino/issues/4492).
1. Optiboot expects the upload communication at [115200 baud](https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L147). ATmegaBOOT, [57600](https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L162). This is the reason why the old boards don't work with the **Tools > Processor > ATmega328P** selection and vice versa.

There is another very significant difference between the two bootloaders that, sadly, you will not benefit from with the new Arduino Nano board/hardware definition: Optiboot will fit in a 0.5 kB boot section, while ATmegaBOOT requires a 2 kB boot section. Unfortunately Arduino [forgot to change the BOOTSZ fuse](https://github.com/arduino/Arduino/commit/1cf34c8250658c5c4a5c488f7a7a0d7071e3430f#commitcomment-27653082) accordingly and so the opportunity to free up 1.5 kB of precious flash memory for the users of the Nano was lost. The willingness of Arduino to knowingly release flawed hardware has [historic precedent](http://forum.arduino.cc/index.php?topic=22737.msg171839#msg171839).

>I haven't been able to find any release notes about the bootloader.

Arduino's release notes have not yet adapted to the fact that hardware packages may be released independently of IDE releases ever since Arduino IDE 1.6.2. There is a note about the bootloader change in the IDE release notes for the next IDE release:

https://github.com/arduino/Arduino/commit/ec179e5af67b7f1eeb5e46d22034798f8b24b7cb

Other than that, you can consult the commit history:

https://github.com/arduino/ArduinoCore-avr/commit/1b14cc07331268e95eddcce2cc67e29ed667e62f


message:
How to fix Arduino restarting when two servos are powered by an external power?

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

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

Can anyone help me fix this? It always restarts when I power the servos with an external battery. I connected one battery to Arduino and one battery to servos, each 5V, but my Arduino keeps restarting.

body:
You will need to fix this on your own but I can suggest some things that you will likely need to investigate.

1. Evaluate what exactly causes the AVR to get reset. It is highly likely that long wires and current surges as loads are applied is causing either the GND or the VCC to the AVR to be compromised and initiating a brown out reset in the MCU.
2. Driving inductive loads without proper design may be putting high voltage spikes into your design that create havoc with proper software execution and/or risking serious damage to the silicon components. Make sure you take steps to eliminating such with clamp diodes, filter caps or zener diodes.
3. You will have to check your exact MCU data sheet but many parts have a reset reason register that your software can read to see what particular thing initiated the reset.
4. Lastly the most important thing is to make sure you have the proper tools for debugging problems like this. It is very common that you should have access to an oscilloscope so you can find the problems and learn how to fix them. The best way to learn how to design in a way that you avoid problems like this on the next project is to see first hand what went wrong and learn from it.


body:
The reason here is, you are not able to provide enough current required for the servo. There are multiple ways to work around.

1. Change the code: Just try to rotate only one servo at a time. Rotate the second servo after servo1 finished rotation.

2. Use a 9V battery and connect it to the power socket of arduino [this could solve the issue if you are using normal servos]

3. Use separate power supplies for servo and Arduino. Use two different 5V supplies to power servo and arduino. Please don't forget to connect the grounds of both supplies together.


message:
NodeMCU - Vin pin as 5V output?

I know that Vin can be used to power the board but have also been reading that it can be used as a 5V output. Is it possible to assign Vin as an output as I would any other GPIO?

If I want to power an LED from GPIO 12, I would assign GPIO:

    const int LEDpin_0 = 12; // D6, LED power pin

...and in the setup:

    pinMode(LEDpin_0, OUTPUT);

I can then turn on and off the LED based on whether or not GPIO 12 goes HIGH or LOW.

Can I do the same with Vin without resorting to relays or other hardware?

body:
There is confusion about what is and what isn't possible with this board. This is because there are different versions with different power arrangements.

## NodeMCU 0.9

In this board the USB's 5V and the 5V pin are directly connected together. The combined result is then fed through a diode before entering the 3.3V voltage regulator.

With this arrangement the 5V pin will provide the exact same voltage that the USB port feeds the board. However it is dangerous to connect that pin to any power source - it may kill (or at the very least disable) the USB port in your computer - when the board is also connected to a computer through the USB port.

## NodeMCU 1.0 and 1.1

On this version the USB's power is first fed through the diode and then to the 5V pin and the 3.3V regulator together.  This means that the 5V pin will show about 0.5V below whatever voltage is fed in through USB. This isolates the USB from the 5V pin so it becomes safe to provide power through the 5V pin whilst at the same time having the board plugged in to the computer - at the cost of having a slightly lower output from the 5V pin.

----
<sub>Original answer:

The VIN pin not directly connected to the USB's 5V supply (at least on the LoLin v3 board). this means the pin cannot be used as a 5V supply output.

* You cannot control that voltage. It is always on, and always 5V (or whatever your USB port happens to provide - 4.75v - 5.25v).
* You must never ever connect VIN to a power source *and* connect the USB socket. That can destroy the USB port in your computer. There is zero back-powering protection on that board.
* Drawing more than 500mA from the VIN pin could cause the USB port of your computer to be shut down.
</sub>


body:
my 2 cents:

A LoLin NodeMCU V3 when powered via USB in the Vin pin reads 2.2 V (don't know why) but... in the VV pin you can get the 5V coming from the USB; so if you need 5V use that pin.

The board if powered via Vin with 5V, the VV pin reads 2 V (don't know why either)

in any case you can always get 3V in the 3V pin.

Cheeers!


body:
No you cannot use a Vin or VU pin as a GPIO pin which can be controlled by a program. Vin can be used as an input for 5V battery or as a 5V output when NodeMCU is powered by USB (except on NodeMCU v3 by LoLin).

On the V0.1 LoLin board, there are 2 diodes between the VIN and VU pins.  So you cannot get power from one to the other.  These diodes isolate the two possible sources of 5V power from each other while allowing the board to obtain the 5V needed by its its 3.3V power supply from either 5V source.

Other board versions might be different.

To control 5V sensor with help of GPIOs on NodeMCU you will need a logic shifter connected between your sensor and GPIO pin thats boost the 3v3 to 5V.


message:
Use external power - nodemcu 0.9

I'd like to deploy my project so I'm looking for a way to power the nodemcu.
I'd like to know if there's a way to power it with a 9V battery **without any other external circuit**.

Until now I've found information for the nodemcu 1.0 and it supports up to 20V on the VIN port. Here's the article I read:
http://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/powering-the-esp-12e-nodemcu-development-board/

I'd like to use the two port: 5V and GND but I'm not sure, here there is no VIN port and I'd prefer to not burn my board.
Are there any better way to power my project?

body:
It looks like the 0.9 uses the SPX3819 regulator. That can run with up to 16V on the input, so 9V on the 5V pin (*as long as USB never gets connected*) should work fine.

**Except:** 9V PP3 batteries are useless. If it can even provide enough power to run the board (which is doubtful) it won't last more than a few hours.  You would have to ensure that you use *very very* deep sleep mode to get any semblence of longevity out of it.

The 3.3V regulator will be throwing away half to two-thirds of the power as heat. So wasteful. You would be better off investing in a 3.3V switch-mode ("buck") regulator circuit (cheap on eBay) to directly power the 3.3V pin of the board instead of 9V into the on-board regulator.


message:
How to test if PWM mode is working correcly?

I d'like to test if the PWM mode is working correctly on the pins of my Arduino Board. Do you know a simple schema to do this ?

body:
There are my options:

 - The default way to do this is to use an oscilloscope. These can be quite expensive.
 - Use a logic analyzer if the voltage is logic/binary (0 and 3.3 or 5V). These are very cheap.
 - The easiest way to know if it works without the devices above, is to lower the speed drastically (using a divider in the software, like 1000 or more to get PWM widths of 100 ms to multiple seconds) and connect the PWM output with a resistor and a LED to GND. If the LED flashes faster, the PWM speed is high, otherwise low. By using a stopwatch you can roughly calculate the PWM speed (taking the divider into account) and after the test remove the divider.
 - If the PWM is controlled completely from your Arduino (probably not), you can use a software counter and print it out afterwards to see the speed.


body: You could just do a simple analogWrite, varying the duty cycle, with an LED/resistor. Fade the value up & down, see if the LED gets brighter & dimmer.


message:
Adding music to loop

Im newbie. I just wanted to ask how can i put my tmrpcm.play into loop. Im trying to put it in a loop but the problem is it didn't play. I also try adding a method and call the method into the loop but it give me the same problem also. It will just only play in the void setup.

Here's my code.

    #include "SD.h"
    #define SD_ChipSelectPin 4
    #include "TMRpcm.h"
    #include "SPI.h"

    TMRpcm tmrpcm;

    void setup(){
    tmrpcm.speakerPin = 9;
    Serial.begin(9600);
    if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("SD fail");
    return;
    }

    tmrpcm.setVolume(5);
    tmrpcm.play("Yeah.wav");
    }

    void loop(){  }

body:
The library has a built in loop function:

    audio.loop(1);             0 or 1. Can be changed during playback
                               for full control of looping.

See [WIKI][1] page of the library.

Btw, it is unclear if you mean by 'a loop' a while(true) loop or the void loop() function. Although it should not make a difference.

  [1]: https://github.com/TMRh20/TMRpcm/wiki


body:
The TMRpcm library is *non-blocking*. That means, when you start playing it keeps playing in the background. If you put the play function in a loop it will just keep restarting what you are playing over and over again and you won't get to hear anything.

As Michel says, you can get it to loop automatically (`tmrpcm.loop(1);`), in which case you just leave it in `setup()` and leave `loop()` empty.

If you want to do it manually you should check to see if the sound has finished playing or not. The simplest way is:

    loop() {
        if (!tmrpcm.isPlaying()) {
            tmrpcm.play("Yeah.wav");
        }
    }

That is - if it's *not* playing then start it playing. When it finishes it'll not be playing any more, so it will start playing again.


message:
I am new to arduino please help me in understanding this code

while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);

Why we require **char c** and what is the use of using this command **Serial.write(c)**

body:
`client.read()` returns exactly one byte from the serial input buffer for the port connected with object `client`. That is why you use a `char` variable. The name `c` is not relevant.

The next line, `Serial.write(c)` then writes that same character to the main serial port.

The code basically reads from one serial port and writes the same data immediately to the other serial port.


body:
What you have there is simple "Serial pass-thru" code. Whatever a client receives gets printed on the serial terminal.

It can be written, line by line, in English like this:

    - While the client is connected:
        - If there is some text available in the client:
            - Read one character from the client and store it in the
                  variable "c" which is of "char" type.
            - Print that character out to the serial port.

The reason you use `Serial.write(c);` is so that you can see what has been received.


message:
How to rebuild Arduino core for ESP8266

I'm experimenting adding DHCP option 160 to dhcpserver.c in the Arduino core for ESP8266 and therefor need to rebuild the relevant parts.

I made an initial guess that I might be able to make the change by installing [using git][1] according to the instructions in the readme and just restarting the IDE. I wasn't surprised to learn that this didn't help. The modifications to dhcpserver.c did not make it to the device following restart of the IDE and a new upload.

From [another forum][2] I saw a suggestion that the following commands could be used to rebuild from source:

    $ cd esp8266/tools/sdk/lwip/src
    $ make install

Again the changes didn't make it to the device after restarting and uploading the sketch again.

Does anyone have any clearer instructions for how to build a new Arduino core for esp8266?

  [1]: https://github.com/esp8266/Arduino#using-git-version
  [2]: https://github.com/esp8266/Arduino/issues/3143

body:
There are four variants of LwIP bundled with the ESP8266 core:

* V1.4 (Compile from source)
* V1.4 (Precompiled)
* V2 Lower Memory
* V2 Higher Bandwidth

By default (for most boards) one of the V2 variants is selected. You need to change that to the V1.4 (Compile from source) for it to use the version that you have modified.


message:
Controlling multiple 24V solenoids with Arduino

I'm building a pump for which I need 4 medium strength solenoids (20-50N). 24V is probably the minimum I will need to put through them, but this is something I need to test, once I've got them working. At 24V they draw 400mA.

I've found various posts with very useful info, especially https://playground.arduino.cc/Learning/SolenoidTutorial and https://forum.arduino.cc/index.php?topic=417030.0

Will the attached sketch below work for one? If so what resistance should R1 be?
And if so can you see any problems with hooking up 4 working at different intervals?

The power supply is an LRS-350-24RS, and the Mosfet has a max gate source voltage of 35V. The 5v-24v optocoupler is off ebay -  https://www.ebay.co.uk/itm/152904980799

Many thanks for your help!!

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

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

body:
No, it won't:

* The diode D1 is backwards.
* The opto-coupler is wired completely wrong.

You don't actually need the opto-coupler as long as the threshold voltage of the MOSFET is low enough for the Arduino to switch.  However if you do want (or need) to use it you should wire it like this:

![schematic](https://i.stack.imgur.com/JOBYL.png)

R1 is a pull-down that keeps the MOSFET off when not being turned on (just like with a button). The value doesn't matter much.  R2 is a resistor just like you use for any LED with an Arduino.  D1 must be connected reverse biased or it will just short out your solenoid. The opto-coupler must be connected with the transistor the right way around or it will not work (or melt, or create a black hole...)

To ditch the opto-coupler you can just treat it like any other load on the Arduino (as long as the MOSFET's threshold voltage *VGS* is below 4V):

![schematic](https://i.stack.imgur.com/zFkWv.png)


message:
MQTT not working on ESP8266 (Nodemcu 0.9)

I'm trying to use NodeMCU on my **ESP8266** (NodeMCU 0.9) but the board **keep crashing** and I don't understand why.

I **tested** the **mqtt broker** using command line and it **works** perfectly, so I can suppose that the problem is not the server.

I was following [this guide][1] but it doesn't seem to work with me.

Here's the code I wrote:

Previously:

    #include <PubSubClient.h>
    #define MQTT_SERVER    "1.2.3.4"
    #define MQTT_PORT      1883
    #define MQTT_USER     "user"
    #define MQTT_PSW      "psw"
    ...
    WiFiClient client;

Then:

    PubSubClient clientMqtt(MQTT_SERVER, MQTT_PORT, this->client);
 //Try mqtt connection
 while (!clientMqtt.connected()) {
  Serial.print("Attempting MQTT connection...");
  // Attempt to connect
  if (clientMqtt.connect("ESP8266Client", MQTT_USER, MQTT_PSW)) {
    Serial.println("connected");
  } else {
    Serial.print("failed, rc=");
    Serial.print(clientMqtt.state());
    Serial.println(" try again in 5 seconds");
    // Wait 5 seconds before retrying
    delay(5000);
  }
 }

 //Try send message
 clientMqtt.publish("bin", "test", true);

The code works correcty until `clientMqtt.connect("ESP8266Client", MQTT_USER, MQTT_PSW)` where at the first/second attempt crashes.

This is the output:

    Attempting MQTT connection...
    failed, rc=-2 try again in 5 seconds
    Attempting MQTT connection...
    failed, rc=-2 try again in 5 seconds
    Attempting MQTT connection...

    Soft WDT reset

    ctx: cont
    sp: 3ffefa90 end: 3ffefe30 offset: 01b0

    >>>stack>>>
    3ffefc40:  3ffe897d 40202c5d 3ffefcc4 40202dab
    3ffefc50:  3ffe89b7 3ffefcc0 3ffefcc4 40203cdc
    3ffefc60:  514d0400 00045454 3ffe89a7 40204cdc
    3ffefc70:  3ffe89c0 3ffe89a9 00000000 3ffe88fa
    3ffefc80:  3ffeeb70 3ffefdb0 3ffeedd8 3ffe88fa

  [1]: https://www.home-assistant.io/blog/2015/10/11/measure-temperature-with-esp8266-and-report-to-mqtt/

body:
The `Soft WDT reset` means that the software watchdog timer reset. Depending on the version of Arduino core to the ESP8266 using `delay()` can cause this to happen, though current versions handle this better, and using `delay()` does not cause problems. Make sure you are up-to-date with the Board Manager definitions for ESP8266-based projects.

[This page][1] has lots of information on the watchdog timers and especially notes how to use a tool called [ESP8266/ESP32 Exception Stack Trace Decoder][2] to determine exactly what line in your code caused the reset to happen.

[This page][3] notes that the PubSubClient library can cause problems with the watchdog feeding and gives examples of some alternative `yield()` and `delay()` functions you can include and call instead of the built-in versions, which help alleviate resets when using PubSub on ESP8266.

The software watchdog timeout is on the order of 3 seconds, so you can also try reducing your `delay(5000)` to something shorter, like `delay(1000)` while debugging, to rule out the 3-second WDT reset due to the `delay()` call.

Your output also indicates status `-2` to the `state()` function. The [documentation for PubSubClient][4] notes that this means "the network connection failed". So one other thing to check is that your device actually connects to the WiFi network and that the MQTT server is listening on the IP address and port you specify.

  [1]: http://arduino-esp8266.readthedocs.io/en/latest/faq/a02-my-esp-crashes.html#watchdog
  [2]: https://github.com/me-no-dev/EspExceptionDecoder
  [3]: https://sigmdel.ca/michel/program/esp8266/arduino/watchdogs_en.html#ESP8266_WDT_FEEDING
  [4]: https://pubsubclient.knolleary.net/api.html#state


message:
Is DateTime from RTClib giving garbage dates/times?

The RTC is working fine, but I'm having trouble with the `DateTime` class. Based on the following test, it seems like its math is wrong.

    #include <RTRlib.h>
    void loop()
    {
        auto ts = TimeSpan(0, 8, 0, 0); // 8 hours
        auto zero = DateTime(0, 0, 0, 0, 0, 0);
        auto alarm = zero + ts;
        Serial.println(String("Zero date: ")+zero.year()+" "+zero.month()+" "+zero.day()+" "+ zero.hour()+":"+zero.minute()+" "+zero.second());
        Serial.println(String("Alarm as timespan: ")+ts.days()+"d "+ ts.hours()+":"+ts.minutes()+" "+ts.seconds());
        Serial.println(String("Alarm date: ")+alarm.year()+" "+alarm.month()+" "+alarm.day()+" "+ alarm.hour()+":"+alarm.minute()+" "+alarm.second());
    }

My output is (repeating):

    Zero date: 2000 0 0 0:0 0
    Alarm as timespan: 0d 8:0 0
    Alarm date: 2043 4 30 1:31 44

Also, when creating `DateTime(0)`, I would expect the hours, minutes, and seconds to be zero. That's not the case. What's up with this library, and how did it get to be so popular if it doesn't work?

body:
You are experiencing the consequences of code that doesn't do sanity checking. The library allows for dates that do not make sense (in addition to giving us all a **new** reverse-Y2K bug of assuming only dates later than year 2000.

When you create `DateTime(0, 0, 0, 0, 0, 0);`, you are saying to use Month 0 and Day 0. Those have no meaning in date calculations, which always assume that the first month is 1 and the first day is 1.

The rest of the library's code assumes valid dates, so when you give it invalid dates, unexpected behavior is to be expected!

Of you only modify your `zero` assignment to `DateTime(0, 1, 1, 0, 0, 0);` you will see behavior that is more expected.


message:
How do I detect the Computer's operating system?

I'm working on an emoji keyboard and it requires different input depending on the OS it's connected to. I've written the relevant methods using Arudion's [default Keyboard library][1] and can manually set which one is used. I'm wondering if there is a method or library for Arduino (currently using a Adafruit Feather 32u4 Bluefruit LE) that allows me to detect the OS.

If not, I'll set up a switch, but that'll cost me pins.

  [1]: https://www.arduino.cc/reference/en/language/functions/usb/keyboard/

body:
If you can't get the OS from the USB port, why not use the existing keys/inputs to set the mode on startup? That is, if you tell the user to press different combinations of 2 buttons on startup, you have 4 (2 bits => 4 values) different paths on startup:

    00 => Normal startup, don't change mode
    01 => OS 1
    10 => OS 2
    11 => OS 3


message:
Question about Variables

is there a way to use a previous assigned value to variable to adjust the step motor? what i mean is:

example:
Sensor reads 100 degrees so

Adjust the step motor to 100 degrees and hold, then after 10 min

the sensor reads 110 degrees so

Adjust the step motor (110 - 100) by extra 10 degrees

and so on..

I'm really new to this and i'm sorry if that's a stupid question :<

body:
Based on your description, the program needs to know only the new target setting and the current position. That means you need two variables. Algorithmically, it would look as follows (written in C-like pseudo-code):

    // initialize global variables (might need float instead of int)
    int target_pos = 0;
    int current_pos = 0;

    void setup() {
        // add code to set up pin IO mode, prepare communication with the sensor...
    }

    // function to read the sensor
    int ReadSensorFunc(void) {
        int reading = 0;   // local variable to store sensor reading
        reading = ...;     // add code to read sensor
        return reading;
    }

    // function to adjust the motor position
    void AdjustStepMotorFunc(void) {
         // add code to to adjust the stepper to (target_pos-current_pos);
    }

    void loop() {  // repeat forever
        target = ReadSensorFunction()   // call sensor read function
        AdjustStepMotorFunc()           // call position adjustment function
        current_pos = target_pos        // update current position
        // add code to delay for 10 minutes
    }

This code initializes the position as zero. In case it's not zero when the controller is turned on, you'll need additional code in `setup()` to assign `current_pos` the correct value based on user input.


body:
Initially you read the value of sensor to some variable, like:

    previous = readSensor();

Every ten minutes you have to call a function ( logic using timer interrupt / RTC /millis() ) which reads the current value from sensor and compares it with previous value to get the offset. Then you pass it to the function which adjusts motor speed. Update 'previous' variable

    offset = readSensor()-previous;
    previous = readSensor();
    adjustSpeed(offset);


message:
Control multiple WS2812B strips with different leds count

First of all, my English is not that good so sorry if I made any mistake.

I'm using the WS2812FX, an awesome WS2812 effect library base on Adafruit NeoPixel library to make a small controller for the lightning in my bedroom.

[![image description][1]][1]

The question here is how do I use this library to control multiple WS2812b led strip with different leds count, like one strip with 30 leds the other with 55 leds but the effect will just cycle through each individual led of each strip.IF somehow I can add one more output pin to this.

Example : There is an effect call "Larson Scanner" will light up one led then it run from the first led to the last led and go back, I want it to do the same on both strips, on the 30 leds strip it goes from first led to 30th led then go back & on the 55 leds strips it goes from first led to the 55th led at the same time.

Hope you guys understand what I'm asking :(

Link to the library : https://github.com/kitesurfer1404/WS2812FX

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

body:
The WS2812 chip requires *highly* timing dependent pulses to work, as I describe [on my page about Neopixels](http://www.gammon.com.au/forum/?id=13357). We are talking about pulse widths of 350 ns.

I suggest it would be impossible to add another strip "if I can add one more output pin to this". It's not a question of adding pins, it's being able to output pulses that fast. You can't do it, at least not on the AVR Arduinos, and I doubt that the ones with faster chips would do it either.

What you *could* do is connect the various strips together so it is really one long strip (assuming they aren't too far away from each other). The different strips could usefully have their own power supplies, but the **data** and **ground** would need to go from the Arduino into the first strip, then out to the second one, and so on.

Something like this:

[![Multiple Neopixels][1]][1]

As for synchronizing the strips, well that is just programming. If you want the first LED on the 30-LED strip to light at the same time as the first LED on the 55-LED strips, then you actually would need to light LED #1 and LED #31 at the same time.

---

## Possible alternative

Actually what might work would be to send to strip #1 first, and then strip #2 after changing pins. That means you would have to interleave the sends. For example to make a pixel seem to run backwards and forward on two strips you make it move one pixel on the first strip, then one pixel on the second strip, and so on.

I'm not sure if the library you mentioned supports that, since the LED count is in the constructor. It looks like it might, as you can change the number of LEDs and the pin number.

You might be able to make two instances of the library object (with different names), initialize them both, and then interleave the sends between them.

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


body: The library repo itself already describes "segments". So you simply connect the 55-part strip's data-in to the data-out of the 30-part strip. Instantiate as one 85-part strip, and then define the segments and set patterns on each as appropriate.


message:
Tian stops working after some hours

I'm having a very strange problem. I have a Tian that is programmed to send out sensor data to a server
every x seconds.
My program run well but after 14,15 hours of operation it stops working and I don't receive datas. The program is fast at the beginning, then after 2 to 3 hours before stopping, it becomes more and more slow with the message "timeout".

I think maybe a misuse of the Ciao library on my part could be at the root of the problem. Or maybe a modification at the program level could correct the problem. So if I can have some help about this..
(the problem doesn't come from the use of String, I have already tested use of array with cstrings and it doesn't work).

Here is the part of the program that I think is problematic (there is another CiaoReadWrite nearly similar to the first) :

    void CiaoReadWrite1() { CiaoData data = Ciao.read("restserver");
    if (!data.isEmpty())
    {
      String id = data.get(0);
      String sender = data.get(1);
      String message = data.get(2);

      splitString(message,"=",LtT2,9);

      gen            =LtT2[0].toInt(); LtT2[0]="";
      belt           =LtT2[1].toInt(); LtT2[1]="";
      genReady       =LtT2[2].toInt(); LtT2[2]="";
      hvOnOff        =LtT2[3].toInt(); LtT2[3]="";
      beep           =LtT2[4].toInt(); LtT2[4]="";
      heart1         =LtT2[5].toInt(); LtT2[5]="";
      sendConf       =LtT2[6].toInt(); LtT2[6]="";
      heart2FB       =LtT2[7].toInt(); LtT2[7]="";

      beepFB         =beep;
      heart1FB       =heart1;
      sendConfFB     =sendConf;

      Ciao.writeResponse("restserver",id, String(baroAlti*100)+"="+baroHumi*10+"="+baroPres+"="+baroTemp*10+"="+beepFB+"="+heart1FB+"="+heart2+"="+sendConfFB+"="+
                                          secCust1+"="+secCust2+"="+secEmrgSW+"="+secloop+"="+secLoop1+"="+secLoop2+"="+gndSwGnd+"="+gndSwUGnd+"="+statusA1+"="+
                                          statusA2+"="+statusA3+"="+beltStat1+"="+beltStat2+"="+beltStat3+"="+beltStat4+"="+request+"=");
      request++;
    }
}

body:
Well, if your program works some time and stops, the first thing you have to check is if there's some variable entering in overflow.
Maybe some variable is concatenating and after some time it goes overflow.
I haven't check your code or the lib, because that is a common problem and already happened with me.


body:
You're using the String (upper-case 'S') functions, which allocate and de-allocate memory, a limited commodity, even with 64K. The standard heap management functions will tend to fragment the heap into pieces too small for further use. That can make new allocations slower because the heap has to be searched for a big-enough piece, and can eventually make it the heap grow toward the stack, until a collision (something gets overwritten) inevitable. We can't say for sure that this is your problem; we don't have enough information.

But try allocating one or a few buffers large enough for the worst case requirement, and use the C string functions instead (lower-case 's'), sprintf(), strcpy(), strcat(), etc. instead.


message:
How can I send and receive data from an Arduino Uno to Arduino Mega using I2C?

I am trying to send data as a string from an Arduino Uno to another Arduino Mega. I have read about the I2C connection where we connect the RX to TX oppositely.

How to start and send and receive data between them? I have no idea how the code can be written.

body:
At instructables there is a good [post][1].

In short the code is

Master code:

    // Include the required Wire library for I2C
    #include <Wire.h>
    int x = 0;
    void setup() {
      // Start the I2C Bus as Master
      Wire.begin();
    }
    void loop() {
      Wire.beginTransmission(9); // transmit to device #9
      Wire.write(x);              // sends x
      Wire.endTransmission();    // stop transmitting
      x++; // Increment x
      if (x > 5) x = 0; // `reset x once it gets 6
      delay(500);
    }

Slave code

    // Include the required Wire library for I2C
    #include <Wire.h>
    int LED = 13;
    int x = 0;
    void setup() {
      // Define the LED pin as Output
      pinMode (LED, OUTPUT);
      // Start the I2C Bus as Slave on address 9
      Wire.begin(9);
      // Attach a function to trigger when something is received.
      Wire.onReceive(receiveEvent);
    }
    void receiveEvent(int bytes) {
      x = Wire.read();    // read one character from the I2C
    }
    void loop() {
      //If value received is 0 blink LED for 200 ms
      if (x == '0') {
        digitalWrite(LED, HIGH);
        delay(200);
        digitalWrite(LED, LOW);
        delay(200);
      }
      //If value received is 3 blink LED for 400 ms
      if (x == '3') {
        digitalWrite(LED, HIGH);
        delay(400);
        digitalWrite(LED, LOW);
        delay(400);
      }
    }

  [1]: http://www.instructables.com/id/I2C-between-Arduinos/

In the instructables post a lot more explanation is shown.


message:
Formula to calculate energy required to power an Arduino board

Given an Arduino board with the following specs:

**ATmega328 Arduino Nano AVR® ATmega MCU 8-Bit AVR Embedded Evaluation Board** ([link][1])

What is the mathematical formula to calculate how much energy/power would be required to keep the Arduino board on (meaning in "standby" mode, therefore not consuming any energy but the one required to keep it "alive")?

Please note I am new to all things electronics, Arduino but most importantly physics and maths. Thank you.

  [1]: https://www.digikey.co.uk/product-detail/en/A000005/1050-1001-ND/2638989

body:
In the datasheet you can read how much every mode uses (normal mode, sleep mode etc). However, it also depends on which peripherals inside the CPU are active and all electronics around it. So make sure you read the datasheet of the entire development board, and not from the CPU itself.

The mathematical formula is reasonably simple: the total power is the sum of each component's Amperage * component's Voltage. But practicially this is hard to calculate.

The easiest way (but not mathematically) is probably just to measure the amperage in the development board, and the voltage and multipley them together.


message:
How to receive more than 64 bytes on Arduino?

I am receiving about 90 bytes on the serial port. But Arduino has a serial buffer of 64 bytes only. Because of this limitation I am unable to receive further bytes.

    char c;

    void read_response() {
      while(Serial.available > 0) {
        c=Serial.read();
        Serial.print(c,HEX);
        Serial.print(",");
      }
    }

I tried using the above function to read the serial data, but it is able to read only 64 bytes.

Another approach I tried as follows:

    char rxdata[]={};

    void read_response() {
      while(Serial.available > 0) {
        int len= Serial.readBytes(rxdata, 90)
      }
    }

With this approach too, I was receiving only 64 bytes.

`Serial.flush()` also doesn't work as it waits for current transmission to finish. And I do not have control on transmission. The transmitter is sending 90 bytes continuously.

Please give me some suggestions.

body:
You will need to adjust your concept of serial communication so that you don't rely on the complete 90 bytes of data to be transferred to the serial input buffer before you read it into RAM.

Instead you need to continually empty the hardware buffer into RAM as often as you run through `loop()`, and avoid using `delay()`, which will stop your program from being able to drain the buffer.

To know when you have reached the end of the transmission, you should either ensure that the incoming serial stream has a marker at the end (such as a `'\n'` character) or is always a fixed length (such as always exactly 90 bytes.)

As an example, here is a program that looks for `'\n'` as the end-of-data marker:

    #DEFINE MAX_INPUT 90

    char inputBuffer[MAX_INPUT+1]; // Handles up to 90 bytes in a c-style string, with a null character termination.

    void setup()
    {
      Serial.begin(115200); // initialization
      inputBuffer[0] = '\0'; //Initialize string to emtpy.
      Serial.println("Begin:");
    }

    void loop() {

      if (Serial.available()>0)
      {
        char input = Serial.read();
        static int s_len; // static variables default to 0
        if (s_len>=MAX_INPUT) {
          // Have received already the maximum number of characters
          // Ignore all new input until line termination occurs
        } else if (input != '\n' && input != '\r') {
          inputBuffer[s_len++] = input;
        } else {
          // Have received a LF or CR character

          // INSERT YOUR CODE HERE TO PROCESS THE RECEIVED DATA //
          // YOU COULD COPY TO A NEW VARIABLE WITH strncpy() OR //
          // SET A FLAG TO SAY TO START SOME OTHER TASK         //
          Serial.print("RECEIVED MSG: ");
          Serial.println(inputBuffer);

          memset(inputBuffer, 0, sizeof(inputBuffer));
          s_len = 0;             // Reset input buffer here if you
                                 // have already copied the data.
                                 // If you don't reset here, then
                                 // you can't start receiving more
                                 // serial port data. This is your
                                 // 'software' serial buffer, contrast
                                 // with the hardware serial buffer.
        }
      }
    }


body:
> But Arduino has a serial buffer of 64 bytes only. Because of this limitation I am unable to receive further bytes.

This assertion is nonsense. Certainly there is a buffer, but that lets you receive up to 64 bytes (put there by the serial interrupt service routine) before you retrieve a single one.

All you need to do is expeditiously retrieve the data (that is, do a `Serial.read()`) fast enough that you remove the data from the buffer and store it into memory.

You need to post a [Minimal, Complete, and Verifiable Example (MCVE)](https://stackoverflow.com/help/mcve) that demonstrates your problem. For example, are you doing `delay(1000)` before attempting to read serial data?

See my post about [receiving serial data without blocking](http://www.gammon.com.au/serial) and also [Async (Serial) peripheral interface - for Arduino ](http://www.gammon.com.au/forum/?id=10894).


message:
Can only write 5V or 0V, not something in between

I'm working on a bigger project, and needs to give out a voltages between 0 and 5V. I've written this code:

    int ledPin = 12;      // LED connected to digital pin

    void setup(){
    pinMode(ledPin, OUTPUT);   // sets the pin as output
    }

    void loop(){
    analogWrite(ledPin, 255);
    delay(2000);
    analogWrite(ledPin, 0);
    delay(2000);
    analogWrite(ledPin, 127);
    delay(2000);
    analogWrite(ledPin, 128);
    delay(2000);
    }

If I've understood it right, this should first give about 5V, then 0V, then 2.5V and againg 2.5V. However my voltmeter only reads 5V and 0V, 2 seconds at each. I've attached my voltmeter to pin 12 and ground. The arduino board is also grounded.

body:
The PWM pins output a square wave from 0 to 5V. If you want something more like a DC level, then run the signal thru a Resistor-Capacitor (RC) Lowpass filter.
1K and 10uF should work well to smooth the squarewave.
http://sim.okawa-denshi.jp/en/CRtool.php

On an Uno, pins 3,5,6,9,10,11 are the PWM pins and output at a frequency of ~ 490 Hz or 980 Hz, with a duty cycle from 1 to 254. 0 is full off, 255 full on.


body:
Most Arduino boards do not have true analog output that can produce voltage range. To check if a particular board has true analog output check the specs and look for pins labeled DAC or Digital-to-analog converter.  Be aware that the supported voltage range will vary depending on the board.

The analogWrite() function uses [Pulse Width Modulation][1] to simulate analog output.

If you need true analog output you will need to attach a Digital to Analog Converter(DAC) to the arduino. e.g. https://learn.adafruit.com/mcp4725-12-bit-dac-tutorial

UPDATE:
If your goal is to drive a motor with a [SN754410][2] you should be able to use the PWM analog output to drive it at varying speeds.  Here is an example: http://web.ics.purdue.edu/~fwinkler/616/sn754410_Arduino.pdf

  [1]: https://www.arduino.cc/en/Tutorial/PWM
  [2]: http://www.ti.com/lit/ds/symlink/sn754410.pdf


message:
Arduino IDE libraries search

Where I can do search libraries on WEB, that similar search in IDE? I did not find search page on `arduino.cc`

body:
You get widest search with Google. Write "arduino" and then the device or topic name.

Most of the libraries have a [GitHub][1] repository. You can use a search field on GitHub.

[A list of selected libraries][2] sorted by topic is on Arduino playground.

  [1]: https://github.com/
  [2]: https://playground.arduino.cc/Main/LibraryList


body:
You can search the [PlatformIO Library Database](https://platformio.org/lib). It covers libraries for many architectures and platforms, but if you add `framework:arduino` to the start of your search it narrows it down to just Arduino libraries.

From there you can go to the homepage or repository for a library you want.

It doesn't have all libraries, only the ones that have been set up for PlatformIO support, but that is quite a lot of libraries now.


body:
The online analog of the Arduino IDE's Library Manager search feature is located here:

https://www.arduinolibraries.info/

That website is generated from the same index file Library Manager uses:

http://downloads.arduino.cc/libraries/library_index.json


message:
Action while button is pressed

**My issue is that I can't rotate the motors continuously. If I press any button, motor.step will be executed and then it stops, even though I didn't release the button.**
This is my project so far.
Code:

    #include <AFMotor.h>

    //define steppers
    AF_Stepper motor1(48, 1);
    AF_Stepper motor2(48, 2);

    char data;

    void setup()
    {

      motor1.setSpeed(200);  // 10 rpm
      motor2.setSpeed(200);  // 10 rpm
      Serial.begin(9600);
    }

    void loop()
    {
      Serial.println(data);
      if (Serial.available())
      {
        data = Serial.read();
        if (data == 'A')
        {
          motor1.step(200, FORWARD, DOUBLE);
        }
        if (data == 'B')
        {
          motor1.step(200, BACKWARD, DOUBLE);
        }
        if (data == 'C')
        {
          motor2.step(200, FORWARD, SINGLE);
        }
        if (data == 'D')
        {
          motor2.step(200, BACKWARD, SINGLE);
        }
        if (data == 'E')
        {
        delay(50);
        }
      }
    }

App Inventor blocks:[![app inventor blocks][1]][1]

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

body:
Serial isn't a keyboard. When you send 'A' you send 'A'. Whatever that source is - if you send a single A you send a single A, and you receive a single A.

You will have to come up with some other protocol and write some special software on your computer that monitors the keys directly, and sends something along the lines of "I Pressed A" and "I Released A".


body:
This statement: `data = Serial.read();` consumes the data sent over the serial port, so to get continual movement, you will have to constantly feed in `A` or `B`, etc. from whatever is generating that data.

Alternately, you could define a 2nd set of single-character commands to accompany the start-rotation parts so that send one command to turn on the motor, and a different command to turn off the motor. You would need to add a variable to hold the current state (started or stopped) of each motor, and turn on or off those states depending on what commands come in from the user.

(untested code)

    #include <AFMotor.h>

    //define steppers
    AF_Stepper motor1(48, 1);
    AF_Stepper motor2(48, 2);

    char data;
    int8_t motor1state=0;  // 0=> Stopped, -1=>Reverse, 1=>Forward
    int8_t motor2state=0;

    void setup()
    {
      motor1.setSpeed(200);  // 10 rpm
      motor2.setSpeed(200);  // 10 rpm
      Serial.begin(9600);
    }

    void loop()
    {
      Serial.println(data);
      if (Serial.available())
      {
        data = Serial.read();
        if (data == 'A')
        {
          motor1state = 1;
        }
        if (data == 'B')
        {
          motor1state = -1;
        }
        if (data == 'C')
        {
          motor2state = 1;
        }
        if (data == 'D')
        {
          motor2state = -1;
        }
        if (data == 'F')
        {
          motor1state = 0;
        }
        if (data == 'G')
        {
          motor2state = 0;
        }
        if (data == 'E')
        {
        delay(50);
        }
      }

      if (motor1state>0)
      {
        // Step forward
        motor1.step(200, FORWARD, DOUBLE);
      }
      else if (motor1state<0)
      {
        // Step backward
        motor1.step(200, BACKWARD, DOUBLE);
      }
      else
      {
        // Do nothing
      }

      if (motor2state>0)
      {
        // Step forward
        motor2.step(200, FORWARD, SINGLE);
      }
      else if (motor2state<0)
      {
        // Step backward
        motor2.step(200, BACKWARD, SINGLE);
      }
      else
      {
        // Do nothing
      }
    }


message:
Program doesn't read memory well

My program does not read the contents of the memory card, in this case the file "objects.txt". What I wanted to do was: the program reads the objects contained in the text file and allocates the table, then organizes the table alphabetically.

Something is escaping me. Another thing, how do I put a function recognizing if the user pressed a button and if pressed, the program continues?

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

    #include <LiquidCrystal.h>
    #include <SPI.h>
    #include <SD.h>

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

    // define some values used by the panel and buttons
    int lcd_key     = 0;
    int adc_key_in  = 0;
    int x = 0;
    String files, memo, memo1;
    int sizef = 0;
    int sizef1 = 0;
    int sizef2 = 0;
    int y = 0;
    int z = 0;

    struct objeto_celeste_s {
      char nome[20];
      float ar;
      float dec;
    };
    typedef struct objeto_celeste_s objeto_celeste;

    char * tab1 [6];
    int myCompareFunction (const void * arg1, const void * arg2) {
      return strcmp (*(char **) arg1, *(char **) arg2);
    }

    File root;
    File file;

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

    char * list[] = {"1.Modo Normal    ", "2.Modo Teste    ", "3.Modo GoTo     ", "4.Modo Manual  "};

    // read the buttons
    int read_LCD_buttons() {
      adc_key_in = analogRead(0);
      if (adc_key_in > 1000) return btnNONE;
      if (adc_key_in < 50)   return btnRIGHT;
      if (adc_key_in < 250)  return btnUP;
      if (adc_key_in < 400)  return btnDOWN;
      if (adc_key_in < 450)  return btnLEFT;
      if (adc_key_in < 650)  return btnSELECT;
      return btnNONE; // when all others fail, return this...
    }

    void setup() {
      Serial.begin(9600);
      Serial1.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }
      Serial.println ("Welcome!");
      Serial.println ("Selecione um modo no lcd.");
      lcd.begin (16, 2);
      lcd.setCursor (0, 0);
      lcd.print ("  Selecione um");
      lcd.setCursor (0, 1);
      lcd.print ("      modo    ");
      delay (1000);
      lcd.clear ();
      lcd.setCursor(0, 0);
      lcd.print(">");
      lcd.println(list[0]);
      lcd.setCursor(0, 1);
      lcd.print (" ");
      lcd.println(list[1]);
      if (!SD.begin(4)) {
        Serial.println("initialization failed!");
        while (1);
      }
    }

    void loop() {
      lcd_key = read_LCD_buttons();  // read the buttons
      switch (lcd_key) {
        // depending on which button was pushed, we perform an action
        case btnRIGHT:
          break;
        case btnLEFT:
          break;
        case btnUP:
          if (x == 1) {
            x--;
            lcd.clear ();
            lcd.setCursor(0, 0);
            lcd.print(">");
            lcd.println(list[0]);
            lcd.setCursor(0, 1);
            lcd.print (" ");
            lcd.println(list[1]);
          }
          break;
          if (x == 3) {
            x--;
            lcd.clear ();
            lcd.setCursor(0, 0);
            lcd.print(">");
            lcd.println(list[2]);
            lcd.setCursor(0, 1);
            lcd.print (" ");
            lcd.println(list[3]);
          }
          break;
        case btnDOWN:
          if (x == 0) {
            x++;
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print(">");
            lcd.println(list[1]);
            lcd.setCursor(0, 1);
            lcd.println("                ");
          }
          break;
          if (x == 2) {
            x++;
            lcd.clear ();
            lcd.setCursor(0, 0);
            lcd.print(">");
            lcd.println(list[3]);
            lcd.setCursor(0, 1);
            lcd.println("                ");
          }
          break;
        case btnSELECT:
          if (x == 0) {
            lcd.clear ();
            lcd.print ("Modo Normal");
            Serial.println ("Selecionou o modo normal!");
            delay (1000);
            if (SD.exists("objectos.txt")) {
              Serial.println("O ficheiro 'objetos' foi encontrado!");
              lcd.clear ();
              lcd.setCursor (0, 0);
              lcd.print ("Modo Normal");
              delay (1000);
              file = SD.open("objectos.txt", FILE_READ);
              if (file) {
                while (file.available()) {
                  String line = file.readStringUntil('\n');
                  sizef++;
                }
              } else {
                //se houver erro a abrir o ficheiro
                Serial.println("Erro a abrir o ficheiro 'objectos.txt'.");
              }
              objeto_celeste *tab = (objeto_celeste *)malloc((sizef) * sizeof(objeto_celeste));
              Serial.print ("Contados ");
              Serial.print (sizef);
              Serial.println (" objetos no ficheiro objectos.txt.");
              if (tab == NULL) {
                lcd.clear ();
                lcd.print ("Erro a alocar memoria");
                Serial.println ("Erro a alocar memória");
                while (1) { };
              } else {
                Serial.print ("Memória alocada para ");
                Serial.print (sizef);
                Serial.println (" objectos.");
                lcd.setCursor (0, 1);
                lcd.print ("Alocados ");
                lcd.print (sizef);
                lcd.print (" obj");
              }
              file.close();
              char * line1 = (char*) malloc(15);
              file = SD.open("objectos.txt", FILE_READ);
              if (file) {
                Serial.println ("Carregando informação para a memória:");
                while (file.available()) {
                  if (file.read() == '\n') {
                    char * justafun = strtok (line1, " "); //divide em tokens
                    while (justafun != NULL) {
                      if (y == 0) {
                        strcpy (tab[sizef2].nome, justafun);
                        Serial.print ("[");
                        Serial.print (sizef2);
                        Serial.print ("] ");
                        Serial.print(tab[sizef2].nome);
                        Serial.print (" ");
                        y++;
                      }
                      if (y == 1) {
                        tab[sizef2].ar = atof (justafun);
                        Serial.print (tab[sizef2].ar);
                        Serial.print (" ");
                        y++;
                      }
                      if (y == 2) {
                        tab[sizef2].dec = atof (justafun);
                        Serial.println (tab[sizef2].dec);
                        sizef2++;
                        y = 0;
                      }
                      justafun = strtok (NULL, " ");
                    }
                  }
                }
              }
              file.close ();
              delay (1500);
              lcd.clear ();
              Serial.println ("Proceda ao alinhamento manual do telescópio.");
              lcd.setCursor (0, 0);
              lcd.print ("Proceda ao ");
              lcd.setCursor (0, 1);
              lcd.print ("Alinhamento man.");
              Serial.println ("Depois de o alinhamento estar concluido, pressione o botão Select para prosseguir o programa.");
              //colocar aqui função para reconhecer quando pressiona select
              if (Serial1.available()) {
                int inByte = "V"; //Se o alinhamento está concluido, 0 para não e 1 para sim
                Serial1.write (inByte);
              }
              while (!Serial1) {
                if (Serial1.available()) {
                  int inByte = "V";
                  Serial1.write (inByte);
                  int inByte1 = "e";
                  Serial1.write (inByte1);
                }
              }
              delay (1000);
              Serial.println ("Tabela ordenada alfabeticamente:");
              qsort (tab->nome, sizef, sizeof (char *), myCompareFunction);
              for (int i = 0; i < sizef; i++)
                Serial.println (tab[i].nome);
              delay (1000);
              lcd.clear ();
              lcd.print ("Carregue Select");
              lcd.setCursor (0, 1);
              lcd.print ("Para modo manual");
              Serial.println ("Carregue em Select para ir para o modo manual e assim continuar com o programa.");
            } else {
              Serial.println ("O ficheiro 'objetos' não existe.");
              lcd.clear ();
              lcd.print ("Erro nao encontrado");
              delay (2000);
              while (1) { };
            }
          }
          if (x == 1) {
            lcd.clear ();
            lcd.print ("Modo Teste");
            Serial.println ("Selecionou o modo teste!");
            delay (2000);
            if (SD.exists("teste.txt")) {
              Serial.println("O ficheiro 'teste.txt' foi encontrado!");
              lcd.clear ();
              lcd.setCursor (0, 0);
              lcd.print ("Modo Teste");
              lcd.setCursor (0, 1);
              lcd.print ("Ficheiro encontrado");
              delay (2000);
              file = SD.open("teste.txt", FILE_READ);
              if (file) {
                while (file.available()) {//ler o ficheiro
                  String line = file.readStringUntil('\n');
                  sizef++;
                }
                files = "Contados " + String (sizef) + " objetos no ficheiro teste.txt.";
                Serial.println (files);
                objeto_celeste *tab = (objeto_celeste *)malloc((sizef) * sizeof(objeto_celeste));
                memo = "Alocados " + String (sizef) + " obj  ";
                memo1 = "Memória alocada para " + String (sizef) + " objetos.";
                if (tab == NULL) {
                  lcd.clear ();
                  lcd.print ("Erro alocar memoria");
                  Serial.println ("Erro a alocar memória");
                  while (1) { };
                } else {
                  Serial.println (memo1);
                  lcd.setCursor (0, 1);
                  lcd.print (memo);
                }
                file.close();
              } else {
                //se houver erro a abrir o ficheiro
                Serial.println("Erro a abrir o ficheiro 'teste.txt'.");
              }
            } else {
              Serial.println ("O ficheiro 'teste.txt' não foi encontrado.");
              lcd.clear ();
              lcd.print ("Erro nao encontrado");
              delay (2000);
              while (1) { };
            }
          }
          break;
        case btnNONE:
          break;
      }
      delay (200);
    }

body:
I would say you can't add a button that restarts/continues the program. Because of all the `delay(...)` in your code. The arduino chip cant read your input and your button, while it is in a delay mode and hence no reading from the button. Read more about[ **non-blocking delay** ][1]

You need to keep the main `loop` method ongoing so the microcontroller-cpu can do it's work. Instead of waiting in a `delay` loop, doing nothing.

So don't use any `delay`, they are good for beginner to jump start into Arduino.

[![No delay][2]][2]

  [1]: https://www.norwegiancreations.com/2017/09/arduino-tutorial-using-millis-instead-of-delay/
  [2]: https://i.stack.imgur.com/d7Vic.png


message:
ArduCAM OV2640 and microSD card module -- SPI problems

So what I'm trying to do is use the ArduCAM OV2640 (2MP Mini) to take a timelapse. Of course the first thing I have to do it to get it to take a picture and write it to an SD card. The thing is, the camera works fine by itself, however when I hook up the SD card something happens where the SPI no longer works (I have a general understanding of how SPI works -- not a highly technical understanding though).

So my main question is if it's possible for a device using SPI to 'use up' the entire SPI bus so that other peripheral devices can't interact with the microcontroller?

And if so, is there any software or way to visualize this? Like something that monitors the SPI bus?

And as for how to actually fix the problem, would it be practical to use a shield with a built in SD card module? Or use a logic gate to determine which device to allow access?

I really don't have the greatest understanding of this, so any help would be appreciated.

EDIT:

I'm using [this camera module][1] with [this sd card module][2]. As for my wireup, the camera follows as below: [![Camera Schematic][3]][3]

The common pins between the SD card module and camera are VCC,GND,MISO (pin 12) , MOSI (pin 11), and SCK (pin 13). I have an individual CS pin for each.

  [1]: https://www.amazon.com/Arducam-Module-Megapixels-Arduino-Mega2560/dp/B012UXNDOY
  [2]: https://www.amazon.com/Storage-Memory-Shield-Module-Arduino/dp/B01IPCAP72
  [3]: https://i.stack.imgur.com/c8qC7.jpg

body:
In this case, I don't think that a device is "*using SPI to 'use up' the entire SPI bus so that other peripheral devices can't interact with the microcontroller*". I think that your problem probably lies with how your SD card is connecting via the SPI bus.

The problem is that a lot of Serial Peripheral Interface (SPI) devices, particularly the cheaper ones, don't properly put the MISO pin into high-impedance when SS is pulled high.

I had almost exactly this situation with one of my projects. I eventually resolved it by placing a tri-state buffer in the MISO line for each of the SPI devices.

In that case, I used a [74HC125][1] (4-channel tri-state buffer).

This is the page on [Better SPI Bus Design in 3 steps][2] that finally got me on the right track. I think the explanations are reasonably clear (at least compared with many other sites I found!).

  [1]: https://assets.nexperia.com/documents/data-sheet/74HC_HCT125.pdf
  [2]: https://www.dorkbotpdx.org/blog/paul/better_spi_bus_design_in_3_steps


message:
Get IR Signal and its strength

Using an IR sensor, how can I get and decode signals from other IR devices? I've seen the IRRemote library and its forks, but it doesn't fulfill my second requirement which is that I need to be able to tell the signal strength of the IR signal.

In addition, do I have to use a higher-end TSOP module? Or could I just use one of [these](https://www.banggood.com/50pcs-5mm-940nm-IR-Infrared-Diode-Launch-Emitter-Receive-Receiver-LED-p-1205409.html?rmmds=search&cur_warehouse=CN)?

Thank you!

body:
An IR signal is modulated. To understand the data you need to demodulate the signal. The simplest way is with an IR receiver module.  However they condition the signal into a digital signal - it's impossible (on the majority of modules) to get the signal strength.

The devices you link to are IR Photodiodes. They form the optical receiver portion of the IR modules. You need to couple them with some form of demodulating system - either in hardware or, if your MCU is powerful enough, in software.  However, you can get at the raw analog voltages that the photodiode generates to get a signal strength value.

So you have either an easy time of it but no signal strength, or signal strength but a very hard job of interfacing.

So why not take the best bits of both?  Use an IR module to demodulate the signal and give you the data, and next to it use a photodiode and op-amp (to boost the tiny signal) to give you the raw optical intensity?  Yes, it would cost you more, and the circuitry would be more complex, but it's really the only way that you can do it without using specialist modules.

But of course, it begs the question: why do you really want to get this kind of information? Of what use can it be? The "signal strength" is of little benefit since there are so many factors that influence it - incidence angle, distance, transmitter battery voltage, etc.