message:
Windows stops recognizing Arduinos

I've just got my first Arduino Pro Mini and a USB to TTL chip. When I try to upload the program I get the message `The uploader process failed` followed by

`avrdude: ser_open(): can't open device "\\.\COM6": Access is denied.`

and a bunch of lines like
`
avrdude: ser_drain(): read error: The device does not recognize the command.
avrdude: ser_send(): write error: sorry no info avail
avrdude: ser_recv(): read error: The device does not recognize the command.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x48
avrdude: ser_send(): write error: sorry no info avail
`

with 10 attempts after which nothing comes from avrdude and I can't upload nor get Arduino's visible in port choice menu all the time until the Windows 7 boots again. I can upload to my Arduino Uno with no problems before I try the ttl chip. TTL chip also shows up in the port menu before trying to upload, with correct name next to the port number. I installed drivers I found on a official site that sells the chip that looks just the same as mine, before I did that it wouldn't show up in the port choice menu at all. Is there any way to reset whatever it is that is preventing me from uploading to Arduinos so I don't have to restart my computer every time it happens? I managed to upload one program to the Arduino Pro and it's working fine but after a couple of hours, when I tried again, it didn't work. Maybe it would be of some use to say that I left my pc on sleep with the TTL chip plugged in and powered by the usb. My guess is that this chip is defective and was near it's life end when I uploaded so now it's just confusing the driver to the point where Windows decides to block the driver for the session.

body:
After a couple of hours I figured out what was happening so I will write all my analysis here for anyone having some of my problems.

First, a list of my components:

-USB TTL ship, used to upload programs to Arduino Pro. The one on the picture on instructables dot com /id/Usb-to-SerialTTL-adapter/, and used that driver.

-Arduino Pro. Chinese copy, red board just like Sparkfun's. 328p chip @ 5V = 16mhz.

-A board very similar to this one. It has a chip with `FT232` written on it, also `FTDI` in bold letters.
[![usb to ttl][1]][1]

The big USB TTL pcb I was using has 5 output pins: 3v3, 5v, TX, RX, GND. Turns out this is not enough to program Arduino Pro as you need one more pin. If you don't connect this pin, avrdude just gets stuck after opening the COM port and waits indefinitely/until you kill the process. To even be able to see this USB TTL chip in Windows, you need to download a driver from the website(first link) and my guess is that the driver is buggy since it won't exit the process when it encounters this type of error, further leading to suspicious/dangerous behaviour which results in Windows completely shutting down all COM ports until next restart.

