body:
I'm getting back up and running with microcontrollers after about 5 years of hibernation time, and I am trying to understand a lot of different things. I have been experimenting with Arduinos for the past few weeks and am having a ton of fun. I'm a software engineer by day and a hardware hacker / manufacturer by night. At my day job, I write scripts and applications that are thousands of lines long and highly complex, using external libraries of thousands more lines of code, etc. These are full-fledge, professional software applications.

So, here is my question. Is the Arduino capable of running full-fledged robotics and other large, complex hardware applications, or is it more of a tinkering, hobbyist tool?

How big of a project can be built using Arduino? Are there memory concerns? Can an Arduino run thousands and thousands of lines of code out of the box, and if not, is there a way to add more memory for larger, more complex projects?

title: How much code can an Arduino board run?

Answers: 3

body:
Although Arduino is more of a hobbyist electronics board, it can handle complex projects depending on which board you use. The Mega has 54 input pins, so can handle loads of devices and has much more memory and storage. See the Uno - Mega specs below

> The ATmega328 chip found on the Uno has the following amounts of memory:
Flash  32k bytes (of which .5k is used for the bootloader)
SRAM   2k bytes
EEPROM 1k byte
>
> The ATmega2560 in the Mega2560 has larger memory space :
Flash  256k bytes (of which 8k is used for the bootloader)
SRAM   8k bytes
EEPROM 4k byte

body:
There are several "Arduinos" with memory capacities ranging from slightly less than 32k/2k/16MHz (Flash/RAM/CPUClock) ("Uno") to 512k/96k/84MHz ("Due".)  In addition, there are "mostly compatible" boards that expand that range down to less than 8k/512/8MHz ("Gemma", "Digistump") and up to about 1M/256k/120MHz (TI "EK-TM4C1294XL Launchpad"), and "somewhat compatible" boards with 4G/1G/400MHz (Intel "Edison")

Whether these are sufficient for "full fledged robotics" depends on what you consider that to mean.  Edison is probably the only contender if you wanted to include computer vision, for example, and it probably doesn't do that very well. ("What did you expect at ONLY 1 core at 400MHz?!")

The small Arduinos probably do not support your "very large libraries", either.  For example, while the "Arduino Language" is technically C++, support for the C++ STL is not included due to limitations of the small CPUs used and their run-time environment.

32k of program memory (on the popular Uno) is sufficient for "thousands of lines of code", but I'd think robotics would tend to run toward much more than that.  The small amount of RAM available on most of the flash-based microcontrollers also tends to be a serious limitation when you start looking at standard data-intensive algorithms.  32k/2k disappears quite quickly if you start implementing an extensive user interface, networking, or graphics.  I would say that an Uno-class Arduino is suitable for implementing COMPONENTS of robotics systems (motor drivers, sensor management, etc), but probably not a whole robot.

A good example of large robotics-like software that runs on Arduino-class hardware can probably be found in the 3D Printer space.  "Marlin" firmware runs on an Arduino Mega or equivalent (256k/8k/16MHz) (with RAMPS shield), and there are alternative driver packages that run on smaller and larger arduino-like hardware.  Marlin is about 280k lines of code, according to cloc.

Most Arduino hardware does NOT have expandable memory.  The AVR cpus cannot run code except from their internal Flash, and few of the other boards have any sort of memory bus that could be used for expansion.

body:
No accepted or up-voted answers, eh? I'll try my hand. :)

> How big of a project can be built using Arduino?

Depends on the model. You can go from around 4 KB of programmable memory to 256 KB, and then get into the larger models like the Due (512 KB).

> Are there memory concerns?

There are *always* memory concerns, however when you have gigabytes of RAM (like on your PC) you tend to ignore them.

These are microcontrollers, designed for embedded applications. You will find yourself probably wishing you had more of everything (RAM, PROGMEM and EEPROM). However for many applications what they have is absolutely fine.

> Can an Arduino run thousands and thousands of lines of code out of the box

Probably not. Consider the Uno with 32 KB of program memory. At from two to four bytes per machine instruction (most are two bytes), you are probably going to fit at most:

    32768 / 2 = 16384

... machine instructions. So no, not hundreds of thousands. The larger models, maybe.

> and if not, is there a way to add more memory for larger, more complex projects?

The Atmega2560 has expandable RAM, for example [here](http://www.rugged-circuits.com/quadram-tech/) which adds 512 KB of RAM.

> How big of a project can be built using Arduino?

I have quite a few around the place here doing their own things. One lets me know if I left the garage door open accidentally. I look upon them as being useful for "helper" applications. I wouldn't try to put my SQL database on one.


body:
I'm creating a project where music gets played that is the same length or slightly shorter than the given time (minutes:seconds). For this I have a Sparkfun MP3 shield, which also has a microSD slot.

The issue is that I can't find a way to get the playtime of a given MP3 file. The only idea that I have is using the filesize and bitrate, but that would be horribly annoying for multiple bitrates.

Thanks in advance,

Michidez

title: Get MP3 play length

Answers: 0


body: I have seen many tutorials on programming an Arduino to control a HC-05 bluetooth module. In that I did not understand the term called 'flag'. What does that mean?

title: What is a flag in programming Arduino?

Answers: 1

body:
I've always used flag to indicate a boolean logic value. I would also suggest this is an archaic term.

Was going to come up with my own explanation but found the following at [In C language, what does flag mean?][1]:

> A 'flag' is a variable that is supposed to signalize something. Think
> about the word itself - flags are used in sending signals. In our
> world of programming a basic boolean flag can either be "up" or
> "down", either true or false.

  [1]: https://www.quora.com/In-C-language-what-does-flag-mean-Is-it-an-arbitrary-variable-name-Can-I-use-flag-2-or-b-etc


body:
I'm new to all this stuff and for the past two days, I have been trying to interface a 16x2 LCD to an Arduino Uno using an Intel 8255A component without any luck. The problem is, how can I attach or set the LCD's pins <<LiquidCrystal lcd(12, 11, 5, 4, 3, 2)>> to the unknown pins of the 8255A.

Is it even possible?

Thanks for any kind of help.[![enter image description here][1]][1]

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

title: Help! Interfacing LCD with Arduino using 8255A Intel peripherals

Answers: 1

body:
You will not be able to use 8255 pins as parameters to the the LiquidCrystal library without making substantial changes to either the library or the Arduino core.

The reason is that to configure or change a pin on the 8255, you will need to go through a series of operations manipulating the ATmega pins to which the 8255's `microprocessor bus interface` is connected.  You can learn about the necessary operations by reading the 8255 data sheet.  Also keep in mind that the 8255 does not have per-pin configuration - rather, the first two ports must each be either entirely inputs or entirely outputs, while there third port can be split in half.

Once you know how to set a pin, you will need to have the liquid crystal functionality trigger these operations.

One approach would be to create a heavily modified version of the library which knows how to work through the 8255.

Another would be to create a modified version of the Arduino core which has additional pin numbers corresponding to the 8255's pins, and generates code which does the necessary intermediate bus operations to access them.  However this will be quite challenging - you have to make sure the intermediate code gets in there in all paths, and figure out how it will handle cases where code tries to set pins that must have the same mode to conflicting modes.

As others have said, you would practically be better off using a different MCU with more I/Os - either an Arduino Mega, or one of the ARM-based boards.


body:
So I am using an Arduino Mega with the [Sparkfun MP3 shield][1]. And I can't seem to read the µSD card. It's formatted in FAT32 and it has a single .txt file on it. I always get this error:

    SD initialization failed.
    Do not reformat the card!
    Is the card correctly inserted?
    Is chipSelect set to the correct value?
    Is there a wiring/soldering problem?
    errorCode: 0x1, errorData: 0xff

I have tried chipSelect 8,9 and 10. I've seen all the other forum threads about the error but none apply here as it is a bought board and not self built, so the wiring should be correct. I've tried software that has ran on the same configuration, and I get the same error.

Thanks in advance,

Michidez

The code that I use to try the SD card (QuickStart, from the SdFat Library):

    // Quick hardware test
    #include <SdFat.h>
    // Test with reduced SPI speed for breadboards.
    // Change spiSpeed to SPI_FULL_SPEED for better performance
    // Use SPI_QUARTER_SPEED for even slower SPI bus speed
    const uint8_t spiSpeed = SPI_HALF_SPEED;
    //------------------------------------------------------------------------------
    // Normally SdFat is used in applications in place
    // of Sd2Card, SdVolume, and SdFile for root.
    Sd2Card card;
    SdVolume volume;
    SdFile root;

    // Serial streams
    ArduinoOutStream cout(Serial);

    // input buffer for line
    char cinBuf[40];
    ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));

    // SD card chip select
    int chipSelect;

    void cardOrSpeed() {
      cout << pstr(
        "Try another SD card or reduce the SPI bus speed.\n"
        "The current SPI speed is: ");
      uint8_t divisor = 1;
      for (uint8_t i = 0; i < spiSpeed; i++) divisor *= 2;
      cout << F_CPU * 0.5e-6 / divisor << pstr(" MHz\n");
      cout << pstr("Edit spiSpeed in this sketch to change it.\n");
    }

    void reformatMsg() {
      cout << pstr("Try reformatting the card.  For best results use\n");
      cout << pstr("the SdFormatter sketch in SdFat/examples or download\n");
      cout << pstr("and use SDFormatter from www.sdcard.org/consumer.\n");
    }

    void setup() {
      Serial.begin(9600);
      while (!Serial) {}  // wait for Leonardo

      cout << pstr(
        "\nSD chip select is the key hardware option.\n"
        "Common values are:\n"
        "Arduino Ethernet shield, pin 4\n"
        "Sparkfun SD shield, pin 8\n"
        "Adafruit SD shields and modules, pin 10\n");
    }

    bool firstTry = true;
    void loop() {
      // read any existing Serial data
      while (Serial.read() >= 0) {}

      if (!firstTry) cout << pstr("\nRestarting\n");
      firstTry = false;

      cout << pstr("\nEnter the chip select pin number: ");
      cin.readline();
      if (cin >> chipSelect) {
        cout << chipSelect << endl;
      } else {
        cout << pstr("\nInvalid pin number\n");
        return;
      }
      if (!card.init(spiSpeed, chipSelect)) {
        cout << pstr(
          "\nSD initialization failed.\n"
          "Do not reformat the card!\n"
          "Is the card correctly inserted?\n"
          "Is chipSelect set to the correct value?\n"
          "Is there a wiring/soldering problem?\n");
        cout << pstr("errorCode: ") << hex << showbase << int(card.errorCode());
        cout << pstr(", errorData: ") << int(card.errorData());
        cout << dec << noshowbase << endl;
        return;
      }
      cout << pstr("\nCard successfully initialized.\n");
      cout << endl;

      uint32_t size = card.cardSize();
      if (size == 0) {
        cout << pstr("Can't determine the card size.\n");
        cardOrSpeed();
        return;
      }
      uint32_t sizeMB = 0.000512 * size + 0.5;
      cout << pstr("Card size: ") << sizeMB;
      cout << pstr(" MB (MB = 1,000,000 bytes)\n");
      cout << endl;

      if (!volume.init(&card)) {
        if (card.errorCode()) {
          cout << pstr("Can't read the card.\n");
          cardOrSpeed();
        } else {
          cout << pstr("Can't find a valid FAT16/FAT32 partition.\n");
          reformatMsg();
        }
        return;
      }
      cout << pstr("Volume is FAT") << int(volume.fatType());
      cout << pstr(", Cluster size (bytes): ") << 512L * volume.blocksPerCluster();
      cout << endl << endl;

      root.close();
      if (!root.openRoot(&volume)) {
        cout << pstr("Can't open root directory.\n");
        reformatMsg();
        return;
      }

    cout << pstr("Files found (name date time size):\n");
      root.ls(LS_R | LS_DATE | LS_SIZE);

      if ((sizeMB > 1100 && volume.blocksPerCluster() < 64)
        || (sizeMB < 2200 && volume.fatType() == 32)) {
        cout << pstr("\nThis card should be reformatted for best performance.\n");
        cout << pstr("Use a cluster size of 32 KB for cards larger than 1 GB.\n");
        cout << pstr("Only cards larger than 2 GB should be formatted FAT32.\n");
        reformatMsg();
        return;
      }
      // read any existing Serial data
      while (Serial.read() >= 0) {}
      cout << pstr("\nSuccess!  Type any character to restart.\n");
      while (Serial.read() < 0) {}
    }

  [1]: https://www.sparkfun.com/products/12660