To get this pin(it's called DTR/GRN), I borrowed the other chip(3rd) and I connected it regarding to this scheme: [![https://cdn.sparkfun.com/assets/learn_tutorials/2/6/4/smartbasic_programming.png][2]][2]

I also had to download a different driver for it, I don't remember where I downloaded it from but it's called CDM21226 driver, when you install it it says `FTDI driver installed`.

Now my uploading was getting stuck no more, however after the first successful upload to my Arduino Pro the upload process would get stuck in the part where it is burning the program, if you turn verbose option in Arduino IDE on, you can see something like `Writing: [#######              ]`.

It turns out this driver was faulty too, as I uninstalled it and when I installed it with the very same setup as before it worked seamlessly ever since. It also took me some time how to uninstall a Windows driver without using Device Manager because it wouldn't show up there - no device attached to it.

To do that open Command Prompt as admin and type `pnputil.exe -e` to get a list of all drivers. Among them will be one called FTDI and that's the guy, in my case he was called oem51.inf. To delete him, type `pnputil.exe -d oem51.inf`, or add `-f` before `-d` to force deletion - in my case it kept saying device is busy so it required this drastic measure. Change 51 to the number you have above your ftdi driver. After this just install the driver again and everything should be fine, even without reboot.

Phew...
So much work to get a simple program burned to Arduino Pro. Hope you have less trouble with it than I did.

  [1]: https://i.stack.imgur.com/lDQ6g.jpg
  [2]: https://i.stack.imgur.com/zFViI.png


sender: user

message:
Pause in the program for some time

I have a variable `timeInSec` which records the time as loop begins. It is defined as `timeInSec = millis();`. I have two conditions. If `(timeInSec - lastRun)< 5` (that is 5 sec) , the first condition is executed(the if statement).Otherwise if `(timeInSec - lastRun)>5` the second condition is executed(else statement). Here is the code:

    void loop(){
      timeInSec = millis();  // Records time in seconds
      // if(lastRun > 0) {   // if i run this, only else statement is executed
      // delay(10000);
      // }
      if((timeInSec - lastRun) < 5000){  // Treshold time (if condition which runs when timeInSec is less than 5 seconds)
        // Some code
      }
      else{ // If treshold time exceeds (executes when timeInSec is > 5seconds)
       delay(10000);  // if i run this, only else statement is executed
       lastRun = timeInSec;
      }
    }

Here the `else` statement executes once and control goes back `if` statement again. I want to pause the control at `else` statement for 10 seconds and then go back to `if` statement for further execution. Everytime  the control should pause at `else` statement for 10 seconds. I have used `delay` in the `else` statement and in this case only `else` statement is being executed. The same happens if I use `delay` at the start of loop (as in code). I have tried without using `delay` but didn't succeed.

Thanks for the help!

sender: assistant

body:
Do not try to change `millis()`. Instead, record the last time the
second code (else statement) ran, and check whether that was more than
five seconds ago:

    void loop() {
        static uint32_t lastRun;
        uint32_t now = millis();
        if (now - lastRun < 5000) {
            // Some code
        }
        else {
            // Some code
            lastRun = now;  // record the time
        }
    }

This is essentially the same technique used in the [Blink without
delay](https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay) Arduino
tutorial.


message:
Recursive list of files on SD card with indexing

I'm trying to create a way to make a recursive list of the long name of files from an SD card with an index so that I call the file I'd like. Right now, I'm having trouble getting the files to list (!CFile.open() is always returning true regardless of the number of files on the card)

    #include<SPI.h>
    #include "SdFat.h"
    #include "FreeStack.h"

    // SD card chip select pin.
    const uint8_t SD_CS_PIN = 10;

    SdFat sd;
    SdFile file;
    SdFile dirFile;

    // Number of files found.
    uint16_t numberOfFiles = 0;

    // Position of file's directory entry.
    uint16_t dirIndex[300];
    //**Is there a way I make an array without allocating the size here?
    //------------------------------------------------------------------------------
    void setup()
    {
      Serial.begin(38400);
      while (!Serial) {}

      // Initialize at the highest speed supported by the board that is
      // not over 50 MHz. Try a lower speed if SPI errors occur.
      if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50)))
      {
        sd.initErrorHalt();
      }
      if (dirFile.open("/", O_READ))
      {
      Serial.print("Reading: ");
      Serial.println();
      printDirectory(&dirFile, 0);
      }
    }
    void printDirectory (SdFile* CFile, int numTabs)
    {
      while (file.openNext(CFile, O_READ))
      {
        if (file.isHidden()||file.)
        {
          //file hidden, skip
        }
        else
        {
          for (uint8_t i = 0; i < numTabs; i++)
          {
            Serial.print('\t');
          }
          if (file.isSubDir())
          {
            file.printName(&Serial);
            Serial.println();
            printDirectory(&file, numTabs++);
          }
          else
          {
            // Save dirIndex of file in directory.
            dirIndex[numberOfFiles] = file.dirIndex();
            // Print the file number and name.
            Serial.print(numberOfFiles++);
            Serial.write(' ');
            file.printName(&Serial);
            Serial.println();
          }
        }
      file.close();
      }

If someone could help me catch what I've got wrong, I'd like to get a second opinion.

Edit: Updated Code

Edit 2: I'm now getting the first level, but the second level is not printing I think I may be doing something wrong with pointers?

body:
dirFile.open("/", ...) opens the root directory which always exist, even if there are no files.

You can check if there are files by checking openNext. If the first call returns false, there are no files or folders.

Some unrelated remarks:

- Name variables you use, with more than 1 character (so e.g. numberOfFiles instead of n)
- Do not increase a variable inside a Serial.print statement .. if you remove the 'test/debug' code, your sketch behaves differently.

Update:

I now see your question about the array. 300 is probably what you assume is the maximum number of files. Note that if 300 is passed, the sketch will crash.

What you can do to prevent this:

- Easy solution: stop storing files after 300. In this case, make 300 a constant.
- Solid solution: do not use a predetermined length array. However, this means some disadvantages:
  - You have to create a list structure and dynamically change the code.
  - This is slower (probably not an issue since SD card communication is much slower)
  - It can result in memory gaps, resulting in hard to solve memory problems later if the code is extended and more memory is needed.

I suggest you add some code, to stop storing at 300.


message:
Problems with I2C connection on ESP8266 - 12F, which pins should I use?

Previously I had pined the temp/hum sensor HDC1080 with an Arduino using this sketch and everything worked fine. Now I want to run it over an ESP-12F, I uploaded it but it has issues at the time of establishing I2C connection. Basically, I'm not sure if at the end of setup() the I2C connection has actually begun, because I get this at the serial monitor:

[![serial_monitor][1]][1]

As far as I see, the code skips everything related to Wire library. I blame it on the SDA/SCL pins, but actually none of the pins are working for me. I found that default I2C GPIO's are 2 and 14, I tried with them and got no result; later I tried with 12/16, as the commented Wire.begin line says, but it was the same. I even read some possible solutions in this [post](https://github.com/esp8266/Arduino/issues/254) but I not even have the mentioned libraries.

Could you give me any suggestion, please? This is the sketch I'm using:

    #include <Wire.h>

    #define HDC 0x40 //B1000000 MSB
    #define cociente 65536 //2^16

    uint16_t humrawvalue;  //Raw data value, MS byte = valmsb, LS byte = vallsb
    uint16_t temrawvalue;  //Raw data value, MS byte = valmsb, LS byte = vallsb
    uint8_t humvalmsb, humvallsb;  //Raw 8-bit byte of humidity
    uint8_t temvalmsb, temvallsb;  //Raw 8-bit byte of temperature
    int incomingByte = 0; //Action input
    float humidity, temperature;

    void setup() {
      delay(100);
      Serial.begin(9600);
      delay(100);
      Serial.println("Hello");
      //Wire.begin(12,16);
      Wire.begin();
      Wire.setClockStretchLimit(1500);
    }

    void loop() {
      if (Serial.available() > 0) {    //User presses 1 to start sensor reading
        // read the incoming byte:
        incomingByte = Serial.read();
        yield();
        // say what you got:
        Serial.print("I received: ");
        Serial.println(incomingByte, DEC);
      }

      Serial.println("---g-");  //Just guideline

      if (incomingByte == 49){
        Serial.println("IIIII");  //Just guideline
        Wire.beginTransmission(HDC);
        Wire.write(0x00);
        Wire.endTransmission(true);
        delay(200);

        Wire.requestFrom(HDC,4,true); //It asks for 4 bytes, 2 bytes per register
        if(Wire.available()){
          Serial.println("     ");
          Serial.println("Measuring: ");
          temvalmsb = Wire.read();
          temvallsb = Wire.read();
          humvalmsb = Wire.read();
          humvallsb = Wire.read();

          Serial.println("====TEMPERATURE====");
          Serial.print("MSB: "); Serial.println(temvalmsb, BIN);
          Serial.print("LSB: "); Serial.println(temvallsb, BIN);
          temrawvalue = temvalmsb <<8| temvallsb; //Locates each byte in its proper place
          Serial.print("Temp: "); Serial.println(temrawvalue, BIN);
          temperature = ((float)temrawvalue/(float)cociente)*165.0-40.0;
          Serial.print("Temperatura [C]: "); Serial.println(temperature);

          Serial.println("====HUMIDITY====");
          Serial.print("MSB: "); Serial.println(humvalmsb, BIN);
          Serial.print("LSB: "); Serial.println(humvallsb, BIN);
          humrawvalue = humvalmsb <<8| humvallsb;
          Serial.print("Hum: "); Serial.println(humrawvalue, BIN);
          humidity = ((float)humrawvalue/(float)cociente)*100.0;
          Serial.print("Humidity [%]: "); Serial.println(humidity);

          Serial.println("     ");
          delay(3000);
        }
      }
      Serial.println("++++"); //Just guideline
      delay(3000);
    }

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

Regards!

body:
Are you referring the I2C pins on the Arduino? You could just skip the Arduino and wire it direct to the ESP8266 and in your code define which pins you are using for I2C or amend the library accordingly. If you go down this route, make sure you use the correct I2C scanner for the ESP8266. Which can be found on this Instructable, otherwise your I2C won't be detected.

http://www.instructables.com/id/ESP8266-I2C-PORT-and-Address-Scanner/

If you do stick with the Arduino, make sure the library is using the right address, again checking using the Arduino I2C scanner sketch to find which I2C address it is using.

https://playground.arduino.cc/Main/I2cScanner


body:
Unlike most Arduinos, the ESP8266 doesn't have a hardware TWI, so I²C is bit-banged in software. This means that you can use any GPIO pins. By default, `Wire.begin()` initializes pins 4 (SDA) and 5 (SCL), but you can specify other pins using `Wire.begin(int sda, int scl)`.

[Documentation][1]

(Note: the datasheet specifies GPIO2 as SDA and GPIO14 as SCL, but that doesn't matter, AFAIK, it's just a convention.)

  [1]: https://github.com/esp8266/Arduino/blob/master/doc/libraries.rst#i2c-wire-library


message:
Library to set internal analog gain of the Arduino?

My original question was if there is a library that covers the internal **comparator** and **differential** and **gain** modes for the Arduino Uno, Mega 2560, Leonardo, Due, Zero, M0.
The answer is obvious: "No". To my surprise there is not even a start to make it and neither a collaboration to gather usefull code.

If you know pieces of code (Arduino compatible and documentation for which pins) for the analog comparator and gain, then please tell me about it, and I put them in this list.

 - [analogComp][1], a library to manage the analog comparator.
To use the analog comparator for the ATmega8, Arduino Uno, Leonardo, Mega 2560, ATtiny85, and others. A routine is called with an interrupt every time a particolar condition happens.
 - [Arduino Differential ADC and Gain ADC][2]
A file "wiring_differential.c" should be added to the Arduino files. Functions "analogReadDiff" and "analogReadGain" will be added. For the Arduino Leonardo and the Arduino Mega 2560.
 - [Nick Gammon: Using the Arduino Analog Comparator][3]
A simple example of a comparator mode for the ATmega328.
 - [Application Note AT11480: Analog Comparator Application Examples][4]
Using the Analog Comparator for SAM D (that includes the ATSAMD21 of the Arduino Zero and M0) processors.

  [1]: http://www.leonardomiliani.com/en/2012/analogcomp-una-libreria-per-gestire-il-comparatore-analogico/
  [2]: https://lawas.nahdhi.com/arduino-differential-adc-and-gain-adc.html
  [3]: https://www.gammon.com.au/forum/?id=11916
  [4]: http://www.atmel.com/Images/Atmel-42473-Analog-Comparator-Application-Examples_UserGuide_AT11480.pdf

body:
What you are trying to do can be easily done via simple programming of the channels bits in the ADV module - the datasheet is your best friend here.

So if you want to take this one, take a look at the datasheet and that's all there is to it.

Happy to provide a sample piece to get you going.


body:
I would recommend you to check [Nick Gammon's example on using the analog comparator][1] by means of configuring the relevant flag bits of registers in the ATmega328. Sample code from the link, by Nick:

    volatile boolean triggered;

    ISR (ANALOG_COMP_vect)
      {
      triggered = true;
      }

    void setup ()
      {
      Serial.begin (115200);
      Serial.println ("Started.");
      ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
      ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
            | bit (ACIE)    // Analog Comparator Interrupt Enable
            | bit (ACIS1);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on falling edge)
       }  // end of setup

    void loop ()
      {
      if (triggered)
        {
        Serial.println ("Triggered!");
        triggered = false;
        }

      }  // end of loop

  [1]: https://www.gammon.com.au/forum/?id=11916


body:
You seem to be interested mainly in ATSAMD21. There is an application note from Atmel, [AT11480: Analog Comparator Application Examples][1], which may be of interest for you.

From the *Getting started* section (3.1, page 8):

> The AC [Analog Comparator] example project has to be opened from New
> Example Project option in Atmel Studio. Using the option Atmel Studio
> → File → New → Example Project will open the New Example Project from
> ASF or Extensions window. The project named Analog Comparator Examples
> – SAM D21 Xplained Pro has to be opened.

There you'll find example code that might be useful for you, as it will show how to configure and manage the registers involved in using the analog comparator of the ATSAMD21. Namely, the example code is related to the following example applications:

 1. Level crossing detector.
 2. Window mode operation.
 3. Preventing false spike detection.
 4. Gray signal frequency measurement.
 5. SleepWalking with analog comparator.

If you look into the first case (**level crossing detector**) for guidelines for where to start from, you can see that the application example goes through the following steps:

 1. Enable alternate function H (AC/CMP[0]) for pin PA12 so that the comparator 0 output is directly routed to the pin.
 2. Select GCLK Generator 0 as GCLK source for AC module. The GCLK Generator 0 is clocked from internal OSC8M oscillator whose output is set to 8MHz.
 3. Select AIN[0] pin (PA04) as positive input and internal voltage scaler output as negative input for comparator 0. The voltage scaler register is set to a value of 9 corresponding to a voltage output of 0.5156V.
 4. Set comparator 0 in continuous comparison mode with hysteresis and filter mode disabled.
 5. Enable comparator 0 output to be routed to I/O pin and select interrupt mode as toggle so that comparator output toggles when positive input crosses the negative input (both during rising and falling).
 6. Enable comparator 0 and then enable the AC module.

You could get from that example code some ideas about the registers to be configured and managed, and then try to use that knowledge for creating (or even reusing) some code within the Arduino IDE.

Hope it helps...

  [1]: http://www.atmel.com/Images/Atmel-42473-Analog-Comparator-Application-Examples_UserGuide_AT11480.pdf


body:
I tried to find further information that would help you about the ATSAMD21, but I only managed to find the source code for the definitions of the [Analog Comparator Controller (ACC)][1], the [Power Management Controller (PMC)][2], and some [example code][3] as well. The example code follows, to avoid this being a link-only answer:

     #include "asf.h"
     #include "stdio_serial.h"
     #include "conf_board.h"
     #include "conf_clock.h"

     #define VOLT_REF   (3300)

     #define MAX_DIGITAL (4095)

     #define DACC_CHANNEL_0 0

     #define DACC_ANALOG_CONTROL (DACC_ACR_IBCTLCH0(0x02) \
                               | DACC_ACR_IBCTLCH1(0x02) \
                               | DACC_ACR_IBCTLDACCORE(0x01))

     #define ADC_CLOCK 6400000

     #define ADC_STARTUP_TIME_SETTING 0x8u

     #define ADC_TRACK_SETTING 0x0u

     #define ADC_TRANSFER_SETTING 0x1u

     #define ACC_SELPLUS_AD5  0x5u
     #define ACC_SELMINUS_DAC0  0x2u
     #define ACC_EDGETYP_ANY  0x2u
     #define ACC_INVERT_NO 0x0u

     #define STRING_EOL    "\r"
     #define STRING_HEADER "-- ACC IRQ Example  --\r\n" \
             "-- "BOARD_NAME" --\r\n" \
             "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL

     void ACC_Handler(void)
     {
         uint32_t ul_status;

         ul_status = acc_get_interrupt_status(ACC);

         /* Compare Output Interrupt */
         if ((ul_status & ACC_ISR_CE) == ACC_ISR_CE) {

             if (acc_get_comparison_result(ACC)) {
                 puts("-ISR- Voltage Comparison Result: AD5 > DAC0\r");
             } else {
                 puts("-ISR- Voltage Comparison Result: AD5 < DAC0\r");
             }
         }
     }

     static void configure_console(void)
     {
         const usart_serial_options_t uart_serial_options = {
             .baudrate = CONF_UART_BAUDRATE,
             .paritytype = CONF_UART_PARITY
         };

         /* Configure console UART. */
         sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
         stdio_serial_init(CONF_UART, &uart_serial_options);
     }

     static void dsplay_menu(void)
     {
         puts("-- Menu Choices for this example--\n\r"
                 "  s: Set new DAC0 output voltage.\n\r"
                 "  v: Get voltage on potentiometer.\n\r"
                 "  m: Display this menu again.\r");
     }

     static int16_t get_input_voltage(void)
     {
         uint8_t i = 0, uc_key;
         int16_t us_value = 0;
         int8_t c_length = 0;
         int8_t ac_str_temp[5] = { 0 };

         while (1) {
             while (uart_read(CONSOLE_UART, &uc_key)) {
             }
             if (uc_key == '\n' || uc_key == '\r') {
                 puts("\r");
                 break;
             }

             if ('0' <= uc_key && '9' >= uc_key) {
                 printf("%c", uc_key);
                 ac_str_temp[i++] = uc_key;

                 if (i >= 4)
                     break;
             }
         }

         ac_str_temp[i] = '\0';
         /* Input string length */
         c_length = i;
         us_value = 0;

         /* Convert string to integer */
         for (i = 0; i < 4; i++) {
             if (ac_str_temp[i] != '0') {
                 switch (c_length - i - 1) {
                 case 0:
                     us_value += (ac_str_temp[i] - '0');
                     break;
                 case 1:
                     us_value += (ac_str_temp[i] - '0') * 10;
                     break;
                 case 2:
                     us_value += (ac_str_temp[i] - '0') * 100;
                     break;
                 case 3:
                     us_value += (ac_str_temp[i] - '0') * 1000;
                     break;
                 }
             }
         }

         if (us_value > (5 * VOLT_REF / 6) || us_value < (1 * VOLT_REF / 6)) {
             return -1;
         }

         return us_value;
     }

     int main(void)
     {
         uint8_t uc_key;
         int16_t s_volt = 0;
         uint32_t ul_value = 0;
         volatile uint32_t ul_status = 0x0;
         int32_t l_volt_dac0 = 0;

         /* Initialize the system */
         sysclk_init();
         board_init();

         /* Initialize debug console */
         configure_console();

         /* Output example information */
         puts(STRING_HEADER);

         /* Initialize DACC */
         /* Enable clock for DACC */
         pmc_enable_periph_clk(ID_DACC);
         /* Reset DACC registers */
         dacc_reset(DACC);
         /* External trigger mode disabled. DACC in free running mode. */
         dacc_disable_trigger(DACC);
         /* Half word transfer mode */
         dacc_set_transfer_mode(DACC, 0);
         /* Power save:
          * sleep mode  - 0 (disabled)
          * fast wakeup - 0 (disabled)
          */
         dacc_set_power_save(DACC, 0, 0);
         /* Timing:
          * refresh        - 0x08 (1024*8 dacc clocks)
          * max speed mode -    0 (disabled)
          * startup time   - 0xf (960 dacc clocks)
          */
         dacc_set_timing(DACC, 0x08, 0, 0xf);
         /* Disable TAG and select output channel DACC_CHANNEL */
         dacc_set_channel_selection(DACC, DACC_CHANNEL_0);
         /* Enable output channel DACC_CHANNEL */
         dacc_enable_channel(DACC, DACC_CHANNEL_0);
         /* Setup analog current */
         dacc_set_analog_control(DACC, DACC_ANALOG_CONTROL);

         /* Set DAC0 output at ADVREF/2. The DAC formula is:
          *
          * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
          * ----------------------------------- = --------------------------
          *              MAX_DIGITAL                       digit
          *
          * Here, digit = MAX_DIGITAL/2
          */
         dacc_write_conversion_data(DACC, MAX_DIGITAL / 2);
         l_volt_dac0 = (MAX_DIGITAL / 2) * (2 * VOLT_REF / 3) / MAX_DIGITAL +
                 VOLT_REF / 6;

         /* Initialize ADC */
         /* Enable clock for ADC */
         pmc_enable_periph_clk(ID_ADC);
         /*
          * Formula: ADCClock = MCK / ( (PRESCAL+1) * 2 )
          * For example, MCK = 64MHZ, PRESCAL = 4, then:
          *     ADCClock = 64 / ((4+1) * 2) = 6.4MHz;
          */
         adc_init(ADC, sysclk_get_cpu_hz(), ADC_CLOCK, ADC_STARTUP_TIME_SETTING);

         /* Formula:
          *     Startup  Time = startup value / ADCClock
          *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
          *     Tracking Time = (TRACKTIM + 1) / ADCClock
          *     Settling Time = settling value / ADCClock
          * For example, ADC clock = 6MHz (166.7 ns)
          *     Startup time = 512 / 6MHz = 85.3 us
          *     Transfer Time = (1 * 2 + 3) / 6MHz = 833.3 ns
          *     Tracking Time = (0 + 1) / 6MHz = 166.7 ns
          *     Settling Time = 3 / 6MHz = 500 ns
          */
         /* Set ADC timing */
         adc_configure_timing(ADC, ADC_TRACK_SETTING, ADC_SETTLING_TIME_3,
                 ADC_TRANSFER_SETTING);

         /* Channel 5 has to be compared */
         adc_enable_channel(ADC, ADC_CHANNEL_5);

         /* Enable clock for ACC */
         pmc_enable_periph_clk(ID_ACC);
         /* Initialize ACC */
         acc_init(ACC, ACC_SELPLUS_AD5, ACC_SELMINUS_DAC0,
                 ACC_EDGETYP_ANY, ACC_INVERT_NO);

         /* Enable ACC interrupt */
         NVIC_EnableIRQ(ACC_IRQn);

         /* Enable */
         acc_enable_interrupt(ACC);

         dsplay_menu();

         while (1) {
             while (uart_read(CONSOLE_UART, &uc_key)) {
             }

             printf("input: %c\r\n", uc_key);

             switch (uc_key) {
             case 's':
             case 'S':
                 printf("Input DAC0 output voltage (%d~%d mv): ",
                         (VOLT_REF / 6), (VOLT_REF * 5 / 6));
                 s_volt = get_input_voltage();
                 puts("\r");

                 if (s_volt > 0) {
                     l_volt_dac0 = s_volt;
                     /* The DAC formula is:
                      *
                      * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
                      * ----------------------------------- = --------------------------
                      *              MAX_DIGITAL                       digit
                      *
                      */
                     ul_value = ((s_volt - (VOLT_REF / 6))
                         * (MAX_DIGITAL * 6) / 4) / VOLT_REF;
                     dacc_write_conversion_data(DACC, ul_value);
                     puts("-I- Set ok\r");
                 } else {
                     puts("-I- Input voltage is invalid\r");
                 }
                 break;
             case 'v':
             case 'V':
                 /* Start conversion */
                 adc_start(ADC);
                 ul_status = adc_get_status(ADC);
                 while ((ul_status & ADC_ISR_EOC5) != ADC_ISR_EOC5) {
                     ul_status = adc_get_status(ADC);
                 }
                 /* Conversion is done */
                 ul_value = adc_get_channel_value(ADC, ADC_CHANNEL_5);

                 /*
                  * Convert ADC sample data to voltage value:
                  * voltage value = (sample data / max. resolution) * reference voltage
                  */
                 s_volt = (ul_value * VOLT_REF) / MAX_DIGITAL;
                 printf("-I- Voltage on potentiometer(AD5) is %d mv\n\r", s_volt);
                 printf("-I- Voltage on DAC0 is %ld mv \n\r", (long)l_volt_dac0);
                 break;

             case 'm':
             case 'M':
                 dsplay_menu();
                 break;
             }
         }
     }

I'm afraid you'll have to study how to configure the registers, taking the datasheet and, as a guideline, **the ACC and PMC definitions linked above**.

  [1]: http://asf.atmel.com/docs/3.8.1/sam.drivers.acc.example.sam4s_ek/html/component__acc_8h_source.html
  [2]: http://asf.atmel.com/docs/3.8.1/sam.drivers.acc.example.sam4s_ek/html/component__pmc_8h_source.html
  [3]: http://asf.atmel.com/docs/3.8.1/sam.drivers.acc.example.sam4s_ek/html/acc__example_8c_source.html


message:
Transistor switching problem

With my team we constructed a circuit using Arduino. The circuit works on the Proteus simulator. It worked fine with LEDs connected directly to Arduino outputs.

However, when I used Arduino output to trigger a BC 337 transistor to try and actuate a 12 V DC coiled relay, it wouldn't trigger. I measured voltage across transistor collector and emitter, it reads 12 V, just like the source I gave... (The transistor is not switched on I guess).

Supply for the Arduino is a constant 5 V DC.

Where have I gone wrong? Picture as uploaded.

[![Full circuit][1]][1]

Furthermore, we are trying to build a controller for an ice making machine. The power circuit (12 V) is to be controlled by Arduino through the transistors.

I am uploading the codes we used and the full circuit diagram.

    const int start = 13;
    const int comp= 2;
    const int cond=3;
    const int hGas=4;
    const int wbut=12;
    const int watersol=5;
    const int dumper=6;
    const int iced=11;

    int startButton=0;
    int waterButton=0;
    int dumperlimswitch=0;

    void setup() {

      pinMode(start, INPUT);
      pinMode(comp, OUTPUT);
      pinMode(cond, OUTPUT);
      pinMode(hGas, OUTPUT);
      pinMode(wbut,INPUT);
      pinMode(watersol, OUTPUT);
      pinMode(dumper, OUTPUT);
      pinMode(iced, INPUT);
    }

    void loop() {

    startButton = digitalRead(start);
    waterButton = digitalRead(wbut);

     if (startButton == HIGH) {

        digitalWrite(comp, HIGH);
        digitalWrite(cond, HIGH);

        waterButton = digitalRead(wbut);
        if (waterButton == HIGH){
          digitalWrite(watersol,HIGH);
          }
        else{
          digitalWrite(watersol,LOW);
          }
         delay(800);
        digitalWrite(hGas,HIGH);
        digitalWrite(cond, LOW);

        waterButton = digitalRead(wbut);
        if (waterButton == HIGH){
          digitalWrite(watersol,HIGH);
          }
        else{
          digitalWrite(watersol,LOW);
          }
        delay(500);
        digitalWrite(hGas, LOW);
        digitalWrite(dumper, HIGH);
        digitalWrite(cond, HIGH);

        waterButton = digitalRead(wbut);
        if (waterButton == HIGH){
          digitalWrite(watersol,HIGH);
          }
        else{
          digitalWrite(watersol,LOW);
          }
        delay(800);
        digitalWrite(dumper, LOW);
      }
    else {
        digitalWrite(comp, LOW);
        digitalWrite(cond, LOW);
      }
    }

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

body:
This is not an answer but its too big to be a comment.  I can't solve your problem, but hopefully I can point you in the right direction.

I think the first problem you have is you have talked this problem in one chunk.  I think even some of the more experienced users would have a problem hitting this in one go.  You need to break it down into simple units (Functional decomposition if you want to be posh).

The problem you are asking about is why your transistor doesn't work.  You have used an LED and you think the correct signals are being sent.

So Phase one, take the transistor and test it in isolation, then you know its working.  Secondly does it still work when the Uno is controlling it rather than just a battery?

Does the object you are powering via the transistor work on its own?
Does it work when you add it to the uno and transistor?

You get the idea.  To be honest I suspect it might be an issue with lack of power.


body:
**TL/DR:** Your LEDs without resistors are diverting all the current away from the transistors so they are unable to switch.

**In detail:**

Let's take a quick look at just one small portion of your circuit in more detail:

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

I have added an extra resistor into the circuit - Rw - which represents the resistance of the wires and pins of the LED, and I have given it a nominal 0.1Ω value.

Now, let's say you set the GPIO HIGH, so it outputs 5V. The LED, D1, is a typical red LED with a forward voltage of, say, 2V.  Let's calculate the current through the LED.

* I = (VCC - VF)/R = (5 - 2) / 0.1 = 3 / 0.1 = 30A

30A?! But the GPIO can't provide more than 40mA *absolute maximum*. So all that *can* come from the GPIO is being sent straight through the LED leaving nothing (much) for the transistor.

Oh and yes, all that current demand is doing unspeakable damage to the Arduino's GPIO pin.

The transistor's Base-Emitter junction has about a 0.7V drop across it, and, if it weren't for the LED, with the 1kΩ resistor that gives (5-0.7)/1000 = 4.3mA. Which with a hFE of around 100, would give a collector current of around 430mA. And that should be fine for most small relays.

But with all the current being dumped through the LED what can get through to the transistor won't be enough to turn on the relay.

So increasing the resistance of the wire to the LED will decrease the current demands of the LED. And of course you do that by adding a resistor. So let's make that 1kΩ - a decent enough value for a simple indicator LED:

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

Now let's do the calculation for the LED's current:

* I = (VCC - VF) / R = (5 - 2) / 1000 = 3 / 1000 = 3mA

Add that to the 4.3mA that wants to go through the transistor, and we have 7.3mA in total.

Now that is way below what the Arduino's GPIO can provide, so the IO pin is happy, the LED is happy and, most importantly, the transistor is happy.


message:
Using tinyGPS++ with millis errors