title: Reading SD card with Sparkfun MP3 Shield

Answers: 1

body:
Firstly, where did you get the get the SdFat library from? A quick search on GitHub returned 34 results: [GitHub search of SdFat][1]. Of those, [Greiman][2] and [Adafruit][3] were the highest results on Google.

The reason I mention this is that you could be using a library that has issues or requires something specific in the hardware. I would suggest using the [Adafruit][3] version, as that would be the most scrutinized and hence the most stable. It appears very similar to the Arduino library (mentioned below).

Arduino has a [SD library][4] that comes with the Arduino IDE. It is simply called `SD`. There are 6 example programs:

 - `CardInfo`: SD card test - This example shows how use the utility libraries on which the'SD library is based in order to get info about your SD card. Very useful for testing a card when you're not sure whether its working or not.
 - `ReadWrite`:  SD card read/write - shows how to read and write data to and from an SD card file.
 - `Files`: SD card basic file example - shows how to create and destroy an SD card file.
 - `ListFiles`:  Listfiles - This example shows how print out the files in a
 directory on a SD card.
 - `DumpFile`:   SD card file dump - shows how to read a file from the SD card using the SD library and send it over the serial port.
 - `Datalogger`: SD card datalogger - shows how to log data from three analog sensors.

Use the CardInfo example program to verify that your setup is correct. Then progress to one of the other examples such as `ListFiles` or `Dumpfile`.

  [1]: https://github.com/search?utf8=✓&q=sdfat&type=
  [2]: https://github.com/greiman/SdFat
  [3]: https://github.com/adafruit/SD
  [4]: https://www.arduino.cc/en/Reference/SD


body:
This is my code. I am tring to make a connection to my wifi through esp8266.

    #define DST_IP "192.168.1.5" // my IP
    #include <SoftwareSerial.h>

    SoftwareSerial mySerial(0, 1);

    void setup()
    {
      Serial.begin(115200);
      mySerial.begin(115200);
      while (! Serial); // Wait until Serial is ready - Leonardo
      Serial.println("AT+RST");
      delay(4000);
      Serial.println("AT+CWJAP=\"Ahmed\",\"12341234Aass\"");
      delay(4000);
      if (Serial.find("OK") )
      {
        Serial.println("1");
      }
      else
      {
        Serial.println("0");
      }
    }

    void loop()
    {

    }

This is the result of my code.

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

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

title: Connecting to WIFI using esp8266

Answers: 1

body:
    SoftwareSerial mySerial(0, 1);

try changing **pin0** and **pin1** with some other pins. (lets say with **pin2** & **pin3**)

**pin0** and **pin1** are used by default **Serial**.


body:
    #include <avr/sleep.h>
    #include <avr/power.h>
    //This sketch is a metronome, in which each led pin shows one beat.

    const int speaker = 13;  //speaker at pin 13
    int ts = 6;  //highest led pin
    int count = 3;  //"beat 1 pin"
    const int keyPin = 11;  //button to change time signature
    const int keyPinR = 10;  //button to change rhythm
    const int keySwitch = 2;  //sleep mode/wake up button

    //All pins below use a pull-up resistor, so the states are inverted
    int buttonState = LOW;
    int buttonState2 = LOW;
    int switchState = LOW;
    int silentState = LOW;

    int bpm = 120;  //you do not need to know this,
    //it's just a variable for the potentiometer to change the tempo

    int rthm = 1;  //rhythm
    volatile int pressed = 0;
    long silent = p;

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

       for(int thisPin = 3;thisPin <= ts;thisPin++)
       {
          pinMode(thisPin,OUTPUT); //initialize thisPin as an output
          pinMode(8, INPUT); //potentialmeter for changing temp
          //Pin 9 to 11, along with pin 2, are all push buttons with pull-up     resistors
          for(int i = 9; i<=11; i++)
          {
             pinMode(i, INPUT);
             digitalWrite(i, HIGH);
          }
             pinMode(2, INPUT);
             digitalWrite(2,HIGH);
       }
    }

    void loop()
    {
       turnOn();
    }

    void turnOn()
    {
        buttonState = digitalRead(keyPin);//key for
        buttonState2 = digitalRead(keyPinR);
        switchState = digitalRead(keySwitch);
        silentState = digitalRead(9);
        //Serial.println(switchState);
        if(switchState==LOW&&pressed==0)
        {
           sleep_enable();
           set_sleep_mode(SLEEP_MODE_PWR_DOWN);
           attachInterrupt(digitalPinToInterrupt(0), interrupt, LOW);
           sleep_cpu();
           //Serial.println(switchState);
        }
        else {
           //The beat starts at pin 3, runs in consecutive pins,
           //and ends at pin 8 at maximum
           if(buttonState==LOW)
           {  //changing time signature - up to 5 beats
               ts++;
               if(ts==8)
               {
                  ts = 3;
                  //8 - 3 = 5 beats max
               }
            }
            if(buttonState2==LOW)
            {  //changing rhythm - quarter note to eighth, then
              //triplets and sixteenths, back to quarter notes
              rthm++;
              if(rthm==5)
              rthm = 1;
     }

        if(silentState==LOW){//if silent key pressed, go to silence (only LED's showing)
        silent++;
      }

      //The RUN code
      for(int thisPin = 3;thisPin <= ts;thisPin++)
      //LED's blinking beats (thisPin - LED pin (beat number + 2))
     {

     for(int r = 1; r<=rthm; r++)
     {//nested loop for the rhythm
       bpm = pulseIn(8, HIGH);//pin 8 - tempo potentialmeter
       digitalWrite(thisPin,HIGH);//each LED blinks

       pinMode(13,OUTPUT); //pin 13 - speaker

       if(silent%2==0)//Press once, tone, press again, no tone
         noTone(13);
     else
     if(count == 3&&r==1). //first beat is higher
     tone(13,4400,80);
     else if(r==1). //downbeats slightly lower
     tone(13,2500,80);
     else
     tone(13,2200,60);  //off beats even lower
     delay((bpm-52)/rthm);
     digitalWrite(thisPin,LOW);  //turn each off as we proceed to the next beat (LED)
     pinMode(13,INPUT);  //speaker input
    }
    count++;  //beat++

    if(count >ts){//go back to count
    count = 3;
    }

       }
      }
     }

    void noSound()//silence the speaker
    {
      noTone(13);
    }

    void interrupt()//this is where the sleep interrupt starts -               //how can i press it to wake up???
    {
        sleep_disable();
        detachInterrupt(0);
        if(switchState==HIGH){
           pressed = 1;
           Serial.println(switchState);
           turnOn(); //go back to the main functional method (?????)
         }
     }

Once the keySwitch button is pressed (pin 2), the arduino goes to sleep; however, the only way to turn it on is by resetting everything. How can I just wake up the Arduino, keeping every state as before the sleep interrupt?

title: Wake up from sleep from pressed button?

Answers: 1

body:
    attachInterrupt(digitalPinToInterrupt(0), interrupt, LOW);

 should be either

    attachInterrupt(0, interrupt, LOW);

or

    attachInterrupt(digitalPinToInterrupt(2), interrupt, LOW);

As pin 0 is not an interrupt pin. Also the button is connected to pin 2, not pin 0. `digitalPinToInterrupt(0)` would actually return `-1`.