Hi I am trying to make search GPS (using tinGPSplus) every x time. The problem is when I do compile the code:

    void loop()
    {
        read=BP_mnger.pressedButton();
        navigateMenus(read);
        dealWithUsedEvents(getmenuUsed());
        setmenuUsed(0);

        if (isStarted && (GPSSearchPeriod<=millis()-oldMillisVallue)) {

            oldMillisVallue=millis();// if i comment this line it works
            Serial.print(F("oldMillisVallue: "));
            Serial.println(oldMillisVallue);
            while (ss.available() > 0){
                if (gps.encode(ss.read()))
                    if (gps.location.isUpdated() || gps.date.isUpdated() || gps.time.isUpdated() || gps.altitude.isUpdated() || gps.satellites.isUpdated() || gps.hdop.isUpdated())
                        GPSSentence=makeGPSSentence( );
            }

        }

I get this:

    oldMillisVallue: 22355
    oldMillisVallue: 24356
    oldMillisVallue: 26357
    oldMillisVallue: 28358
    oldMillisVallue: 30359

When I comment out:

    oldMillisVallue=millis();// if i comment this line it works

I get this :

    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    2000,0,0,4294967295,15,43,3,36,5,41,4.066298,48.269157,77,0.12,90,380,98,2,1,3
    2000,0,0,4294967295,15,43,3,39,5,43,4.066298,48.269157,79,0.122200,92,380,98,2,1,3
    ------------------------
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0

    oldMillisVallue: 0
    oldMillisVallue: 0
    2000,0,0,4294967295,15,43,4,39,5,43,4.066265,48.269126,80,0.12,94,380,101,3,2,5
    2000,0,0,4294967295,15,43,4,41,5,45,4.066265,48.269127,82,0.121900,94,380,103,3,2,5
    ------------------------
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0
    oldMillisVallue: 0

body:
You're only reading from the serial port every `GPSSearchPeriod` milliseconds. That gives plenty of time for the small serial read buffer to overflow and lose the data.

Instead you should be reading *all the time* regardless of your desire to only do things periodically. Sure, *report* the data periodically, but you *must* read all the time *as well*.


message:
Lighting up LED lights on Arduino tank using Arduino transmitter

I am making an Arduino tank using the motor shield, more of a recon tank as it has no gun. And I'm using one Arduino board as the receiver and controller of the tank and the other as the transmitter. I'm thinking of adding lights to the build and want to remotely operated them. I don't know where to look at or start. Can someone help me?

body:
Well, Im going to see your question with good eyes and help you out giving you the properly guidance. With no sarcasm.

First of all you just would do some google searchs using the correct words.

To achieve the correct words you need to enumerate important things just doing the following quastions.

What do I have?

    Arduino, Led

What do I want?

    Controlling Led Remotely

So with these couple of question I could achieve the following sentence:

    controlling led arduino remotely

This gave me the following good and usefull link with source code:
http://www.instructables.com/id/Arduino-Control-LEDs-with-a-Remote-Control/

Now you can improve your serach and come back here, bringing us what you have done so far with a far more accurated techinical question like:

    What is the best way to controlling LED remotely in the given situation?

And go on.

The most important thing to know is how to separate requirements from impediments. I think now you are fair well introduced about how to use this very good resource.


message:
Source code for Arduino “firmware”?

I am wondering if anyone here knows where the source code for the Arduino "firmware" is available for reading? I think it must be more than the 'boot loader' but I am not sure. Thanks!

p.s. I assume this kind of question is ok here, even though it's not ok on StackOverflow?

body:
If you are looking for the Flash Firmware, I think the github project documentation is pretty well developed, here:

https://github.com/arduino/Arduino

This is a good introduction to build and flash your Arduino UNO:

http://angryelectron.com/arduino-firmware/

And here a good start to build you own Arduino on a breadboard:

https://www.arduino.cc/en/main/standalone


body:
The “firmware” is whatever program a microcontroller runs. On an
Arduino, it is typically the program **you** write and upload into the
microcontroller's flash memory.

If by “firmware” you mean the core library (the source code of
`pinMode()`, `digitalRead()` and so on), it is here:

https://github.com/arduino/ArduinoCore-avr

If by “firmware” you mean the bootloader (the small program that runs at
reset and will accept the upload of your firmware), is is here:

https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/bootloaders/optiboot

Note that this is valid for the AVR-based Arduinos.
The cores and bootloaders used in other architectures are stored is
separate repositories, e.g.

https://github.com/arduino/ArduinoCore-sam


message:
Understanding the ESP8266

I've received my ESP8266-01 and playing with it I discovered that with a baudrate of 74880 I can get the boot modes and `hy version, etc:
 ets Jan  8 2013,rst cause:1, boot mode:(3,0)

    load 0x40100000, len 1856, room 16
    tail 0
    chksum 0x63
    load 0x3ffe8000, len 776, room 8
    tail 0
    chksum 0x02
    load 0x3ffe8310, len 552, room 8
    tail 0
    chksum 0x79
    csum 0x79

    2nd boot version : 1.5
      SPI Speed      : 40MHz
      SPI Mode       : DIO
      SPI Flash Size & Map: 8Mbit(512KB+512KB)
    jump to run user1 @ 1000

    rf cal sector: 249
    rf[112] : 00
    rf[113] : 00
    rf[114] : 01

    SDK ver: 1.5.4.1(39cb9a32) compiled @ Jul  1 2016 20:04:35
    phy ver: 972, pp ver: 10.1

With this baudrate I'm not able to check the AT commands. Then, when I switch to a baudrate of 115200 I am able to communicate with the ESP:

    Ai-Thinker Technology Co. Ltd.
    ready
    AT
    OK
    AT+CWL
    ERROR
    AT+CWJAP?
    No AP
    OK
    AT+CWLAP?
    ERROR
    AT+CWLAP
    +CWLAP:(4,"bbox2-7f0d",-88,"00:1 ",1,-46,0)
    +CWLAP:(0,"PROXIMUS_FON",-94,"06: ec:6b",1,-47,0)
    +CWLAP:(5,"PROXIMUS_AUTO_FON",-88,"0a: :ec:6b",1,-44,0)
    +CWLAP:(3,"WiFi-2.4-BB3D-ext",-51,"00: 9a:38",1,-12,0)
    +CWLAP:(3,"NGUYEN",-79,"e0:b ",11,-2,0)
    +CWLAP:(0,"PROXIMUS_FON",-81,"42:6 ",11,0,0)
    +CWLAP:(5,"PROXIMUS_AUTO_FON",-79,"42 ",11,0,0)
    +CWLAP:(4,"WiFi-2.4-6858",-75,"4 e",11,1,0)
    +CWLAP:(0,"PROXIMUS_FON",-89," ",11,-6,0)
    OK

How is that possible that it has two different baudrates?

Thanks in advance,

body:
> How is that possible that it has two different baudrates?

Very simple. Exactly the same as the Arduino.

If you put:

    Serial.begin(9600);

in your program then your sketch runs with the serial port at 9600 baud. However, just before then, the bootloader runs at 115200 baud for a few seconds listening for instructions from the PC.

There's no magic there.

You can even do it yourself:

    Serial.begin(9600);
    Serial.println("Hello at 9600 baud");
    Serial.flush();
    Serial.end();
    Serial.begin(115200);
    Serial.println("Hello at 115200 baud");
    Serial.flush();
    Serial.end();

The baud rate isn't fixed. It's whatever the firmware that is running at that precise moment deems it to be - whether that is the bootloader, the AT firmware, or your own custom sketch.


message:
Write data on the computer with Arduino

I wonder if in Arduino you can modify the computer eg create a text file inside the computer using Arduino. Is there any way you can do this or something like that?

Because you can use the library `#include <stdio.h>`, which is a C++ language library to handle file on the computer.

In Arduino maybe you can create files on the computer using pointers or a library? Because using the library `"Keyboard.h`" you can handle the computer. The Keyboard library can interact with the computer by typing on the computer

I'm in doubt, I need your knowledge.

body: The keyboard library just sends key presses to the computer like a keyboard.  From the PCs point of view it's no different from you banging on the keyboard in front of it.  The Arduino can't control anything on the computer and it can't run any code on the computer.  Now if you can do what you want completely from the keyboard then arduino could send those same keypresses.  But the Arduino has no access to the PCs operating system or file system.


body: There are a number of serial-terminal programs that run on your PC (and pretty much any OS) that will copy the data they receive to a file. I use CoolTerm on MacOS. I think Windows HyperTerminal offers that capability as well on Windows. You have to start the terminal program on the PC, set it to capture, and open the capture file yourself - the Arduino can't cause the PC to do that - but once you've done it, the terminal program will copy all output from the Arduino to the capture-file. You might also have to set the PC to not sleep, if you need it to capture data without you being present.


body:
The arduino can't directly modify the contents of the PC hard drive, the ability for a peripheral device to do this would be considered a massive security flaw in the PC operating system.

Having said that there are a few ways to do it:

To save a text file without anything special on the PC:

Have the Arduino act as a keyboard. Send (windows key + R) (pause) notepad < enter > (pause) [ The text you wish to save to the PC ] (alt-f) s < file name > < enter>

This does require the PC to be unlocked (or you send the unlock key sequence first) and setting the directory to save to or overwriting a file could get tricky but should be possible if you work out the correct key sequence. The (windows key + r) combination is very powerful and also very dangerous. It makes it trivial to wipe the entire computer so use it with care.

To save a binary file to the PC:

Set up the arduino to act as a serial port. Start the terminal program of your choice and set it to log to a file. Send the data from the arduino. On the PC wait until the transfer is complete and then save the log file.

To read/save/modify any file without user interaction:

Set up the arduino to act as a serial port. Write a desktop PC application that takes the data from the Arduino. Define a protocol that allows the arduino to to specify the filename and what to do with it. The arduino doesn't directly access any files, instead it sends the commands to an application running on the PC, that application then performs the required file operations.

Alternative way to read/save/modify any file without user interaction:

Connect the arduino to the PC using USB. Exploit a flaw in the PC operating system to install a virus on the PC that gives you full control over the computer.


message:
Button not working - Arduino Due project (MiniEngine v2)

I am building Arduino Due based project called MiniEngine v2 (an open-source motion control software for timelapse photography).

The project is not very active anymore but there are still all the documentation at github. Project owner had webshop where he sold MiniEngine shields for arduino but they are not available anymore. There was gerber files available at project github page so I orderer PCB's form seeed.com.

Project's Github page is at:
[https://github.com/airiclenz/miniEngine2][1]

Everything seems to work ok but one of the buttons is not working. There is only 2 buttons and one rotary encoder.

I think the reason why the button is not working is that the output voltage for button from 74HC14N (hex smith trigger) is too low (I am not very good at electronic so I might be totally wrong.

I tried to measure values with voltage meter and here is the result what I got for those two buttons:

Here are the values in written format ( I took measurement from SN74HC14N )

 - btn_2 (pin9 input, pin8 output)
 - btn_1 (pin11 input, pin10 output)

**SETTINGS BUTTON** (btn_2) -> **this one works** fine

 - 1) button up  - metering from input pin 11 => 3.26
 - 2) button down -metering from input pin 11 => 0
 - 3) button up - metering from output pin 10 => 0.6
 - 4) button down - metering from output pin 10 => 2.38

**START/BACK BUTTON** (btn_1) -> **this one does not work**

 - 1) button up  - metering from input pin 9 => 3.26
 - 2) button down - metering from input pin 9 => 0
 - 3) button up - metering from output pin 8 => 1.43
 - 4) button down - metering from output pin 8 => 1.53

Here is how the buttons are initialized:

        void input_init() {

      // set pin modes
      pinMode(PIN_ROTARY_PRESS, INPUT);
      pinMode(PIN_KEY_1, INPUT);
      pinMode(PIN_KEY_2, INPUT);

      // attach interrupts for the keys
      attachInterrupt(PIN_ROTARY_PRESS, input_interrupt_keyRotary_press,  RISING);
      attachInterrupt(PIN_KEY_1,        input_interrupt_key1,             RISING);
      attachInterrupt(PIN_KEY_2,        input_interrupt_key2_press,       RISING);

      // attach interrupts to both encoder pins for every state change
      attachInterrupt(PIN_ROTARY_A,     input_interrupt_rotary,           CHANGE);
      attachInterrupt(PIN_ROTARY_B,     input_interrupt_rotary,           CHANGE);

      // set the initial rotary values & configurations
      rotary.setPosition(0);
      rotary.setKeyMode(true);
      rotary_old_pos = 0;
    }

And here is function for btn_1 press that is never called (except once in powering the shield/arduino due)

    void input_interrupt_key1() {

      if ((key_1_time + DEF_INPUT_DEBOUNCE) < millis()) {

        key_1_time = millis();
        setBit(input_status, BIT_2);

      }
    }

I can only use 2 links in posts (I do not have 10 reputation) so you can find the code for inputs at Github (link above). (folder ***MiniEngine2/Software/miniEngine2/mE2_input.ino***)

All code files are at Sotfware at folder: ***MiniEngine2/Software/miniEngine2***

I have put Serial.println command in code and nothing is printed when btn_1 is pressed. When I plug power on then the btn_1 is triggered once...

Here is link to the the schematic for that shield ( it is quite big so that's why I did not embed the photo):

Schematic for shield is at Github folder : ***Hardware/miniE shield v2 revB BED board - schematic.pdf***

Here is also link to the video where you can see how I took the measurements:
[https://youtu.be/wFR7P65qMGA][2]

Please ask if I need to provide more information...

  [1]: https://github.com/airiclenz/miniEngine2
  [2]: https://youtu.be/wFR7P65qMGA

body: It was the Arduino Due issue. Arduino digital pin 43 was faulty or something. I managed to change 43 to 53 and now the button works...


message:
ATTiny85 and DHT11 - Sensor always returning 0

Good day.

I am making a small weather station using ATTiny85, DHT11, and an OLED display.

There are many, many tutorials that explain how this works, and various libraries that show you how to get the DHT11 to work with the ATTiny85 and others that are dedicated to the SSD1306 Oled displays, some even show you how to combine them together. Well, for the better part of 2 days nothing worked for me.

My schematics is as follows:
[![enter image description here][1]][1]

And here is a picture of the actual thing, working with a CR2032 Coin Cell:

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

The Libraries I am using are:

 - OLED Libraries for ATTiny85 - Source: http://www.14core.com/wiring-digispark-attiny85-with-096-oled-screen-display/
 - Rob Tillaart DHT Library - Source: https://github.com/RobTillaart/Arduino/tree/master/libraries

My Code is as follows:

        //OLED Libraries for ATTiny85 - Source: http://www.14core.com/wiring-digispark-attiny85-with-096-oled-screen-display/

    #include <font6x8.h>
    #include <font8x16.h>
    #include <num2str.h>
    #include <ssd1306xled.h>
    #include <ssd1306xled8x16.h>
    #include <SSD1306_minimal.h>
    #include <TinyWireM.h>
    #include <USI_TWI_Master.h>

    #define DEG "\xa7" "C"

    SSD1306_Mini oled;

    char strHum[4];
    char strTemp[4];

    #include <dht.h>
    dht DHT;
    #define DHT11_PIN 1

    void setup()
    {

      TinyWireM.begin(); // initialize I2C lib - comment this out to use with standard arduinos
      oled.init(0x3c);
      oled.clear();

    }

    void loop()
    {

      //            DHT Code goes here                              //

      DHT.read11(DHT11_PIN); //Calling the read function

      float hu  = (DHT.humidity, 1);
      float te  = (DHT.temperature, 1);

      //            OLED Start -- DO NOT CHANGE ANYTHING            //

      //oled.clear();

      oled.startScreen();
      oled.cursorTo(10, 0);
      oled.printString("ATTiny85 & DHT11");

      oled.startScreen();
      oled.cursorTo(12, 9);
      oled.printString("Temp & Humidity");

      oled.startScreen();
      oled.cursorTo(10, 18);
      oled.printString("www.MDChaara.com");

      oled.startScreen();
      oled.cursorTo(0, 27);
      oled.printString("mdchaara@gmail.com");

      oled.startScreen();
      oled.cursorTo(0, 45);
      oled.printString("Humidity(%): ");

      oled.startScreen();
      oled.cursorTo(110, 45);
      oled.printString( itoa(int(hu), strHum, 10));

      oled.startScreen();
      oled.cursorTo(0, 55);
      oled.printString("Temperature(c): ");

      oled.startScreen();
      oled.cursorTo(110, 55);
      oled.printString( itoa(int(te), strTemp, 10));

      //            OLED End          //

      delay(5000);
    }

Now I know that the OLED code works, and it was a very interesting round or research to get it to work. The DHT code is another story. I have tried 6 different libraries and none of them worked. They all either return 0, 1, or blank readings on the screen.

I have checked if the sensor is working with an Uno and a Nano, works well! I checked the connections, and the soldered parts and did continuity tests, but the issue still remains.

I am asking because I am hoping a fresh set of eyes can pin-point the issue that I am facing. Any help will be highly appreciated.

- Arduino IDE: 1.8.2
- OS: Windows 7 64 bits
- Micro controller: ATTiny85-20PU

Sketch is uploaded to the micro controller using Arduino Uno as a programmer.
Sketch is uploaded at Internal 8MHz clock setting.

Thank You.

  [1]: https://i.stack.imgur.com/d3uYW.jpg
  [2]: https://i.stack.imgur.com/Xd8li.jpg

body:
[![my tryout build, the uno you see is just the "programmer" script runs on the Attiny85][1]][1]

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

Ok i tried something like that for myself and thanks to this and ..many other posts and forums/videos i could make myself something that works but with a little other setting like in the start post (other libs ect)

in my case the main reason for the "1" output on the oled was this:

      float hu  = (DHT.humidity, 1);    //original

      hu  = (DHT.humidity);       //what worked for me

Maybe you can figure out more Problems, my code is shure not perfekt! But maybe it helps someone for a vew steps

    #include <dht.h>
    #include <U8x8lib.h>
    #define DHT11_PIN 1
    dht DHT;
    int temp = 0;
    int humi = 0;
    char strTemp[4];
    char strHumi[4];

    U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ 2, /* data=*/ 0, /* reset=*/ U8X8_PIN_NONE);         // Digispark ATTiny85 Pin 0 Data, Pin 2 clock

    void setup(void)
    {

      u8x8.begin();
      u8x8.setPowerSave(0); //enegergiesparen 0 aus

    }

    void loop(void)
    {

      int chk = DHT.read11(DHT11_PIN);

      temp = (DHT.temperature);
      humi = (DHT.humidity);

      u8x8.setFont(u8x8_font_chroma48medium8_r);
      u8x8.drawString(0,0,"~~~~~~~~~~~~~~~~");
      u8x8.drawString(0,1,"Temperatur");
      u8x8.drawString(1,2,( itoa(int(temp), strTemp, 10)));
      u8x8.drawString(4,2,"Grad Celsius");
      u8x8.drawString(1,3,"--------------");
      u8x8.drawString(0,4,"Luftfeuchtigkeit");
      u8x8.drawString(1,5,( itoa(int(humi), strHumi, 10)));
      u8x8.drawString(4,5,"Prozent");
      u8x8.drawString(0,6,"~~~~~~~~~~~~~~~~");
      delay(200);
    }


body:
The DHT11 is notoriously slow to respond and often returns null for readings sporadically.
I notice in your second circuit you have resistors by the sensor but I cant see what pins they are connected to.
You will need pullup for the sensor data line 4K7 usually does the trick.


body:
The DHT works, by specification, with a 3.5V minimally. I think you can expect anything if you don't provide the appropriate voltage, which seems to be only 3V from the picture you show.

source:
https://components101.com/dht11-temperature-sensor


message:
A1 was not declared in the scope

I'm trying to put all my settings in a config.h file and then `#include` it in the Arduino sketch.

Here's what my config.h looks like:

**RobotConfig.h**

    #ifdef BOT
        //hardware pins
        int motor1Pin = 9; //s0
        int motor2Pin = 10; //s1

        //pins for light
        int light2 = A4;
        int light3 = A2; //right
        int light1 = A1; //left

And here's what .ino sketch looks like:

    #define BOT
    #include "RobotConfig.h"

    void setup() {
      //Light INIT
      pinMode(light1, OUTPUT); //left light with motor1/s1 in front
      pinMode(light2, OUTPUT); //middle light with motor1/s1 in front
      pinMode(light3, OUTPUT); //right light with motor1/s1 in front
      ...
    }

This compiles fine on my Mac but I'm trying to compile this on Raspberry Pi (Pi3 with new Jessie install with `sudo apt-get install arduino`) and get an error while doing so. The error says:

> A1 was not declared in the scope etc.

What am I missing?

body: RobotConfig.h needs to include Arduino.h in order to have those constants.


message:
Humidity sensor for wet environment

I've had a bit of experience with DHT11/DHT22 sensors in a greenhouse environment, and believe that when they get wet they stop working altogether.

Are there any low cost humidity sensors that I can hook up to an Arduino that don't suffer from this problem, or is there a way to protect these sensors from damage when near water? (I'm not talking about immersing them in water - but do expect condensation to get sprayed with water and/or get condensation on them from time-to-time).