body:
I am trying to use a rotary encoder with an integrated circuit to measure the position of a rotating shaft. I am then taking this data and writing to an SD card. The IC seems to be working correctly and outputting binary data to the specified pins,  but the data does not seem to be reaching the micro-controller. My output data is fragmented, and seems to only be receiving binary data from some of the IC pins. The IC I am using is HCTL-2021-A00 (http://www.mouser.com/ProductDetail/Avago-Technologies/HCTL-2021-A00/?qs=RuhU64sK2%2bsgeK17XZB/NA==). I tried using a larger gauge wire to connect the two, but then the micro-controller didn't seem to pick up any of the data. Here is the code I used.

   I am trying to use a rotary encoder with the HCTL-2021-A00 from avago. I am getting data output from the IC, but only one of the two bytes which it should be providing. When I move the encoder forward, it will only give me the LOW byte and all of the high bits will be zero. However, when I move the encoder backward, all of the high data bits are 1, and the low data bits still operate normally, counting the position. What could cause the high data bits to all be 1 when moving backward, and all 0 when moving forward? Code used is below.

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

    File datafile;
    const int chipSelect = 10; // connected to the CS pin on the sd card, Make sure the card is formatted
    int encoderpos=0;
    int i=0;
    int pulses, A_SIG=0, B_SIG=1;
    int b[15];  //the individual bits of data read from the IC
    int pos; //position output of IC ranging from 0 to 5000 for 1 revolution
    int selpin=1, OEpin=2;
    int clock=4;
    int d[7]; //the pins on the IC attached to which digital teensy pins
    double deg; //degree position of the servo as found from the encoder and IC

    void setup()
    {
      //set pwm signal for timer input
      pinMode(4, OUTPUT);
      analogWriteFrequency(4, 6000000); // Teensy 3.0 pin 3 also changes to 375 kHz
    analogWrite(4, 128);
       //First setup and attach the pins used to communicate with the IC and encoder
      d[0]=22;//pin numbers for attaching the IC to the teensy
      d[1]=21;
      d[2]=20;
      d[3]=19;
      d[4]=18;
      d[5]=17;
      d[6]=16;
      d[7]=15;
    //first set pins as inputs and outputs
    pinMode(selpin, OUTPUT);
    pinMode(OEpin, OUTPUT);
    pinMode(d[0], INPUT);
    pinMode(d[1], INPUT);
    pinMode(d[2], INPUT);
    pinMode(d[3], INPUT);
    pinMode(d[4], INPUT);
    pinMode(d[5], INPUT);
    pinMode(d[6], INPUT);
    pinMode(d[7], INPUT);

    digitalWrite(selpin, HIGH);
    digitalWrite(OEpin, HIGH);

    pinMode(5, OUTPUT);

    digitalWrite(5, HIGH);
    delay(5);
    digitalWrite(5, LOW);
    delay(5);
    digitalWrite(5, HIGH);
    delay(5);

    pinMode(chipSelect, OUTPUT);
    SD.begin();
    datafile=SD.open("c.txt", FILE_WRITE);
    pinMode(7, INPUT);
    pinMode(8, OUTPUT);

    }

    void loop()
    {
    datafile.println(pose());
    if (millis()>4000)
    {
      datafile.close();
    }

    delay(5);
    }

    int pose()     //Gives the position in degrees from the readings from encoder and IC for 0 to 5000 representing one revolution
    {
        digitalWrite(selpin, LOW);     // The sel pin on the IC
      digitalWrite(OEpin, LOW);     // The OE pin on the IC
    digitalWrite(4, HIGH);
    digitalWrite(4, LOW);
    analogWrite(4, 128);

      b[0]=digitalRead(d[0]);
      b[1]=digitalRead(d[1]);
      b[2]=digitalRead(d[2]);
      b[4]=digitalRead(d[4]);
      b[5]=digitalRead(d[5]);
      b[6]=digitalRead(d[6]);
      b[7]=digitalRead(d[7]);
    if(digitalRead(7)==1)
    {
      digitalWrite(8, HIGH);
    }
    else if(digitalRead(7)==0)
    {
      digitalWrite(8, LOW);
    }
      digitalWrite(selpin, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(4, LOW);
    analogWrite(4, 128);

      b[8]=digitalRead(d[0]);
      b[9]=digitalRead(d[1]);
      b[10]=digitalRead(d[2]);
      b[11]=digitalRead(d[3]);
      b[12]=digitalRead(d[4]);
      b[13]=digitalRead(d[5]);
      b[14]=digitalRead(d[6]);
      b[15]=digitalRead(d[7]);

      digitalWrite(OEpin, HIGH);

      pos=0;
      i=8;
      for(i; i>0; i--)
      {
    pos=2*pos+b[i-1];
      }

      i=16;
      for (i; i>8; i--)
      {
        pos=2*pos+b[i-1];
      }

      return pos;

    }

title: Communication between IC and microcontroller (Teensy 3.2)

Answers: 3

body:
Wanted to just put this in a comment but apparently still don't have the rep to do that, so taking a stab at answering.

Sounds to me like you are having physical layer corruption issues.  I highly doubt that your wires were too fine a gauge since these are just signal wires for SPI, however, it was instructive that you did that since larger wires seemed to make the problem worse, I would guess that you have too large capacitance on the wire for the datarate you have chosen.

When I am debugging any serial communications for the first time, the first thing I do until communication is reliable is to slow the data rate down.  Something like 10kHz should work in most cases.  See if this fixes the corrupted data.  If it does, go back to a finer gauge wire and then bump the speed back up til you see corruption issues.  If you have a logic analyzer or a scope you can get on the line, it will be very educational to see what is going on with your edge rates.

body:
You seem to be overlooking (or at least mishandling) the fact that these parts are built with a bus interface where the /OE and SEL signals as well as the internal position data latch are *sampled* synchronously with a clock input which you do not seem to be driving.

* You need to generate a low-to-high transition of the CLK signal to latch the count into the readout

* You need to generate a high-to-low transition of the CLK signal to latch in chosen values of the /OE and SEL signals.

On second examination of your code, perhaps you are trying to use a free-running clock asynchronous to your reading.  That, however, is extremely unwise.  First, you don't know that a suitable clock edge will happen between when you set the /OE or SEL and when you try to read the data.  Next, you do not know that an *undesired* clock edge will *not* happen in the midst of reading data, causing you to end up with a corrupted value that contains some "old" bits from before the clock edge and some "new" bits from after.  This would be particularly bad if it happened across a transition such as 0b01111111 to 0b10000000 or similar...

You may have other problems as well - your question is not complete without a schematic diagram of how you have wired up this chip.

body:
I found the problem.
I had assumed that the rst pin was supposed to be held low unless you wanted to reset the count on the encoder, and was ignoring it the whole time. Once I held the reset pin high, the count started to show up.

As of now there are still problems, I cannot read the high byte from the IC.


body:
I'm using two [nRF24L01](http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01) to communicate with each other. I did the right setup and they worked fine, however I wanted to change the air data rate to a lower value, for more stability, as the [datasheet](http://www.nordicsemi.com/eng/content/download/2730/34105/file/nRF24L01_Product_Specification_v2_0.pdf) says.

How can I setup the configuration for this?

After a small research I knew that you can change this using `RF_DR`
to change the value of the transmission, but I didn't really know how I could exactly write the correct code for this.

Another question: does this effect the range of the module? Or does it only affect the stability? And if not, then which code can I use to extend the range of these two modules ?

title: Air data rate nRF24L01

Answers: 3

body:
The documentation for the function you want is [here](http://tmrh20.github.io/RF24/classRF24.html#aeb9920e7a95699748b003c4a839b0814).

Reducing the speed doesn't directly increase the range, but increased stability will have the knock-on effect that the fringes of transmission distance will be more reliable, making it appear that you have slightly greater distance.

body:
Increasing stability will increase the (usable) range. At least a bit. You could try decreasing the packet size, to make it even more reliable. There is no way to increase the output-power (only decrease).

You could try different channels, and see which one gives you the best range in your application.

After that you have to get NRF24 modules, with external antennas and amplifiers.

body:
According the nRF datasheet if you decrease the data rate it will definitely affect your range.

A lower data rate will increase your stability due to which the nRF can detect weaker signals (-102 dB at 250Kbps) due to this you can significantly increase the range (up to 1km theoretically).

Also if you need to increase your range further you can attach an antenna with a higher gain than what you already have.

No other software changes will affect the range other than reducing the transmission speed.


body:
I am currently trying to learn how to use my MQ 7 CO Standalone to read CO in the air around the sensor. Currently Im using this circuit using my Arduino Uno. I get results of 900-1000. Here's a Fritzing Schematic on my setup. [![enter image description here][2]][2]

Currently this is the code I am using on the arduino:

[code]

    int mqx_analogPin = A0; // connected to the output pin of MQ-X

    void setup(){
      Serial.begin(9600); // open serial at 9600 bps
    }

    void loop()
    {
      // give ample warmup time for readings to stabilize

      int mqx_value = analogRead(mqx_analogPin);
      Serial.println(mqx_value);

      delay(100); //Just here to slow down the output.
    }

I'm following the setup from this Instructables:
http://www.instructables.com/id/Smoke-Detector/?ALLSTEPS

However his readings are around 150-200ppm outside. I'm unsure how to reach these values since im following basically everything from the guide. Does anyone any experience with a MQ7 sensor?

I've been reading I need to preheat the sensor but I can't find any circuit that clearly shows how to preheat an MQ7 sensor or find any code for the arduino.

  [2]: https://i.stack.imgur.com/gPi7c.png

title: MQ7 Readings are too high

Answers: 2

body:
Using of this sensor is a bit more complicated than that. You must cycle through 60 seconds of heating and 90 seconds of measurement cycles, during heating you need to provide 5V on its heater pins, during measurement you need to provide 1.4V, so you'll need transistor or some other PWM-controlled current limiter (Arduino pin can't provide enough current for sensor heating).
I've tried to explain all details and calibration process here: https://www.instructables.com/id/Arduino-CO-Monitor-Using-MQ-7-Sensor/

body: Yes, it is not easy, lot of details to MQ-7 is here: http://www.arduinohobby.euweb.cz/  in the section "Analysator CO"


body:
I'm working on a personal project  (a usefully tool based on ublox GPS and Arduino Mega that can measure distance between 2 points, compute area, speed, save data on SD card)

Now I want to add new feature and when I show the area(in m^2) on LCD, I want to show the polygon built by more coordinates.

I tried all I know, I searched for solutions but without success.

How can I "scale down" coordinates to make them fit in a x,y system with max size (320*480, LCD size) ?

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

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

title: Draw polygon on LCD from GPS latitude and longitude

Answers: 2

body:
Over a small area lat and long are just simple Y and X coordinates respectively.

Dynamic scaling of the points is a very simple matter.  All you need to do is work out the range of each dimension - so subtract the lowest latitude from the highest, and the lowest longitude from the highest.

That gives the full X and Y dimension of your area. Then just divide those by the dimensions of your screen.  That gives you a scaling factor for each direction.

For each point, subtract the lowest longitude and latitude, and divide by the scaling factor for each direction.

If you want to be more fancy and retain the aspect ratio then you just need to work out which of the two scaling factors will allow all the polygon to remain on the screen - that is, divide and offset all your points by one factor, then by the other, and pick the smallest factor where all the points are within the area of your screen.

body:
I did the code for Arduino and it works really nice. I added an dynamic X offset to center it on the screen.

    // lat = coordinatesForArea[i][0]
    // lng = coordinatesForArea[i][1]
    // cntr is the count of points

    float newPoints[100][2];
    float maxLat = 0;
    float maxLng = 0;
    float minLat = 180;
    float minLng = 180;

    for (int i = 0; i < cntr; i++) {
      maxLat = max(maxLat, coordinatesForArea[i][0]);
      maxLng = max(maxLng, coordinatesForArea[i][1]);
      minLat = min(minLat, coordinatesForArea[i][0]);
      minLng = min(minLng, coordinatesForArea[i][1]);
    }

    float ySize = maxLat - minLat;
    float xSize = maxLng - minLng;

    float scaleFactor = ySize / 300;

    float maxY = 0;
    float maxX = 0;

    for (int i = 0; i < cntr; i++) {
      newPoints[i][1] = (coordinatesForArea[i][1] - minLng) / scaleFactor;
      newPoints[i][0] = (coordinatesForArea[i][0] - minLat) / scaleFactor;
      maxX = max(maxX, newPoints[i][0]);
      maxY = max(maxY, newPoints[i][1]);
    }

    float newScaleFactor = maxY > maxX ? maxY / 300 : maxX / 300;

    float newMaxX = 0;

    for (int i = 0; i < cntr; i++) {
      newPoints[i][1] = newPoints[i][1] / newScaleFactor;
      newPoints[i][0] = newPoints[i][0] / newScaleFactor;

      newMaxX = max(newMaxX, newPoints[i][0]);
    }

    float newOffsetX = (320 - newMaxX) / 2;
    float newOffsetY = 100;

    for (int i = 0; i < cntr; i++) {
      newPoints[i][1] = newPoints[i][1] + newOffsetY;
      newPoints[i][0] = newPoints[i][0] + newOffsetX;
    }

    for (int i = 0; i < cntr-1; i++) {
      myGLCD.drawLine(newPoints[i][0], newPoints[i][1], newPoints[i+1][0], newPoints[i+1][1]);
    }

    myGLCD.drawLine(newPoints[0][0], newPoints[0][1], newPoints[cntr-1][0], newPoints[cntr-1][1]);

Thank you Majenko


body:
I have connected a BMP280 temperature/pressure sensor to an Arduino Uno just like here:

[![pin layout BMP280+Arduino Uno][1]][1]

and used the example code provided by the Adafruit BMP280 library. However, the values for temperature and pressure return 0.00 on the serial monitor. What might be the reason for this? I have set it up in I2C mode and deleted the lines responsible for the SPI connections.

        /***************************************************************************
      This is a library for the BMP280 humidity, temperature & pressure sensor

      Designed specifically to work with the Adafruit BMEP280 Breakout
      ----> http://www.adafruit.com/products/2651

      These sensors use I2C or SPI to communicate, 2 or 4 pins are required
      to interface.

      Adafruit invests time and resources providing this open source code,
      please support Adafruit andopen-source hardware by purchasing products
      from Adafruit!

      Written by Limor Fried & Kevin Townsend for Adafruit Industries.
      BSD license, all text above must be included in any redistribution
     ***************************************************************************/

    #include <Wire.h>
    #include <SPI.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BMP280.h>

    #define BMP_SCK 13 // deleted the following 4
    #define BMP_MISO 12
    #define BMP_MOSI 11
    #define BMP_CS 10

    Adafruit_BMP280 bme; // I2C
    // and the following 2 lines:
    //Adafruit_BMP280 bme(BMP_CS); // hardware SPI
    //Adafruit_BMP280 bme(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);

    void setup() {
      Serial.begin(9600);
      Serial.println(F("BMP280 test"));

      if (!bme.begin()) {
        Serial.println("Could not find a valid BMP280 sensor, check wiring!");
        while (1);
      }
    }

    void loop() {
        Serial.print("Temperature = ");
        Serial.print(bme.readTemperature());
        Serial.println(" *C");

        Serial.print("Pressure = ");
        Serial.print(bme.readPressure());
        Serial.println(" Pa");

        Serial.print("Approx altitude = ");
        Serial.print(bme.readAltitude(1013.25)); // this should be adjusted to your local forcase
        Serial.println(" m");

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

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

title: BMP280 returns 0

Answers: 4

body:
I2C has to have pull up resistors on the data lines, otherwise it just doesn't work.

Have a quick search for the correct value but off the top of my head is 4.7k ish.

You have to place a resistor from the SDA and SCK lines to the +5V and suddenly it will jump into life. (Hopefully)

body: I had the same problem and I solved it by changing I2C address from 0x77 to 0x76, in Adafruit_BMP280.h

body:
well the reason for changing the I2C address from 0x77 to 0x76 is when you have your SD0 pulled down to ground.

If there is nothing attached to SD0 on the BMP280 the device address is 0x77 by default.

body:
Recently i bought a bmp280 which is not an adafruit one and connected it to esp32 and and tried to upload the code from the examples test but i got the error no valid bmp 280 found, i searched on google and found
[https://www.circuitschools.com/interfacing-bmp280-with-esp-32-on-i2c-with-errors-and-solutions/][1]
i read on i2c addresses errors,then from there i copied the code for an i2c scanner and ran it to get the correct i2c address  I checked on I2c address and replaced the i2c hex address in the BMP initiialization line.

then the sensor worked and gave me temp, pressure and approx altitude. Thanks

  [1]: https://www.circuitschools.com/interfacing-bmp280-with-esp-32-on-i2c-with-errors-and-solutions/


body:
I am trying to get a response from the arduino when I press a key, but when I try to upload the code it says that it could not find 'Keyboard' with 'Keyboard.write'. Here is my code. Ignore the bits with servo stuff, that is for the project later on. I am using the arduino mega 2560.

      #include <Servo.h>
      #include <Keyboard.h>

    Servo myservo;
    Servo myservo2;

    int pos = 0;
    int pos2 = 0;
    String comdata = "";
    int lastLength = 0;

    void setup() {
    myservo.attach(12);
    myservo2.attach(11);
    Serial.begin(9600);
    pinMode(2, INPUT_PULLUP);
    Keyboard.begin();
    }

    void loop() {
    if (Serial.available() > 0) {
     // read incoming serial data:
     char inChar = Serial.read();
     Keyboard.write(inChar + 1);
    }

    }

title: 'Keyboard' not found when trying to use Keyboard.write from the <Keyboard> library

Answers: 2

body:
The Mega2560 can't be a keyboard. It lacks the required hardware.

Instead you need to use one of the pure USB boards, like the Leonardo.

body: To use USB communication (such as mouse or keyboard) you must have a arduino that uses an ATMEGA32U4. These are so far, the only boards that can work as a USB device.


body:
I made something that uploads the measured current to Thingspeak. Everything works, but i did not place the DC to DC converter on the board because i was worried that it would interfere with the analog input. Also the ESP8266 is very close to the Arduino Pro Mini. Could it affect the reading?
Could i have put the DC to DC converter on the board without any problem?

[![Arduino Pro Mini that uploads the current consumption to Thingspeak every 15 seconds][1]][1]

230VAC to 12VDC adapter(not on the picture) --> 12VDC to 3,3VDC(on the picture)-->the prototype board

Sensor: SCT-013-030 30A = 1V

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

title: When should you worry about interference affecting the analog input?

Answers: 2

body:
Noise reduction involving Analog to Digital Conversions can be done in many ways.  Common software solutions involve averaging multiple conversions.  [Exponential smoothing][1] is one such method.  One advantage of exponential smoothing is that it can be applied to an endless stream of conversions.

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

body: You are more likely to have noise injected on the power pins of the Arduino that by EMI or capacitative coupling. With the switcher on board of off board it will make no difference if the voltage it supplies to the Arduino (and hence to the ADC) is noisy and full of spikes.


body:
Curently I am using these connectors for my prototype:
[Ebay link][1]

However, I need something more reliable so I can deliver the prototype to a user without to risk that the cables fall out of their pins.
Is there something else to use? I would like to avoid soldering.. :(

  [1]: http://www.ebay.com/itm/120pcs-10cm-2-54mm-1pin-Jumper-Wire-Dupont-Cable-for-Arduino-/381350806379?hash=item58ca47836b:g:V38AAOSwN81WEeMm

title: Are there fixed connectors for gpio?

Answers: 2

body:
Unless you want to replace the headers with something else, which means soldering, then you will be soldering.

The options are:

1. Solder different connectors in the place of the existing headers
2. Remove the existing headers and solder wires directly in their place
3. Get a prototyping shield and solder wires in to that
4. Get a prototyping shield and solder different connectors to it.

Whatever you choose you will be soldering.

Don't be scared of soldering - it's the most basic thing you need to be able to do when you are working with electronics.

body:
The cables you link are supposed to be assembled by *crimping* rather the *soldering*.  The risk of them falling out is mostly because the housing are only for a single contact.

If you instead get multi-contact housings the width of the headers you are matching, and insert contacts into those in the desired positions, the risk of things falling out will be greatly reduced.  You can add a label to indicate correct insertion direction.

Of course, a much better result would be to make either a custom shield with terminations for the signals you need to route elsewhere, or to replace the Arduino itself with a custom ATmega board that handles application-appropriate polarity-keyed wiring harnesses.


body:
I want to have 6 audio jacks IN waiting for connection to start some WAV/OGG playback as soon as a headphone plugs in. In fact, I'd like to have simultaneous playback in 6 lines.

I've seen in the market some stuff that you can add buttons to different actions (play, pause, stop, etc). So far I believe this might be possible and affordable with Adafruit's Audio FX (which are stand-alone, Arduino-programmable WAV/OGG decoder circuits).

But,
> Is it possible to start audio playback when headphones gets plugged
> in? HOW?

Is that an event? like pressing a button?

Does it need some "hacking" between GND lines maybe?

title: Is it possible to start audio playback when headphones gets plugged in?

Answers: 1

body:
A lot of 3.5mm jacks come with built-in normally-closed contacts, and their state can be tested through the pins of the jack with a multimeter or sensed by your MCU like any other switch. There are usually 2 pins each for the **ring** (pins 2 and 4 below) and the **tip** (pins 3 and 5), each pair connected to the other and one pin for the **sleeve**. The insertion of the headphones' connector breaks the connection between each pair, so that only one pin of each pair is actually connected to the connector's tip and ring.

[![jack schematic][1]][1]

You can connect the tip (pin 3) of each jack to digital input pins and connect the other pin of the pair (pin 5) to Vcc; you only need to read the tip because if the tip contacts are closed, it means nothing is fully plugged in yet. When no connector is plugged in, input pin reads HIGH from the tip since it is connected to Vcc through pin 5. When the headphones are plugged in, it breaks the 3-5 connection, and the tip now floats. Its voltage is indeterminate; it will probably sit somewhere near the middle of the 0-5V range, but we can't be sure.
To remedy this, there are 2 possible approaches I can see:

 - You use an **analog** input pin, instead of a digital pin. This way, you can read the very voltage at the tip; if its ADC value is above 900 perhaps, you can conclude that its HIGH and therefore nothing is plugged in, whereas if its below 600, you can conclude that the tip is floating and a headphone is plugged in. However, this method will require an input pin per headphone. The Uno has 6 analog pins, so this will take up all of them. If you aren't already using any of them, this method may be good enough. You could also use an analog GPIO expander.

 - You can use a digital input pin for the tip (pin 3) *but* instead of pulling pin 5 to Vcc, you connect it to a digital output pin. You can connect the pin 5 of each headphone set to this common output pin. To test if a particular jack has headphones plugged into it, you read the associated input pin and check if this is the same as the current value of the common output pin (saved to some variable). If it is, you toggle the output pin and again check the input pin to see if it mirrors the new value of the output pin; just additional confirmation. If everything checks out, then nothing is connected to the jack yet. If either test fails, you can reasonably conclude that headphones are plugged in.

Now that you know headphones are plugged in, you can call the appropriate function to begin playback through the right jack. Of course, all this assumes you'll be working with the jacks directly and not through some module. If you use the Adafruit Soundboard, you can check out the L (Left Channel) pin, which corresponds to the tip. I don't know if it's actually connected to the jack so you'll have to experiment and find out.

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


body:
I'm using an ESP8266 (NodeMCU Dev Kit v1) to read analog data via an MCP3008 ADC chip.

However I'm receiving only zeros when I know non-zero data should be present. I'm using the following code, which works perfectly when using the MCP3008 with my Arduino UNO. Using verbose mode on compilation, I can confirm that when compiling for the ESP8266, that is indeed linking the ESP8266 SPI library.

Am I missing something here in the code?

    #include <SPI.h>

    #define CS_PIN 15 // Use 10 when compiling for Arduino

    int adcRead(int channel) {
      if ((channel > 7) || (channel < 0)) {
        return -1;
      }

      digitalWrite(CS_PIN, LOW);

      SPI.transfer(1);
      uint8_t r1 = SPI.transfer((channel + 8) << 4);
      uint8_t r2 = SPI.transfer(0);

      digitalWrite(CS_PIN, HIGH);

      return ((r1 & 3) << 8) + r2;
    }

    void setup() {
      SPI.begin();
      SPI.setBitOrder(MSBFIRST);
      SPI.setDataMode(SPI_MODE0);
      SPI.setFrequency(1000000); // 1 MHz -- remove line when running on Arduino UNO
      Serial.begin(9600);
      digitalWrite(CS_PIN, HIGH);
    }

    void loop() {
      Serial.println(adcRead(0));
      delay(50);
    }

In terms of wiring, I have the following

    MCP3008   ESP8266
    V_DD      3v3
    V_REF     3v3
    AGND      GND
    CLK       GPIO14 (D5)
    D_OUT     GPIO12 (D6)
    D_IN      GPIO13 (D7)
    CS        GPIO15 (D8)
    DGND      GND

title: Arduino/ESP8266 no SPI data coming from MCP3008

Answers: 1

body:
I was having trouble with this code and setup with the Adafruit Feather HUZZAH ESP8266.

# Solution #
In addition to adding the `pinMode(CS_PIN, OUTPUT);` to `setup()`, I also dropped the frequency to something much lower. In my case, dropping the frequency to 10000 gave me good readings.


body:
I am communicating with my GoPro via ESP8266 and GET requests.

One of the replies returns a set of predefined number and what I would like to do is extract the number on position "38". This is what the reply looks like in full:

    SEND OK

    +IPD,4,163:HTTP/1.1 200 OK
    Transfer-Encoding: chunked
    Date: Sun, 24 Apr 2016 03:13:40 GMT
    Server: Cherokee/1.2.101b150714_bd80061 (UNIX)
    Content-type: application/json

    OK

    +IPD,4,972:3c0
    {"status":{
    "1":1,"2":1,"3":0,"4":0,"6":0,"8":0,"9":0,"10":0,"11":0,"13":0,"14":0,"15":0,"16":0,"17":1,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"26":0,"27":0,"28":18,"29":"","30":"xxx","31":0,"32":0,"33":0,"34":7933,"35":5039,"36":0,"37":4,"38":0,"39":4,"40":"
(","41":0,"42":0,"43":1,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"54":29698976,"55":1,"56":4,"57":1022279,"58":0,"59":0,"60":500,"61":2,"62":0,"63":0,"64":0},
    "settings":{"1":0,"2":9,"3":6,"4":1,"5":2,"6":1,"7":1,"8":0,"9":0,"10":0,"11":1,"12":1,"13":1,"14":0,"15":4,"16":0,"17":2,"18":2,"19":2,"20":0,"21":1,"22":2,"23":0,"24":2,"25":0,"26":4,"27":0,"28":2,"29":1,"30":10,"31":0,"32":0,"33":0,"34":1,"35":2,"36":1,"37":2,"38":0,"39":4,"40":0,"41":13,"42":8,"43":0,"44":8,"45":8,"46":0,"47":0,"48":0,"49":0,"50":1,"51":1,"52":0,"53":0,"54":0,"55":1,"56":1,"57":1,"58":1,"59":0,"60":8,"61":1,"62":700000,"63":4,"64":1,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":1}}

    0

    OK

As you can see, position 38=0 (...,"38":0,...). The number 0 will increment. So I would like to find the string `"38":` and do something with following numbers until `,`.

What is the correct way to grab that number from the serial reply and echo or do something with it?

title: Find number in a reply returned via serial

Answers: 1

body:
Since you are being returned JSON, you can use the jsoncpp library found [here][1]
To split your return to an array. Then you simply retrieve whatever item you want using array index notation.

Here is another helpful post on creating arrays of strings in C++ from JSON.
[C++ and JSON][2]

  [1]: https://github.com/open-source-parsers/jsoncpp
  [2]: https://stackoverflow.com/questions/14082643/parsing-json-arrays-in-c


body:
Originally, I had a single sensor which I was reading at 100MHz. I used Timer3 and function attached to it to do both reading and writing of the sensor data (print to com port).

Now I have added another sensor which can only be read at half the frequency. I still want to be able to write data in the same format as before for both sensor data at 100Hz, with slower sensor data just being repeated twice.

How do I handle this? Do I use multiple Timer3 attachments at different frequencies? I am planning to have three interrupts.. 1st for reading sensor A, 2nd for reading sensor B, and 3rd for writing data.

title: Reading two sensors at different frequencies... multiple Timer3?

Answers: 2

body:
The rule is:

* One Timer, One Interrupt.

When the timer overflows it triggers its interrupt. It only has one. That interrupt then runs your ISR.

If you are using a library to provide abstraction from the timer registers then it is down to that library how it calls your ISR. It is possible for one to provide a mechanism whereby you can "attach" multiple routines to the same interrupt, but that is quite a lot of work and overhead for a simple timer library to provide, so it is highly unlikely anyone would ever bother.

So how do you do multiple sensor measurements from one timer? Simple: just do multiple sensor measurements. You don't have to restrict yourself to just reading one sensor within your interrupt - you can read as many as you like. There is just a couple of caveats though:

1. The whole ISR must take less that 10ms to run or it will overrun the timer overflow period.
2. You cannot do serial from inside an interrupt*

So in your interrupt you read the sensors and add their values to a buffer. Then in your main loop you read that buffer to send the data out through serial. You may want to set a flag in your interrupt routine to alert the main loop that there is data available, or implement a circular buffer which has an equivalent of a `.available()` function to see if there is any data to read from it.

----
*You can place data in the serial TX buffer but it will not be transmitted out of the TX buffer until after the interrupt routine has finished. If you put too much data in that TX buffer it will block indefinitely waiting for it to empty.

body:
Conceptually, this is best solved by having an ISR which always reads the high rate sensor, but implements a toggle so that it only ready the low rate sensor every other execution.  On the times when you don't read it you could repeat a stored version of the last reading, though it would be more bandwidth efficient not to transmit that at all.

However, practically speaking this may not be the best choice.  The process of reading sensors often has a latency - typically to achieve the highest possible rate you would need to start the reading, and claim the result sometime later.  If your two sensors have distinct interfaces, or even if the they share an I2C or SPI bus, you may be able to start readings for both and then claim them with subsequent transactions after allowing them an overlapped measurement time.

It is also not clear that you are best to use an interrupt service routine at all.  If your MCU has nothing else to do, the most *deterministic* and ultimately *fastest* behavior on an ATmega might be to accomplish reading and direct (unbuffered) serial transmission within the main program loop, busy waiting at each phase.  This avoids not only the overhead of context switches when entering an ISR, but also a lot of the variability.  That would be doubly true if you can be transmitting the old reading while waiting for the already-triggered sensors to measure the next one.

However, you mentioned you are using a Teensy 3.x, which probably communicates natively via USB, rather than a serial UART.  That complicates things a bit - so called "serial" output flows in response to interrupts from the USB engine responding to the host, which is not really deterministic for you.  Fortunately, the Teensy is enough faster that you are less likely to have issues with running out of time, particularly when sampling at 100 Hz.


body:
I was thinking of using multiple analog light sensors (variable resistance by light), but basically I only need to know if there is "a lot of light" or "not a lot of light". And would like to use interrupts.

Since I'm using multiple analog inputs, I can't set the ADC module to interrupt on a specific voltage, for each of the (5?) sensors?
I'd like to do this withouth using a external comparator.

I've checked the ATMega328p datasheet (going to use Arduino Nano probably).

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

The fun thing, however, is that on 5V a high signal is >2.6V and a low signal is <2.2V

What does this mean for the grey area? Would my inputs be glitching randomly? Would they maintain high, until below 2.2V and maintain low until above 2.6V? Or can the switching point be any where between that (and is it different per chip or pin?

*EDIT: I've checked, my voltage divider circuit has 0.6V for "nothing" and 3V for "interrupted", so it should work neverthless. Though, I'm still interested in how the grey threshold area behaves.*

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

title: Digital input pin voltage treshold (voltage to register 1 or 0)

Answers: 1

body:
The titles of the graphs are actually saying what happens: the hysteresis.

In other words:

- if the input level is high (greater than 2.6V), it will be considered high through the hysteresis area (until it goes below 2.2V)

- if the input level is low (below 2.2V), it will be considered low through the hysteresis area (until it goes above 2.6V)

According to the description you gave, this should work for your case.
In case it doesn't, you have to condition it until the values you want to consider 0 and 1 are respectively below 2.2V and above 2.6V, with a safety margin, for good measure (say 30%).

The hysteresis is meant to prevent noise from causing unwanted spurious transitions: without safety margin, it should be greater than 0.4V.

You can dimension the safety margin to meet your needs.

But, for the sake of completeness, I'll say that it might be preferable to have a timer to trigger periodic sampling with the ADC.

If you know the maximum frequency at which every input can vary, you can sample it at twice that frequency and be sure that you will not miss anything. Again, this is theory, I would probably make it 4 times, to allow for unforeseen variations.

This works as long as the conversion time of the ADC is shorter than the maximum combined frequency at which you need to read the values.

The GPIOs, of course, are faster, but might require additional circuitry for the conditioning I mentioned earlier.


body:
Why does this code not function in a similar way to the example fade sketch?
I have had to resort to using bit-banging as a way to implement PWM onto non PWM pins due to  a lack of available free pins on my Arduino Pro Mini. I am using a sketch that supposedly should fade an LED ranging from maximum brightness to minimum brightness. My code however does not work. Can anyone figure out why my code does not operate in the same way the fade sketch does?

My current code is:

    int brightness = 0;
    int fadeAmount = 50;
    void setup()
    {
      pinMode(12, OUTPUT);
    }
    void loop()
    {
      brightness = brightness + fadeAmount;
      if (brightness == 0 || brightness == 255) {
        fadeAmount = -fadeAmount ;
      }
      digitalWrite(13, HIGH);
      delayMicroseconds(brightness); // Approximately 10% duty cycle @ 1KHz
      digitalWrite(13, LOW);
      delayMicroseconds(1000 - 100);
    }

And I want it to work in the same way as:

    int led = 9;
    int brightness = 0;
    int fadeAmount = 5;
    void setup() {
      pinMode(led, OUTPUT);
    }
    void loop() {
      analogWrite(led, brightness);
      brightness = brightness + fadeAmount;
      if (brightness == 0 || brightness == 255) {
        fadeAmount = -fadeAmount ;
      }
      delay(30);
    }

If possible could anyone provide a correct version to help me with my project.

title: PWM on non PWM pins

Answers: 4

body:
You seem to have a typo on the pin number: you are configuring pin 12 and driving pin 13.

In other words: `pinMode(12, OUTPUT);` and `digitalWrite(13, HIGH);` do not match.

body:
Your code here is not quite right:

    digitalWrite(13, HIGH);
    delayMicroseconds(brightness);
    digitalWrite(13, LOW);
    delayMicroseconds(1000 - 100);

Your two delays should add up to the total period (wavelength), or the reciprocal of the frequency (scaled to microseconds).

Hence the `- 100` in the second delay - that is subtracting the "on" time from the total time to give the "off" time.   It should be replaced with `- brightness` as such:

    digitalWrite(13, HIGH);
    delayMicroseconds(brightness);
    digitalWrite(13, LOW);
    delayMicroseconds(1000 - brightness);

And of course the brightness is in the range 0 - 1000 not 0 - 255 like `analogWrite()`.  To make it 0-255 you should replace the 1000 with 255, which of course makes it all run at a much higher frequency. (1 / 0.000255 = 3922Hz).

    digitalWrite(13, HIGH);
    delayMicroseconds(brightness);
    digitalWrite(13, LOW);
    delayMicroseconds(255 - brightness);

Mind you, all this is not good regardless of your calculations. This is a *blocking* system in which you are unable to do anything else at all in your program whilst generating PWM.  Instead you should be using a timer (like the `tone()` command does) and switch between two different time periods each interrupt for "on" and "off" time periods. That way it can function asynchronously ("in the background") like `analogWrite()` does.

body:
It's not strongly related to your question but i suggest you to use external library as SoftPWM.h

You can find the whole documentation on https://github.com/bhagman/SoftPWM

body:
A more generic version of your approach would be like this.

1. Set the output pin - don't hardwire the pin number but instead use a macro for it.

2. Delay for it's duty cycles.

3. Clear the output pin.

4. Delay for period - duty cycles used in step 2 above.

You can put that in a routine and call it.

With that said the routine has limited use in a real application as it can drive one output pin and ties up the whole mcu needlessly.

A better approach is to use an interrupt and test for duty cycles in the interrupt . This can drive multiple pins with independent duty cycles. All without tying up the mcu.


body:
I was wondering if it's possible to send data from my Arduino Uno (e.g. from the temperature sensor) to the Amazon Web Service RDS or anything there, which will then upload the data to a website on my localhost?

If yes, could someone give me guidance please?

I've been messing with this for a few weeks now, but I am just getting lost with linking it all up together.

Thanks.

title: Is it possible to use AWS and Arduino Uno to upload data from Arduino to a website running on my localhost?

Answers: 2

body:
No, it is not (easily) possible.

AWS has no access to your localhost - you are (most likely) behind a NAT router.

You could *possibly* open up port forwarding on your router and then ensure that AWS knows always what the IP address of your router is so it can connect (using some dynamic DNS service maybe).

However, that is not secure, and dynamic IP address assignments makes it a real pain. It opens up your computer to hacking from the internet.  A more secure method is to use AWS as the "central point" and have your computer go and fetch data from there rather than having it send data to your computer.

body:
I realize that this probably two years too late for the OP; however, I'd like to provide insight to anyone else who might be interested.

It is possible to do what you're asking. What you are looking for my friend is AWS IoT Core and the related IoT Services (e.g. IoT Device Management).

There are several steps that you're going to need to perform prior to being able to send telemetry to AWS:

1. Ensure that your device has the necessary components to connect to the Internet (e.g. a network shield).
2. Once you are Internet-capable, locate [here](https://docs.aws.amazon.com/en_us/iot/latest/developerguide/iot-sdks.html) the AWS IoT SDK that will work well with your device.
3. Read the documentation (I'll let you look that part up ;-)...probably within the sub-links on the page from #2) on how to connect your device to an MQTT-based Web Sockets connection to AWS IoT Core.
4. Once you've figured out how (using the SDK from your device) to connect to AWS using MQTT, [read about AWS Lambda](https://aws.amazon.com/lambda/?nc1=f_ls) and how you can setup various triggers off of IoT Core, which can then propagate data down to your RDS DB or the like.
5. Once you have your data in AWS, you can then connect your "localhost" website to RDS, using the appropriate connection string, and pull the data from there.

Good luck and happy IoTing.


body:
I made this exact build on my Arduino, with the following differences:

- I'm using Arduino Nano
- Transistors I use are 2N2222A
- I'm running everything on 12V except Arduino, I use LM317 to feed Arduino 6v

Here's the build:
[![enter image description here][1]][1]

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

Here's what happened. First, it started to get strange voltage, arduino would light up even when disconnected from power. After that, Arduino kind of got fried, when I connect it to USB, nothing happens. I can give it 6v to VIN and ground it with the rest, but turning potentiometers only dims the onboard LED of the Arduino and that's it.

Now I'm going to go and pick up a new nano, however, I'd prefer not to fry that one, so figuring out why this one burned would be nice.

PS. The image shows RGB LED instead of RGB LED Strip because 123d doesn't have strip component.

title: RGB Led strip pot control burned my arduino?

Answers: 2

body:
First, as Majenko said, you need resistors between the arduino output pins and the transistor bases. Start at something like 330 Ohm.
Second, what is the value of the potentiometers? If it is too low you would be drawing too much current from the 5V pin to the ground.
Third, you should power the arduino with at least 7V, assuming you power it through the Vin pin or the power jack. 6V is considered too low.
I assume the pins connected to the potentiometers are initialised as inputs. Otherwise, it would be possible to burn your arduino by having them source/sink too much current (i.e. by turning the potentiometers to one end or the other).

body:
Looking at the datasheet for the 2N2222A at http://www.onsemi.com/pub_link/Collateral/2N2222A-D.PDF
The 2N2222A base will draw 50 ma at 2volt.  You are giving them more than that.
The maximum allowed output from the Arduino is 40ma.
So check the 2N2222A's they are probably burnt out as well as the Arduino.
Next time put in a limit resistor of 1k to the 2N2222A bases.
Try pulling out the 2N2222A's and see if your Arduino powers up ok.


body:
When I power my ATmega328P chip from 5.16V and 3.3V, there doesn't seem to be a single bandgap voltage compensation figure that works for both.

I'm using the following sketch, and I need the following `InternalReferenceVoltage` values to read the correct voltage from `A0`:

- `1255L` to correctly output 5.16V.
- `1358L` to correctly output 3.3V.

I have a couple of questions:

- Should I be able to use a single `InternalReferenceVoltage` compensation value whe powering the ATmega328P from different voltages?
- Aren't both of these values outside the specced 1.0 to 1.2 range?

The code is from, http://forum.arduino.cc/index.php?topic=56750.msg407897#msg407897, retolefty post @ Mar 28, 2011, 02:27 pm.

    #include <SPI.h>

    void setup()
    {
      delay(5000);

      Serial.begin(115200);
    }

    void loop(void)
    {
      // Determines what actual Vcc is, (X 100), based on known bandgap voltage
      int battVolts = readVcc1();

      Serial.print("Battery Vcc volts =  ");
      Serial.println(battVolts);
      Serial.print("Analog pin 0 voltage = ");
      Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
      Serial.println();

      delay(1000);
    }

    // Returns actual value of Vcc (x 100)
    int readVcc1()
    {
      uint8_t oldADMUX = ADMUX;

      const long InternalReferenceVoltage = 1255L; // Adjust this value to your boards specific internal BG voltage x1000

    #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      // For mega boards
      // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc reference
      // MUX4 MUX3 MUX2 MUX1 MUX0  --> 11110 1.1V (VBG)         -Selects channel 30, bandgap voltage, to measure
      ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (0 << MUX5) | (1 << MUX4) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);

    #else
      // For 168/328 boards
      // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc external reference
      // MUX3 MUX2 MUX1 MUX0  --> 1110 1.1V (VBG)         -Selects channel 14, bandgap voltage, to measure
      ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);

    #endif
      delay(50); // Let mux settle a little to get a more stable A/D conversion
      // Start a conversion
      ADCSRA |= _BV(ADSC);
      // Wait for it to complete
      while (((ADCSRA & (1 << ADSC)) != 0));

      // Scale the value
      int results = (((InternalReferenceVoltage * 1023L) / ADC) + 5L) / 10L; // calculates for straight line value

      ADMUX = oldADMUX;

      return results;
    }

I have read these other references to try and find a solution:

- https://arduino.stackexchange.com/questions/16352/measure-vcc-using-1-1v-bandgap
- https://hackingmajenkoblog.wordpress.com/2016/02/01/making-accurate-adc-readings-on-the-arduino/
- http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/

title: Measure different Vcc using 1.1V bandgap

Answers: 1

body:
The internal reference won't change much. That's why it's a reference.

Running this code on my Atmega328P:

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

    void setup ()
    {
      ADMUX = bit (REFS0) | bit (REFS1);  // Internal 1.1V reference
    }
    void loop () { }

That outputs the reference voltage on Aref. I measured it as follows with different values for Vcc:

<!-- language: lang-none -->

    Vcc     Aref
    ------------
    5.00   1.085
    4.00   1.081
    3.30   1.080
    3.00   1.079

So you can see that it retains, more or less, the same voltage regardless of Vcc. In any case, there is no way of measuring Aref, unless you have *another* reference voltage around to compare it to.


body:
I am using Arduino Uno for measuring sensor voltages. I am using multiplexer to switch between different sensors. The readings measured in the range of 800-900 mv are accurate, but at low millivolts (at about 20 mv) they are erratic. I read repeatedly to get average of 20 values. I get values such as 1.3, 1,4, 2,0, 3.8 etc.
Can any one help on why it is happening and how to avoid it.

Additional information: I am using reference voltage of 1.25 volt for better resolution.
I tried having delay between two readings, though there is some improvement, still the problem persists.

I appreciate the help by experts.
Thanks

title: Erratic readings on Analogread with low voltages

Answers: 1

body: You are almost certainly running into the noise floor for your setup. When your target signal is a very low voltage your signal to noise ratio (SNR) is small. Because it is the noise floor setting the ADC for better resolution didn't help much. There are many ways to deal with noise. If your signal is "slow" and your noise is random you can try oversampling. If the noise is from the power supply you can add filtering on the input to your sensor. If you have done those and still want to reduce noise more you can try adding shielding to your device/wires.


body:
This (maybe stupid) question is bothering me for a long time...

If the pin 0 has to be connected to the ground for uploading a sketch into ESP8266, and after the uploading the chip automatically starts the uploaded sketch (without waiting for reboot with pin 0 to be disconnected), then won't it destroy the chip if I do digitalWrite(0, HIGH) in my sketch? Correct me if I'm wrong, but it should short 3.3V directly to the ground through this pin... Is this problem secured somehow? Or maybe this pin can be safely used for reading only?

Edit:

I have seen it connected to ground directly on every schematic about ESP8266, but maybe I should just use a pull-down resistor? Or maybe the chip already has a resistor before this pin to solve this problem?

title: ESP8266: Is it safe to use pin 0?

Answers: 3

body:
What do you consider pin 0?
As I look at the schematics it could either be GND, VCC, RX or TX pin. Or do you mean GPIO0?

GPIO0 when connected to GND and in combination with RST to GND will put ESP into programing mode.
Good practice is to have separate programing board, something like [This here][1]. Go down to "Writing a program to the ESP8266" section and check out the schematic. Voltage regulator can be omitted if you are already powering it with 3.3v.

  [1]: http://www.whatimade.today/esp8266-easiest-way-to-program-so-far/

body: You can absolutely use GPIO0 as an output. The ESP will read the state of GPIO0 once at boot (And never again thereafter) to determine what boot mode to enter. During this time it is an input, so, whatever you hook GPIO0 up to must not hold this pin low (Unless you want to enter bootloader mode, of course), at least until the chip boots. As long as you satisfy this condition, you can use the pin for anything else. On my board for example, I use it to drive a simple status LED, and have never seen any issue from it.

body:
It may be stated that GPIO0 is safe to use as an output, but I challenge anyone to show he has actually done it. When configuring GPIO0 as an output I get only oscillations (about 70kHz), loaded or open, when driving this pin LOW.
Even GPIO15 works without issues when used as an output.
Several new ESP8266-12F modules were tested.


body:
I am trying the esp8266 esp-01, and did all it asked on the arduino IDE side, but i am having problems compiling and building the blink example into the board

Using: FT232RL usb-ttl in the 3.3v configuration, two 1.6v (new) batteries to power the esp, and all the conections as indicated here (not using the led though).

when I hit (go) it compiles, but as it transfers both boards blink sincronously and I recive the following errors:

O sketch usa 219.479 bytes (50%) de espaço de armazenamento para programas. O máximo são 434.160 bytes. Variáveis globais usam 31.172 bytes (38%) de memória dinâmica, deixando 50.748 bytes para variáveis locais. O máximo são 81.920 bytes.

error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data error: failed reading byte warning: espcomm_send_command: cant receive slip payload data warning: espcomm_sync failed error: espcomm_open failed error: espcomm_upload_mem failed

I looks to me as a newbie that its trying to establish a link and failing... what could it be?

the configurations are default, programmer is "AVRISP MKII"

title: ESP8266 blink not building to esp-01

Answers: 1

body:
You did not put ESP8266 into programing mode.

the easiest way to do so is to make your own programing board, something like [shown here][1]. Go down to middle of the document to title "Writing a program to the ESP8266" where you will see a schematic of simple programing board. You will need two switches and a 10k resistor.

The voltage regulator can be omitted if you are powering it by 3.3v power. Also its a good idea to put a small capacitor (100uf) between vcc and ground to stabilize any drops in voltage which is primary cause of esp8266 rebooting it self.

  [1]: http://www.whatimade.today/esp8266-easiest-way-to-program-so-far/


body:
im working on the following project [kalman filter][1]

and im working to implement in arduino.. i read the entire code and i succesfully implemented it into arduino but i couldnt implement the following function [code line][2] because arduino gives "not defined" error in **PI_DIV_180**

    imu_MadgwickQuaternionUpdate(bUseAccel,elapsedTimeSecs,fax,fay,faz,fgx*PI_DIV_180,fgy*PI_DIV_180,fgz*PI_DIV_180,fmx,fmy,fmz);

it multiplies `fgx` with **PI_DIV_180** but as i said arduino cant identify it

i looked into math.h to find the value of that define but there isnt anything in math.h related with this

the `imu_MadgwickQuaternionUpdate` function is in here **IMU.cpp**

can anyone help me please thanx..

  [1]: https://github.com/har-in-air/Kalmanfilter_altimeter_vario
  [2]: https://github.com/har-in-air/Kalmanfilter_altimeter_vario/blob/master/Usage.txt#L28

title: Unidentified constant value

Answers: 1

body:
Maybe it's pi (π) divided by 180?

Pi is roughly: 3.1415926535898

So:

    3.1415926535898 / 180 = 0.017453292519943

So add this line:

    #define PI_DIV_180 0.017453292519943


body: I'm doing some tests and I notice a bad things with digitals pins. I have a wire that sends 1 signals. If i connect it to a reading pin, I read 1 - and it's ok. But if i disconnect it, for 5-6 seconds Arduino continues to read 1 instead of 0! How can I stabilize it more quickly?

title: UNO's digital pin continue to read 1 for a while

Answers: 2

body:
Digital inputs should either be low or high. In this image acceptable input voltages on the left represent common TTL voltages based on a 0 to 5 volt range:
[![enter image description here][1]][1]

It is bad practice to leave a digital input floating.  A floating or disconnected input implies the voltage is unknown.  I suspect in your case a small amount of input capacitance held a charge for several seconds.  Once leaked off the input appeared to change from 1 to 0.  Even though you know what might be happening, you should not depend on it as it is unreliable behavior.

If connecting a SPST switch use a pull up (or pull down) resistor to pull the input pin to the opposite voltage the switch is pulling.  In this image the switch is connected to ground so the resistor is connected to positive voltage as a pull up:

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

The fist image comes from [this][3] Logic Level tutorial.

  [1]: https://i.stack.imgur.com/KWFKX.png
  [2]: https://i.stack.imgur.com/CPRWs.png
  [3]: https://learn.sparkfun.com/tutorials/logic-levels

body:
St2000 's reply above gives the background, which is valid for any digital input, not just the Arduino pins.

However, in the specific case of the Arduino, one more thing should be noted: You can skip the use of an external pullup resistor by configuring the pin to use the internal pullup resistor:

    pinMode(pin, INPUT_PULLUP) ;

This assumes, of course, that it is easy to modify the part of your circuit that is connected to your input pin to have the following two states:

    - ground
    - high impedance (floating)

If, for example, it is a switch you are reading, just connect one pin of the switch to your arduino pin and the other to GND.


body:
I have created a car that can detect obstacle and change its direction, but now I want to add a bluetooth module to control it and I want to switch between the two circuits using a three state switch (ON-OFF-ON), so how can I do that and how can I upload two different codes on the arduino.
Here is a fritzing diagram, (the pins for the bluetooth will be changed).

Sensor:

[![Breadboard diagram][1]][1]

Bluetooth:
[![Breadboard diagram w/ Bluetooth][2]][2]

And here is the code for the sensor:

       #define echopin  8 // echo pin
       #define trigpin 9 // Trigger pin

       int maximumRange = 30;
       long duration, distance;

        void setup() {
            Serial.begin (9600);
            pinMode (trigpin, OUTPUT);
            pinMode (echopin, INPUT );
            pinMode (4, OUTPUT);
            pinMode (5, OUTPUT);
            pinMode (13, OUTPUT);
            pinMode (6, OUTPUT);
            pinMode (7, OUTPUT);
        }

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

            digitalWrite(trigpin,HIGH);
            delayMicroseconds(10);

            duration=pulseIn (echopin,HIGH);

            distance= duration/58.2;
            delay (50);
            Serial.println(distance);
        }

            if (distance >= 30 ){
                digitalWrite(4,HIGH);
                digitalWrite(5,HIGH);
                digitalWrite(6,LOW);
                digitalWrite(7,LOW);
                delay (200);
            }
            else if (distance >=15 && distance <= 25) {
                digitalWrite (4,HIGH);
                digitalWrite (5,LOW);
                digitalWrite (6,LOW);
                digitalWrite (7,LOW);
                delay (1000);
            }
            else if (distance < 15){
                digitalWrite (4, LOW);
                digitalWrite (5, LOW);
                digitalWrite (6,HIGH);
                digitalWrite (7,HIGH);
                delay (1000);
                digitalWrite (4,LOW);
                digitalWrite (5,HIGH);
                digitalWrite (6,LOW);
                digitalWrite (7, LOW);
                delay (1000);
            }
        }

Please write in the most details and write any code as I am still a beginner.

  [1]: https://i.stack.imgur.com/R9uRs.jpg
  [2]: https://i.stack.imgur.com/5ZAHI.jpg

title: How to connect a a three state switch (ON-OFF-ON) to arduino?

Answers: 3

body:
While a simple concept, having 2 different selectable programs (sketches) in 1 Arduino is not the way the Arduino paradigm works.

Most Arduinos contain an Atmel processor.  This processor contains a boot loader program.  This program only knows how to deal with 1 other program (the sketch).  In order to switch between 2 different programs (sketches) you would have to re-write this boot loader.

But you still have to deal with the creation of the 2nd program.  In order to do this you need to change the SDK used to create the 2nd program (sketch).  Specifically, you need to link the 2nd program (sketch) so that it can operate out of a different location in the Atmel processor's memory.

It would be far easier to combine the two programs (sketches) into a single program (sketch).  Then use your switch to change the program's (sketch's) behavior.

body:
As stated by st2000, it's not common practice to have two separate programs running on one microcontroller.

The solution is simple, use the switch to "switch between" behavior.

    if(switch is on){
      //Automatic
    }else{
      //Bluetooth
    }

*You should also use functions, to make your code more readable.*

This might work:

    #define echopin  8 // echo pin
    #define trigpin 9 // Trigger pin
    #define switchPin 10

    int maximumRange = 30;
    long duration, distance;

    void setup() {
      Serial.begin (9600);
      pinMode (trigpin, OUTPUT);
      pinMode (echopin, INPUT );
      pinMode (4, OUTPUT);
      pinMode (5, OUTPUT);
      pinMode (13, OUTPUT);
      pinMode (6, OUTPUT);
      pinMode (7, OUTPUT);

      pinMode(switchPin, INPUT_PULLUP);
    }

    void loop ()
    {
      if (digitalRead(switchPin)) { //If the switch is pressed.
        automaticLoop();          //Do the automatic control.
      } else {                   //If not pressed.
        bluetoothLoop();          //Do the bluetooth control.
      }
    }

    void measureDistance() {
      digitalWrite(trigpin, LOW);
      delayMicroseconds(2);

      digitalWrite(trigpin, HIGH);
      delayMicroseconds(10);

      duration = pulseIn (echopin, HIGH);

      distance = duration / 58.2;
      delay (50);
      Serial.print("Distance is: ");
      Serial.println(distance);
    }

    void automaticLoop() {
      measureDistance();

      if (distance >= 30 ) {
        digitalWrite(4, HIGH);
        digitalWrite(5, HIGH);
        digitalWrite(6, LOW);
        digitalWrite(7, LOW);
        delay (200);
      }

      else if (distance >= 15 && distance <= 25) {
        digitalWrite (4, HIGH);
        digitalWrite (5, LOW);
        digitalWrite (6, LOW);
        digitalWrite (7, LOW);
        delay (1000);
      }
      else if (distance < 15) {
        digitalWrite (4, LOW);
        digitalWrite (5, LOW);
        digitalWrite (6, HIGH);
        digitalWrite (7, HIGH);
        delay (1000);
        digitalWrite (4, LOW);
        digitalWrite (5, HIGH);
        digitalWrite (6, LOW);
        digitalWrite (7, LOW);
        delay (1000);
      }
    }

    void bluetoothLoop() {
      //Code for bluetooth.
    }

body:
I'm trying to give you some more general advice.

**How to combine two Arduino sketches into one**
There is no general rule, how to do this. But there are some common problems to solve.

 1. Code has to be merged for setup and loop independently
 2. You can have only one setup() and one loop() when finished.
 3. If there are variables with same names in both sketches, you have to rename those in one of them.
 4. If you operate with delays, be aware, that delays sum up and retard processing of your loop accordingly.
 5. Having your code merged in most cases you need additional variables to transfer information from one code part to another.

**How to use two different hardware setups with one Arduino**
There are some general rules, too:

 1. Except for some meticulously and intricately designed electronics, you can use each port only once. You have to move hardware to another port if they are conflicting.

 2. If you run out of ports, you may have to use port expanders or some logic circuitry to gain more inputs and outputs

 3. Check if your hardware does not overload your arduino power supply. some shields and modules can easily suck up the available power.


body:
I'm trying to create a Tic Tac Toe game using the Arduino Uno. Since the Uno has a limited amount of pins to use, I am trying to see if there is a configuration that would make the project possible.

For the button detection circuit I am using a simple voltage divider and an analog pin. I made the following in a circuit simulator:

[![Switch Input Detection Circuit (Voltage Divider)][1]][1]

Now for the LEDs, since the Uno only hosts 9 pins, and we need 18, we need some sort of wizardry to get something working. I came up with the following design using the circuit simulator:

[![Controlling Two LEDs using One Pin][2]][2]

  [1]: https://i.stack.imgur.com/r0dGF.png
  [2]: https://i.stack.imgur.com/n6B7g.png

I would use 9 of these, one connected per Arduino pin. Since only one of the LEDs in each of the 9 sets should be on, this type of circuit should allow the Arduino to control all of the 18 LEDs. In the simulation I get about 5mA draw from each side (with 5v and GND).

However my problem is that the LED setup doesn't work. The lights are extremely dim. At first I simply thought that 5mA was not enough for the LED. I decided to measure the current going through the LED and found that it was about 0.8mA. What happened to my 5mA calculation? After all, isn't Arduino pin able to handle about 40mA? Am I asking for too much current?

Where have I gone wrong with this? Thanks in advance for any help.

tommis15

title: Creating an Arduino Tic Tac Toe game

Answers: 2

body:
You should really provide more info:
- your program
- what exactly you are trying to achieve (you seem to be driving two leds per 'board position'. What do they represent?) and schematics.

It would also help if you measured the voltage level at the pin in both the ON and OFF state and mentioned it here.

However, one thing that should be noted (hopefully before it is too late) is that your 40mA/pin assumption is wrong. First of all, 40mA is the absolute maximum rating for one pin (i.e. the value you should stay clear of). Secondly, although one isolated pin can source or sink close to 40mA, the total of all GPIO pins should stay below 200 mA. See also http://playground.arduino.cc/Main/ArduinoPinCurrentLimitations .

body: I was working with it more and I found that my mistake was that I was using pin 0 and 1 to test (serial) and switching to pin 2 and above works.


body:
I am trying to find some information on how to use the analog comparator on an Atmega328 to detect when an analog pin has reached a certain voltage (3.16 volts).

I cannot find any example code that says how to do this, although I have read that the analog comparator can compare the voltage on an analog pin with the voltage output by a PWM pin. I do not understand how this would work as the PWM pins do not output an analog voltage, but a pulse width modulated square wave. Is it possible to use the comparator to compare with a certain voltage this way?

I have tried polling with `analogRead()`, but it is too slow for my application.

title: How to use the analog comparator to determine when an analog pin has reached a certain voltage?

Answers: 2

body:
You need a low-pass filter between the PWM output and the comparator input. This will allow you to produce an analog voltage from the PWM output, which can the be used as a reference voltage for the comparator.

Typically, a simple RC LPF is sufficient. Choose a large time constant relative to your PWM frequency (the Arduino defaults to 490Hz) so that you don't have ripple in your reference voltage.

body:
I have a [page about the analog comparator](http://www.gammon.com.au/forum/?id=11916) that has code:

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

    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

This is for a fixed reference voltage, for example:

[![Reference voltage][1]][1]

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


body:
[![Fritzing diagram][1]][1]

When I try uploading to my Arduino/Genuino UNO I get the following not in sync error with "unique" resp(resp=0X54) or (resp=0X81) please solve ... I have to submit my project tommorow......

>
error message:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x54
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x54
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

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

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

title: Arduino not in sync unique error

Answers: 2

body:
You have a BT module attached to Arduino Tx Rx pins. That's the culprit. Disconnect anything from Tx and Rx pins of arduino while uploading code. Once the code has been uploaded, re-connect the BT module.

Edit:

Since this didn't solve your problem, you need to pin point the issue. If you have removed everything from Arduino and still not able to upload the code - either your drivers are not up to date or your arduino is faulty.

Test the arduino:

Try uploading blinky sketch. Didn't succeed? Restart arduino IDE and try again. Didn't succeed? Restart PC and try again. Didn't succeed? Re install arduino and try again? Didn't succeed? Try on a friend's PC? No luck? Arduino is faulty.

Note: This answer is for the exact schematic you have given. If you have done something else, there might be other reasons why you are not able to upload the code. Post a real picture of what exactly you are doing and we might be able to help you further.

body:
NOTE

That schematic shows you are trying to power the motors from the Arduino's 5V power supply. That is a 'bad idea' unless they are good quality, low-current, motors.

The electrical noise from the motors may cause the Arduino to reset, and run the same program from the beginning until it reaches the part where the motor's electrical noise resets it.

Worse, current drawn if the motors stall may damage the Arduino's power supply. The Arduino's voltage regulator is supposed to protect itself from damage, but it doesn't always succeed. This is rare, but I have had students break it.

I have elevated this comment to an answer to warn other people against trying to use the schematic in the question.


body:
So I was starting to gain some knowledge on the PIR sensor and how to let the Arduino 'sleep' while there is no movement detected by the PIR.

I found the following code somewhere and looked fairly simple. So  I thought I would give it a try and grabbed my Mega2560, a LED and a PIR sensor.

While it was seeming to work at first sight, the Arduino is doing the opposite from what I was expecting. It turns off the LED and the Arduino when there is movement, instead of turning off the Arduino when there is NO movement. As I said before, it is doing pretty much the inverse.

Probably an easy solution, but can't figure it out on my own.

The code:
<!-- language-all: lang-cpp -->

    #include <avr/sleep.h>

    int wakePin = 2;                 // pin used for waking up
    int led = 13;

    void wakeUpNow() {
    }

    void setup() {
      pinMode(wakePin, INPUT_PULLUP);
      pinMode(led, OUTPUT);
      attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW
    }

    void sleepNow() {
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
        sleep_enable();          // enables the sleep bit in the mcucr register
        attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
        digitalWrite(led,LOW);
        sleep_mode();            // here the device is actually put to sleep!!
        // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
        sleep_disable();         // first thing after waking from sleep: disable sleep...
        detachInterrupt(0);      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
        digitalWrite(led,HIGH);
    }

    void loop() {
      sleepNow();     // sleep function called here
    }

Thanks in advance.

**EDIT**

Adapted the code to the following and seems to work now. When motion is detected by the PIR it turns on the LED on pin 13; when no motion is detected, the LED is turned off.

Two questions still remain:

1) How can I be sure that the Arduino really sleeps now?

2) When the Arduino just entered sleep, it takes a couple of seconds (+/- 6s) before it can pick up another motion. Can I get a faster detection or another 'sleep' or 'powersave' method that lets the Arduino react faster to motion?

    #include <avr/sleep.h>

    const int wakePin = 2;                 // pin used for waking up
    const int led = 13;

    int wakeVal = 0;
    int wakeState = LOW;

    void wakeUpNow() {

    }

    void setup() {
      Serial.begin(9600);
      pinMode(wakePin, INPUT_PULLUP);
      pinMode(led, OUTPUT);
      //attachInterrupt(0, sleepNow, LOW); // use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW
    }

    void sleepNow() {
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
        sleep_enable();          // enables the sleep bit in the mcucr register
        attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
        sleep_mode();            // here the device is actually put to sleep!!
    }

    void disSleep(){
      // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
        sleep_disable();         // first thing after waking from sleep: disable sleep...
        detachInterrupt(0);      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
    }

    void loop() {
      wakeVal = digitalRead(wakePin);
      if (wakeVal == HIGH){

        disSleep();

        digitalWrite(led,HIGH);
        delay(1000);

        if (wakeState == LOW){
          Serial.println("Motion detected");
          wakeState = HIGH;
        }
      }
      else{
        digitalWrite(led,LOW);
        delay(1000);

        if (wakeState == HIGH){
          Serial.println("Motion stopped - Going to Sleep Mode !");
          wakeState = LOW;
          delay(1000);

          sleepNow();     // sleep function called here
        }
      }
    }

title: PIR sensor and sleep (interrupt) on Mega2560

Answers: 1

body: This is a problem with the Arduino Mega board. On the Mega, D2 is not INT0 as it is on the Uno. It's INT4. There's a footnote in the spec sheet that says only level interrupt is supported. That means you can't use RISING, FALLING or CHANGE. Your only choice is to use LOW. So the Arduino will be woken up when the motion turns OFF, not on. That's why it's backward. If you use an Uno instead of a Mega, you can use RISING and it will work as you think it should.