Am I correct that the SHTxx sensors are able to withstand this kind of abuse, and that these sensors are about 5-10 times the cost of DHT sensors?  (I did not want to spend that much, but if it's the only possibility I might consider it).

body:
**2022 UPDATE**: After ~5 years since I wrote this answer, I'd like to mention that I don't like BME280 anymore, because of its (1) inaccuracy and (2) requirement to make some non-trivial computations to get real values from sensor's data. If you already got a BME280 and your project requires only approximate values of temperature/humidity, it will work, go ahead. Otherwise, consider using **SHT3x**!

See also [this][1], [this][2], and especially [this one][3].

Original answer:

------------------
I'd consider using **Bosch BME280** digital sensor. Although it's a bit expensive, it has very good sensitivity, precision and *amazingly* fast response for humidity changes (for ex. in my project it detects dry human hand lying in 2" away within a 1-2 seconds).

So its features make possible to put it into an enclosure to avoid direct water contact with water spays and it'll still be very responsive for greenhouse needs, I suppose.
Datasheet warns:

> Liquids shall not come into direct contact with the device.

Also, I'd use electronic-friendly protective acrylic lacquer (Plasticote 70 for instance) and put two layers to sensor's PCB, avoiding small black tiny vent hole on the chip itself:
[![BME280][4]][4]

**UPD**: Here's DHT11 with cover removed:
[![DHT11 inside][5]][5]

It *might be* the easiest and cheapest solution to cover all internal contacts and IC (avoiding humidity sensor's stripes) of DHT11 with Plasticote 70.

  [1]: https://forum.arduino.cc/t/compare-different-i2c-temperature-and-humidity-sensors-sht2x-sht3x-sht85/599609
  [2]: https://www.kandrsmith.org/RJS/Misc/hygrometers.html
  [3]: https://wiki.liutyi.info/display/ARDUINO/Test+i2c+humidity+sensors
  [4]: https://i.stack.imgur.com/zvnot.jpg
  [5]: https://i.stack.imgur.com/D3Zro.jpg


message:
Arduino Esplora

So I'm trying to turn my Arduino Esplora into a controller, and my first step is to understand how the controller works. I've copied and pasted this code into the Arduino 1.8.2 IDE.

    Esplora.writeRGB(255, 255, 255); // sets red, green and blue all to full brightness

But I get an error saying,

   exit status 1
'Esplora' does not name a type

Please explain why it's doing this.

body:
You probably forgot:

 - To include Esplora.h in your sketch.
 - To select "Esplora" for the board.


message:
Control a 5 volt water pump with an Arduino

I want to control (only on/off) a small water pump (5 V, 200 mA max.) with my Arduino.

I read something about NPN transistor, because the output pins of the Arduino can't supply enough current to the pump. However, I don't know how to choose the right transistor and how to connect it with my Arduino and my water pump.

body:
To use an NPN, connect a power rail of 5V to the pump's positive terminal, and from its negative terminal wire it to the transistor's collector pin. Wire emitter to GND, and place a >=220 ohms resistor between your arduino control pin and the transistor _base_.

If instead using an N-channel MOSFET, wire load to drain, source to GND, and use a 4K7 pull-down on gate.

Also add a diode, with its anode at the pump's negative terminal, and cathode (white ring) at the positive terminal.


message:
Arduino Uno alarm interrupt

I am trying to create a temperature-humidity monitor using Arduino and I want to power it using a battery. So, power efficiency is of interest. I am trying to put the Arduino to sleep for x-time (10sec for testing now). I am using a DS3231 alarm as an interrupt on pin 2 to wake-up. I am using the [tutorial here][1] along with its associated [RTClibExtended][2] library. Here is the code I am using:

    #include "DHT.h"
    #include <RTClibExtended.h>
    #include <Wire.h>
    #include <LowPower.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>      // library for interrupts handling
    #include <avr/sleep.h>          // library for sleep
    #include <avr/power.h>          // library for power control

    #define DHTPIN 7     // what pin we're connected to
    #define DHTTYPE DHT22   // DHT 22  (AM2302)
    #define wakePin 2    //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW

    RTC_DS3231 rtc;
    char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    int interval_sec=10; //An alarm every 10 sec
    DHT dht(DHTPIN, DHTTYPE);

    void setup () {

      Serial.begin(9600);

      delay(3000); // wait for console opening

      /**RTC**/
      if (! rtc.begin()) {
        Serial.println("Couldn't find RTC");
        while (1);
      }
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

      /**INTERRUPT**/
      //Set pin D2 as INPUT for accepting the interrupt signal from DS3231
      pinMode(wakePin, INPUT);
      Wire.begin();
      //clear any pending alarms
      rtc.armAlarm(1, false);
      rtc.clearAlarm(1);
      rtc.alarmInterrupt(1, false);
      rtc.armAlarm(2, false);
      rtc.clearAlarm(2);
      rtc.alarmInterrupt(2, false);

      //Set SQW pin to OFF (in my case it was set by default to 1Hz)
      //The output of the DS3231 INT pin is connected to this pin
      //It must be connected to arduino D2 pin for wake-up
      rtc.writeSqwPinMode(DS3231_OFF);

      Serial.println("Initialisation complete.");
      delay(100); //Allow for serial print to complete.
    }

    void loop () {
        DateTime now = rtc.now();

        Serial.print(now.year(), DEC);
        Serial.print('/');
        Serial.print(now.month(), DEC);
        Serial.print('/');
        Serial.print(now.day(), DEC);
        Serial.print(" (");
        Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
        Serial.print(") ");
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);
        Serial.print(':');
        Serial.print(now.second(), DEC);
        Serial.println();

        /**Temperature and Humidity**/
        // Reading temperature or humidity takes about 250 milliseconds!
        // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
        float h = dht.readHumidity();
        // Read temperature as Celsius
        float t = dht.readTemperature();
        // Read temperature as Fahrenheit
        //float f = dht.readTemperature(true);

        // Check if any reads failed and exit early (to try again).
        //if (isnan(h) || isnan(t) || isnan(f)) {
        if (isnan(h) || isnan(t)) {
          Serial.println("Failed to read from DHT sensor!");
          return;
        }

        Serial.print("Humidity: ");
        Serial.print(h);
        Serial.print(" %\t");
        Serial.print("Temperature: ");
        Serial.print(t);
        Serial.println(" *C\t");

        delay(3000); // wait for console

        /**INTURRUPT**/
        DateTime nextAlarm = now + TimeSpan(0, 0, 0, 10);
        Serial.print("Alarm at:");
        Serial.println(nextAlarm.hour());
        Serial.println(nextAlarm.minute());
        Serial.println(nextAlarm.second());
        rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.minute(), nextAlarm.hour(), nextAlarm.second());   //set your wake-up time here
        rtc.alarmInterrupt(1, true);
        delay(3000); // wait for console
        attachInterrupt(0, wakeUp, LOW);       //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
        LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);   //arduino enters sleep mode here
        detachInterrupt(0);                                    //execution resumes from here after wake-up
        //When exiting the sleep mode we clear the alarm
        rtc.armAlarm(1, false);
        rtc.clearAlarm(1);
        rtc.alarmInterrupt(1, false);

        Serial.println();
        delay(3000);
    }

    void wakeUp()        // here the interrupt is handled after wakeup
    {
    }

The Arduino is going to sleep as expected, but not waking up. Where am I going wrong?

Here is the output:

> Initialisation complete. 2017/6/7 (Wednesday) 12:42:49 Humidity: 36.90
> % Temperature: 25.60 *C
> Alarm at:12
> 42
> 59

  [1]: http://www.instructables.com/id/Arduino-Sleep-and-Wakeup-Test-With-DS3231-RTC/
  [2]: https://github.com/FabioCuomo/FabioCuomo-DS3231/blob/master/examples/wakeup_alarm/wakeup_alarm.ino

body:
After trying for a few hours, I was able to figure it out.

The change required is:

    rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.second(), nextAlarm.minute(), nextAlarm.hour (), 1);   //set wake-up time here

So, in the original code, the order of arguments as well as the number of arguments passed to *rtc.setAlarm()* was wrong. Even though we are not interested in the "day" part (last argument) for setting the alarm, it requires a value. Using *ALM1_MATCH_HOURS* ensures that we match the alarm time to seconds, minutes, and hours ignoring the day part.

**Improvement**

Instead of hardcoding the alarm interval, the global variable called *interval_sec* can be set at the top and used to set the alarm time:

    DateTime nextAlarm = now + TimeSpan(0, 0, 0, interval_sec);


body:
In RTClibExtended.h it is important to always include all arguments: seconds, minutes, hours, daydate. If 0 value is used then this means "always" for that argument.

**Example:**

    RTC.setAlarm(ALM1_MATCH_SECONDS, 30, 00, 0, 0); // activate every minute at 30 seconds
    RTC.setAlarm(ALM2_MATCH_MINUTES, 0, 01, 0, 0); // activate every hour at 01 minutes
    RTC.setAlarm(ALM1_MATCH_HOURS, 33, 18, 0); // activate every day at 18:33

(note: this example is copied from RTClibExtended.h examples, author does not adhere to his own rule to include seconds, even in ALM2. But it works).
Any suggestions or corrections are welcomed!


message:
ESP8266 proper power circuit for avoid reset issue

I am using an ESP8266 in a project which will be on for at least 18 hours a day. I'm using an Arduino 3.3V power supply to feed the ESP8266.

The issue I'm facing is a reset issue. It sometimes disconnects from the hotspot automatically.  I have heard this could be because the ESP8266 draws more power than the Arduino's regulator is able to supply.

I want to know what will be the proper circuit to power the ESP8266.

I know I have to use an AMS1117 regulator, but I also know I have to use capacitors too. How would I configure the AMS1117 with capacitors to properly power an ESP8266?

body:
You don't "need" an AMS1117 regulator. You *need a power source that can supply enough current.*  One *example* is an AMS1117-33, although it's not a great one as far as efficiency goes (though it is simple).

The basic circuit is to have a 10µF capacitor on both the input and output of the regulator - that should be enough for most uses.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

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

<!-- End schematic -->

Powered from more than around 5V the AMS1117-33 would need some heatsinking.  You can also add some smaller (100nF) capacitors in parallel with the 10µF ones if you want to improve high frequency response.

[You can pick modules up with this circuit on from eBay for a dollar.](http://www.ebay.co.uk/sch/i.html?_nkw=3.3v+dc-dc+1117)

A better power source would be a "buck" switching regulator. These are far more efficient and generate much less heat.  It's harder to search for these on eBay since all the AMS1117-33 modules seem to be labelled erroneously as "buck" regulators (which they so are not!), so be careful when looking around. A true "buck" regulator will have an inductor on it. [Here's one example](http://www.ebay.com/itm/152551807267).


message:
ESP8266, prints ready at start but no response to AT command

I have been using **ESP8266** wifi module with **Arduino as FTDI**. The power for ESP8266 comes from **LM317** 5V - 3.3v regulated supply(I am sure 5V is powerful enough to give upto 1A of current).

The RX of ESP8266 is connected to RX of Arduino via a **voltage divider** to ensure 3.3V logic level. But still, I am not getting any response to **`AT`** command, though my laptop and phone wifi have successfully connected to *AI-Thinker...* SSID(which is an open hotspot from ESP8266).

I am also having some **garbage values** on the serial port immediately after I turn on the power supply to ESP8266. I have tested all baud rates available in Arduino IDE v1.0.5 with no results.

The resistor values for lm317 are R1 = 125 Ohm, R2 = 225 Ohm with which I am getting around 3.2 Volts.

The connections are as follows:-
___
-----Arduino UNO-----

RESET ------------ GND
___
Arduino UNO ----- ESP8266

TX ------------------- TX

RX ---5V to 3.3v--- RX

GND ----------------- GND
___
ESP8266 --------- LM317(5V to 3.3V)

VCC --------------- 3.3V

GND --------------- GND

CH_PD ------------ 3.3V

___

---------

**EDIT - 1**: I have bought a **new _ESP8266_**, and even it doesn't responds to any `AT` commands, thought there is some difference in the previous ESP8266 output and this new ESP8266 output.

The difference is a sort of **good** news to me, it **sends `ready`** after sending some garbage at `115200` baud on boot which never happened with previous one(ESP8266).

Is anyone having some clue why there is no response to `AT` commands?
May it be a issue with **TX** line?

--------
**EDIT - 2**: I have also used **another Arduino** with same connections doubting the **TX** pin on Arduino, but with same luck, bad luck. Still, nothing got changed.

--------
**EDIT - 3**: I am shifting 5v to 3.3v by using three 100 ohm resistors.

body:
Connect TX of arduino to esp8266 RX, and arduino RX to esp8266 TX.

See [this][1] link for more info.

  [1]: https://blogs.msdn.microsoft.com/abhinaba/2016/01/23/esp8266-wifi-with-arduino-uno-and-nano/


body:
First of all your connectons are wrong:
-----Arduino UNO-----

RESET ------------ GND (Why)

Arduino UNO ----- ESP8266

TX ------------------- RX

RX ------------------- TX

(RX is the recieving end, TX is the transmitting end, one should allways connect a transmitter to a reciever both directions, never a transmitter to transmitter or reciever to reciever, and use a logic level shifter)

GND ----------------- GND

ESP8266 --------- LM317(5V to 3.3V) (only for Vcc)

VCC --------------- 3.3V

GND --------------- GND

CH_PD ------------ 3.3V

In these cases you should use a logic level shifter like [74LVC245][1] or [sparkfun level converter][2] and not a voltage regulator. If you must use lm317 connect it correctly, diodes, capacitors and an adjusting potmeter or resistor. Typical application found in the [datasheet][3] on p. 10

baudrate should be 57600 on the esp8266.

glhf :)

  [1]: https://cdn-shop.adafruit.com/datasheets/sn74lvc245a.pdf
  [2]: https://www.sparkfun.com/products/12009
  [3]: http://www.ti.com/lit/ds/symlink/lm317.pdf


body:
The problem was with my **logic level shifting**.

Any Arduino pin can provide only upto *40mA* of current. What current you are trying to draw is:-

> 5 Volts / 100 Ohm = *50mA*

which is clearly more current than what an UNO can provide. Your ESP also adds up its own resistance meaning even more current draw requirement from RX pin.

Instead of using three 100 ohm resistors, use some **high valued resistors** such as 1K ohm resistors(or even higher value) in the **voltage divider circuit** so that no much current pass through it, consuming less power **affordable** by the Arduino RX pin.

Remark: If you don't know how logic level shifting works with voltage divider circuit, click [here][1].

  [1]: https://en.wikipedia.org/wiki/Voltage_divider


body:
Which version of arduino IDE are you using? I use 1.6.12 and works, it does not work for 1.8 versions.
Also ensure 3.3v power input for the esp8266 separately from arduino power. I suggest using a PC power supply (color orange is 3.3v).


body:
The issue you are running into is that the Arduino Uno cannot source enough current at 3.3V for esp8266 operation. I had to use a separate power supply with grounds tied together and then my esp8266 responded to AT commands.

Summary:

 - I use the Arduino Uno as the serial bridge (RESET tied to GND)

 - an external power supply for the esp8266

 - and a bidirectional level shifter for 3.3V to 5V TX/RX data paths
 - Connected CHPD of esp8266 to GND, waited 5 sec then reconnected to 3.4V
 - Arduino IDE > Tools> Serial Monitor > Both NL&CR > 115200 Baud Rate

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

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


message:
Optimizing Arduino File Selection from SD card

the following code will display the files on an SD card in an Arduino and allow the user to open a file of their choosing. Here's the code with a walkthrough of what it does.

In the Init state, I call the libraries needed to run the code

    // Example use of lfnOpenNext and open by index.
    #include<SPI.h>
    #include "SdFat.h"
    #include "FreeStack.h"

    // SD card chip select pin.
    const uint8_t SD_CS_PIN = 10;

    SdFat sd;
    SdFile dirFile;
    SdFile file;

    // Number of files found.
    uint16_t numberOfFiles = 0;

**This is the area of the real problem, calling**  `SdFile parIndex[50];` **Takes a large amount of dynamic memory. For number of files on an SD card, this is a pretty small number, so I need to get at something better**

    // Position of file's directory entry.
    uint16_t dirIndex[50];
    SdFile parIndex[50];
    //------------------------------------------------------------------------------

In the Setup phase, we make sure the SD card is plugged in and, if it is, we call the function to give the files on the SD card.

    void setup()
    {
      Serial.begin(38400);
      while (!Serial) {}

      // Initialize at the highest speed supported by the board that is
      // not over 50 MHz. Try a lower speed if SPI errors occur.
      if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50)))
      {
        sd.initErrorHalt();
      }
      if (dirFile.open("/", O_READ))
      {
      printDirectory(dirFile, 0);
      }
    }

The printDirectory function (This is the part most open to edits, if there's any way to improve performance here, please let me know as well).

    void printDirectory (SdFile CFile, int numTabs)
    {
      SdFile file;
      while (file.openNext(&CFile, O_READ))
      {
      if (file.isHidden()||false)
        {
          //file hidden, skip
        }
        else
        {
          for (uint8_t i = 0; i < numTabs; i++)
          {
            //create tabs for spacing
            Serial.print('\t');
          }
          if (file.isSubDir())
          {
            SdFile SubDirFile;
            printDirectory(SubDirFile, numTabs+1);
          }
          else
          {
            // Save dirIndex of file in directory.
            dirIndex[numberOfFiles] = file.dirIndex();
            parIndex[numberOfFiles] = CFile;
            // Print the file number and name.
            Serial.print(numberOfFiles);
            Serial.write(' ');
            file.printName(&Serial);
            Serial.println();
            numberOfFiles++;
          }
        }
      file.close();
      }
    }

----------
This is the user interface portion, it was largely slapped together as a proof of concept for the above code. As it's written, the code only accepts index values 0-9, but my actual program could call any index value.

    void loop() {
      int c;

      // Read any existing Serial data.
      do {
        delay(10);
      } while (Serial.available() && Serial.read() >= 0);
      Serial.print(F("\r\nEnter File Number: "));

      while (!Serial.available()) {
        SysCall::yield();
      }
      c = Serial.read();
      uint8_t i = c - '0';
      if (!isdigit(c) || i >= numberOfFiles) {
        Serial.println(F("Invald number"));
        return;
      }

After making sure that the input value exists, it calls up the arrays that contain the parent's directory SdFile object and the index of the desired file.

      Serial.println(i);
      if (!file.open(&parIndex[i], dirIndex[i], O_READ)) {
        sd.errorHalt(F("open"));
      }
      Serial.println();

      char last = 0;

      // Copy up to 500 characters to Serial.
      for (int k = 0; k < 500 && (c = file.read()) > 0; k++)  {
        Serial.write(last = (char)c);
      }
      // Add new line if missing from last line.
      if (last != '\n') {
        Serial.println();
      }
      file.close();
      Serial.flush();
      delay(100);
    }

The main issue I have is that `SdFile parIndex[50];` uses 22% of my dynamic memory vs the rest of the program using 12%. How can I rewrite my code to not require keeping the SDFile objects in dynamic memory?

For anyone unfamiliar, [documentation for the SdFat library][1] can be downloaded from that link.

----------
Edit:
In terms of use: The SD files are .csv files that store speed and time parameters for running a motor test. Each test lasts for a few minutes to hours.

  [1]: https://github.com/greiman/SdFat

body:
You have several possibilities:

- Do not store the names of all files, but use the index and iterate through all files again. Disadvantage: this takes a lot of time (every time you need the file name)
- Add SRAM to the Arduino (e.g. 23LC1024, 23K256), depending on your memory needs. Disadvantage: you have to 'manage' this memory yourself.
- If you know something about the file names, you might generate the name. Probably it's not the case, but just to add another option. E.g. if you know that file nr 10 will always be called 'File10.txt', you can 'generate' the name.
- I don't know exactly how you want to use the file names, but you might store only the latest x files used, to prevent having to iterate again reading the SD card. Of course, this only helps if there is a high chance the last x files are used more than the non recent files.

Update:
If you need to read the files while leaving the Arduino unblocked, you have to incorporate it in your loop, but don't read all the files in a loop. Something in pseudo code like:

bool readingSd = false; // True between reading first and last file
uint16_t lastTimeRead = 0; // Last time read

    void loop()
    {
       // Check if file read needed (initial or one hour past, I don't take
       // overflow into account
       if (lastTimeRead == 0 || (lastTimeRead + 1000 * 60 < millis())
       {
          checkReadFile();
       }

       // Perform your normal code... this will run between processing/reading
       // one file/dir.
       ...
    }

    void ProcessSingleFile()
    {
       readingSd = true; // Within reading first/last file
       "read/process ONE file or dir (without containing files)";
       if ("last file read")
       {
           readingSd = false;
           lastTimeRead = millis(); // Move to top to prevent reading time
             // between first/last to take into account
       }
    }


message:
How to change a code for an I2C 16x2 to a 20x4?

I have found a sketch that someone wrote for a rotary encoder controlled LCD menu.

The code is for an I2C that is 16x2 and I have an I2C that is 20x4. With the code that I found, the layers are all 3 lines, so when they appear on the LCD, it is on 2 "pages".  Since my LCD is 20x4, I don't need to scroll to a second page.

How do I get that third line on the same page as the first two?  I am also still looking at other sketches people have posted for LCD menus, but most of them seem to have outdated libraries or are for 16x2 screens.

    #include <OneButton.h>
    #include <Encoder.h>
    #include <Wire.h>
    #include <LCD.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C  lcd(0x27, 2,1,0,4,5,6,7);

    // ROTARY ENCODER
    long oldPosition  = 0;
    int encoderDTpin = 34;
    int encoderCLKpin = 30;
    Encoder myEnc(encoderDTpin, encoderCLKpin);

    int buttonPin = 26;
    OneButton button0(buttonPin, true);

    // MENU ARRAY
    // First number in array = amount of menu items in root layer. Same goes for next layer.
    //(Example: first value in array is 4. This means Layer 0 has 4 menu items. Layer 1 has only 2 menu items.)
    // First number infront of menu text is the layer number that item points to. (Example: 1_Rotation points to Layer 1)
    // Second number infront of menu text is the number of the value connected to that menu item in the values array.
    //(Example: 15Direction points to position 5 in the values array)

    String menu[] = {"4","1__Rotation","056Active","3__Watches","4__Item4",       // Layer 0
                     "3","100Rotations","105Direction","109Speed",                // Layer 1
                     "3","256Active","2__Item2.2","2__Item2.3",                    // Layer 2
                     "4","4__Watch 1","3__Watch 2","3__Watch 3","3__Watch 4",     // Layer 3
                     "2","4__Item3.1.1","4__Item3.1.2"};                          // Layer 4

    // VALUES ARRAY
    // TYPES, 1 numeric / 2 character value range
    // 1 - type,value,increments,min,max
    // 2 - type,starting value in options array,lowest value options array,max value options array
    int values[] = {1,11,25,50,1450, //0-4 WATCH1
                    2,2,0,2,         //5-8
                    1,600,25,75,600, //9-13

                    1,11,25,50,1450, //14-18 WATCH2
                    2,2,0,2,         //19-22
                    1,600,25,75,600, //23-27

                    1,11,25,50,1450, //28-32 WATCH3
                    2,2,0,2,         //33-36
                    1,600,25,75,600, //37-41

                    1,11,25,50,1450, //42-46 WATCH4
                    2,2,0,2,         //47-50
                    1,600,25,75,600, //51-55

                    2,4,3,4,         //56-59 WATCH1 ACTIVE
                    2,4,3,4,         //60-63 WATCH2 ACTIVE
                    2,4,3,4,         //64-67 WATCH3 ACTIVE
                    2,4,3,4};        //68-71 WATCH4 ACTIVE

    String options[] = {"CW","CCW","MIX",
                        "No","Yes"};

    // Custom character for LCD.
    byte cursor[8] = {
      0b10000,
      0b10000,
      0b01000,
      0b00110,
      0b01000,
      0b10000,
      0b10000,
      0b00000
    };

    byte watch[8] = {
      0b01110,
      0b01110,
      0b11011,
      0b10001,
      0b10001,
      0b11011,
      0b01110,
      0b01110
    };

    int currentType = 0;
    int value = 0;
    int numIncr = 0;
    int Min = 0;
    int Max = 0;

    int currentLayer = 0;
    int lastLayer = 99;
    int currentLength = menu[0].toInt();
    int currentPosition = 0;
    int currentSelect = 1;
    int currentChange = 0;
    String currentPress = "";
    float currentlcdLayerFloat = 0;
    int currentlcdLayer = 0;
    int lastlcdLayer = 0;
    int lcdUpdated = 0;
    int currentLine = 0;
    int cursorLayer = 0;
    int cursorPosition = 0;
    int valueLength = 0;

    /*
    int homeScreen = 1;

    String currentTime = "00:00:00";
    String lastTime = "00:00:00";
    String temptime = "00";
    String currentDate = "";

    int watch1active = values[56] - 3;
    int watch2active = values[60] - 3;
    int watch3active = values[64] - 3;
    int watch4active = values[68] - 3;
    int watch1rotations = 0;
    int watch2rotations = 0;
    int watch3rotations = 0;
    int watch4rotations = 0;
    int watch1left = values[1];
    int watch2left = values[15];
    int watch3left = values[29];
    int watch4left = values[43];
    String temprotationsleft = "";
    */

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

      // Map rotary button to actions single and doubleclick.
      button0.attachClick(singleClick);
      button0.attachDoubleClick(doubleClick);

      lcd.begin (16,2);
      lcd.setBacklightPin(3,POSITIVE);
      lcd.setBacklight(HIGH);
      lcd.home();

      // Create the custom character.
      lcd.createChar(0, cursor);
      lcd.createChar(1, watch);

      lcd.setCursor (2,0);
      lcd.print("Watch Winder");
      delay(1000);
      clearLine(0);

      // Set the select cursor on the first line.
      cursorLayer = 0;
      lcd.setCursor (0,cursorLayer);
      writeCursor();

    }

    void loop() {

        // Listen to button presses.
        button0.tick();

        // Listen if the rotary encoder moves.
        rotary_check();

        // Print the LCD menu.
        lcdMenu();

    }

    void singleClick() {

      // IF current layer number is the same as redirect layer number, we stay on the same layer
      // AND no item is selected in the menu
      // AND the selected item has a redirect to another layer
      if(currentLayer == menu[currentPosition + currentSelect].substring(0,1).toInt()
          && menu[currentPosition + currentSelect].substring(1,3) != "__" && currentPress == ""){

        currentPress = menu[currentPosition + currentSelect].substring(3);
        currentChange = menu[currentPosition + currentSelect].substring(1,3).toInt();

        Serial.println("Currentpress: " + currentPress);

        currentType = values[currentChange];
        value = values[currentChange + 1];

        // Type select change is numeric
        if(currentType == 1){
          Min = values[currentChange + 3];
          Max = values[currentChange + 4];
          numIncr = values[currentChange + 2];

          Serial.println("Currentvalue: " + String(value));
          Serial.println("Increments: " + String(numIncr));
          Serial.println("Min: " + String(Min));
          Serial.println("Max: " + String(Max));

          valueLength = String(value).length();

        // Type select change is character range
        } else if(currentType == 2){
          Min = values[currentChange + 2];
          Max = values[currentChange + 3];

          Serial.println("Currentvalue: " + options[value]);
          Serial.println("Options: ");

          for (int i=Min; i <= Max; i++){
            Serial.println(options[i]);
          }

          valueLength = options[value].length();

        }

        clearSelect();
        cursorPosition = 15 - valueLength;
        lcd.setCursor(cursorPosition,cursorLayer);
        writeCursor();

      // ELSE IF something is selected in the menu, and the button is pressed again. We deselect the item.
      } else if(currentPress != ""){

        currentValues();
        currentPress = "";
        currentChange = 0;

        clearChar(cursorPosition,cursorLayer);
        lcd.setCursor(0,cursorLayer);
        writeCursor();

      // IF nothing is selected and nothing will be deselected, move to the redirect layer listed in the first position of the array.
      } else {

        currentLayer = menu[currentPosition + currentSelect].substring(0,1).toInt();
        currentSelect = 1;
        currentlcdLayerFloat = 0;
        currentlcdLayer = 0;
        lastlcdLayer = 0;

        clearSelect();
        cursorLayer = 0;
        lcd.setCursor (0,cursorLayer);
        writeCursor();

      }

    }

    // Reset to layer 0.
    void doubleClick() {
      if(currentLayer == 0){
        currentLayer = 0;
        currentSelect = 1;
        currentlcdLayerFloat = 0;
        currentlcdLayer = 0;
        lastlcdLayer = 0;

        clearSelect();
        cursorLayer = 0;

        lcd.clear();
        lcdUpdated = 0;
      }
      if(currentLayer != 0){
        currentLayer = 0;
        currentSelect = 1;
        currentlcdLayerFloat = 0;
        currentlcdLayer = 0;
        lastlcdLayer = 0;

        clearSelect();
        cursorLayer = 0;
        lcd.setCursor (0,cursorLayer);
        writeCursor();
      }
    }

    void rotary_check(){

      // Constantly read the position of the rotary encoder
      long newPosition = myEnc.read() / 4;

      // IF the new position of the encoder is different then the old position
      if (newPosition != oldPosition) {

        // IF nothing has been selected in the menu
        if(currentPress == ""){

          if(newPosition > oldPosition && currentSelect < currentLength){
            clearSelect();
            currentSelect++;
            currentlcdLayerFloat = currentlcdLayerFloat + 0.5;
            currentlcdLayer = currentlcdLayerFloat;

            cursorSelect();

            lcd.setCursor (0,cursorLayer);
            writeCursor();
            Serial.println("> " + menu[currentPosition + currentSelect].substring(3));

          } else if (newPosition < oldPosition && currentSelect != 1){
            clearSelect();
            currentSelect--;
            currentlcdLayerFloat = currentlcdLayerFloat - 0.5;
            currentlcdLayer = currentlcdLayerFloat;

            cursorSelect();

            lcd.setCursor (0,cursorLayer);
            writeCursor();
            Serial.println("> " + menu[currentPosition + currentSelect].substring(3));

          }

          if(lastlcdLayer != currentlcdLayer){
            lcdUpdated = 0;
          }

          lastlcdLayer = currentlcdLayer;
          oldPosition = newPosition;

        // IF something has been selected in the menu, we are going to change the value of a menu item.
        } else if(currentPress != ""){

          lcd.setCursor(cursorPosition + 1,cursorLayer);
          // IF the new position is HIGHER then the old position
          if(newPosition > oldPosition){
            clearChar(cursorPosition,cursorLayer);

            // IF the selected item has a change type that is NUMERIC.
            // AND the MAXIMUM of the selected item has not been reached.
            // We change the value UPWARDS with the icrements listed in the array.
            // SAME applies for next ELSE IF, just for the change type character. And the next ELSE IF we just go down.
            if(currentType == 1 && value < Max){
                value = value + numIncr;
                values[currentChange + 1] = value;
                Serial.println(value);

                clearValue();
                valueLength = String(value).length();
                cursorPosition = 15 - valueLength;
                lcd.setCursor(cursorPosition + 1,cursorLayer);
                lcd.print(value);
              }

            if(currentType == 2 && value < Max){
                value++;
                values[currentChange + 1] = value;
                Serial.println(options[value]);

                clearValue();
                valueLength = options[value].length();
                cursorPosition = 15 - valueLength;
                lcd.setCursor(cursorPosition + 1,cursorLayer);
                lcd.print(options[value]);
              }
              lcd.setCursor(cursorPosition,cursorLayer);
              writeCursor();

          } else {
            clearChar(cursorPosition,cursorLayer);

            if(currentType == 1 && value > Min){
              value = value - numIncr;
              values[currentChange + 1] = value;
              Serial.println(value);

              clearValue();
              valueLength = String(value).length();
              cursorPosition = 15 - valueLength;
              lcd.setCursor(cursorPosition + 1,cursorLayer);
              lcd.print(value);
            }

            if(currentType == 2 && value > Min){
                value--;
                values[currentChange + 1] = value;
                Serial.println(options[value]);

                clearValue();
                valueLength = options[value].length();
                cursorPosition = 15 - valueLength;
                lcd.setCursor(cursorPosition + 1,cursorLayer);
                lcd.print(options[value]);
              }
              lcd.setCursor(cursorPosition,cursorLayer);
              writeCursor();

          }

          oldPosition = newPosition;
        } else {
          oldPosition = newPosition;
        }

      }
    }

    void lcdMenu(){
      if (lastLayer != currentLayer || lcdUpdated == 0){

        currentLength = menu[0].toInt();
        currentPosition = 0;

        for (int i=0; i < currentLayer; i++){
          currentPosition = (menu[currentPosition].toInt() + 1) + currentPosition;
          currentLength = menu[currentPosition].toInt();
        }

        clearMenu();
        int tempPosition = currentPosition;

        if(currentlcdLayer != 0){

          currentPosition = currentPosition + (currentlcdLayer * 2);
        }

        Serial.println("LCD-------------");

        for (int i=1; i <= 2; i++){
          lcd.setCursor (1,i - 1);
          lcd.print(menu[currentPosition + i].substring(3));

          currentType = 0;
          value = values[menu[currentPosition + i].substring(1,3).toInt() + 1];
          String tempvalue = "";

          if(menu[currentPosition + i].substring(1,3) != "__" && menu[currentPosition + i].substring(1,3) != ""){
            currentType = values[menu[currentPosition + i].substring(1,3).toInt()];
            if(currentType == 1){
              lcd.setCursor (16 - String(value).length(),i - 1);
              lcd.print(value);
              tempvalue = " "+ String(value);
            }else if(currentType == 2){
              lcd.setCursor (16 - options[value].length(),i - 1);
              lcd.print(options[value]);
              tempvalue = " "+ options[value];
            }

          }

          Serial.println(menu[currentPosition + i].substring(3) + tempvalue);
        }
        Serial.println("----------------");

        currentPosition = tempPosition;
        lastLayer = currentLayer;
        lcdUpdated = 1;

        /**
        Serial.println("Layer " + String(currentLayer + 1));
        Serial.println("Layer length " + String(currentLength));
        Serial.println("Layer position " + String(currentPosition));
        **/

      }
    }

    void currentValues(){

      Serial.println("Currentpress: " + currentPress);

      if(currentType == 1){
          Serial.println("Currentvalue: " + String(value));
          Serial.println("Increments: " + String(numIncr));
          Serial.println("Min: " + String(Min));
          Serial.println("Max: " + String(Max));

        } else if(currentType == 2){
          Serial.println("Currentvalue: " + options[value]);
          Serial.println("Options: ");

          for (int i=Min; i <= Max; i++){
            Serial.println(options[i]);
          }
        }
    }

    void clearChar(int charPosition, int line){
      lcd.setCursor (charPosition,line);
      lcd.print(" ");
    }

    void clearLine(int line){
      lcd.setCursor (0,line);
      lcd.print("                ");
    }

    void clearMenu(){
      lcd.setCursor (1,0);
      lcd.print("               ");
      lcd.setCursor (1,1);
      lcd.print("               ");
    }

    void clearSelect(){
      lcd.setCursor (0,0);
      lcd.print(" ");
      lcd.setCursor (0,1);
      lcd.print(" ");
    }

    void cursorSelect(){
      switch (currentSelect){
              case 1:
                cursorLayer = 0;
                break;
              case 2:
                cursorLayer = 1;
                break;
              case 3:
                cursorLayer = 0;
                break;
              case 4:
                cursorLayer = 1;
                break;
              case 5:
                cursorLayer = 0;
                break;
              case 6:
                cursorLayer = 1;
                break;
            }
    }

    void writeCursor(){
      lcd.write(byte(0));
    }

    void clearValue(){
      for (int i = 16 - valueLength; i <= 16; i++){
            lcd.setCursor (i,cursorLayer);
            lcd.print(" ");
          }

    }

body:
Change line

    lcd.begin (16,2);
to

    lcd.begin (20,4);

then position cursor as you did for lines 0 & 1.